import { amount, contracts } from "@wormhole-foundation/sdk-base";
import { TokenTransfer } from "../../protocols/tokenTransfer";
import { TransferState, isAttested } from "../../types";
import { Wormhole } from "../../wormhole";
import { ManualRoute } from "../route";
export class TokenBridgeRoute extends ManualRoute {
    static meta = {
        name: "ManualTokenBridge",
    };
    static supportedNetworks() {
        return ["Mainnet", "Testnet"];
    }
    // get the list of chains this route supports
    static supportedChains(network) {
        return contracts.tokenBridgeChains(network);
    }
    // get the list of source tokens that are possible to send
    static async supportedSourceTokens(fromChain) {
        // Default list for the chain
        return Object.values(fromChain.config.tokenMap).map((td) => Wormhole.tokenId(td.chain, td.address));
    }
    // get the liist of destination tokens that may be recieved on the destination chain
    static async supportedDestinationTokens(sourceToken, fromChain, toChain) {
        return [await TokenTransfer.lookupDestinationToken(fromChain, toChain, sourceToken)];
    }
    static isProtocolSupported(chain) {
        return chain.supportsTokenBridge();
    }
    getDefaultOptions() {
        return { payload: undefined };
    }
    async validate(params) {
        const amt = amount.parse(params.amount, this.request.source.decimals);
        const validatedParams = {
            amount: params.amount,
            normalizedParams: { amount: amt },
            options: {},
        };
        return { valid: true, params: validatedParams };
    }
    async quote(params) {
        try {
            return this.request.displayQuote(await TokenTransfer.quoteTransfer(this.request.fromChain, this.request.toChain, this.toTransferDetails(params)), params);
        }
        catch (e) {
            return {
                success: false,
                error: e,
            };
        }
    }
    async initiate(signer, quote) {
        const { params } = quote;
        const transfer = this.toTransferDetails(params);
        const txids = await TokenTransfer.transfer(this.request.fromChain, transfer, signer);
        const msg = await TokenTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
        return {
            from: transfer.from.chain,
            to: transfer.to.chain,
            state: TransferState.SourceFinalized,
            originTxs: txids,
            attestation: { id: msg },
        };
    }
    async complete(signer, receipt) {
        if (!isAttested(receipt))
            throw new Error("The source must be finalized in order to complete the transfer");
        return await TokenTransfer.redeem(this.request.toChain, 
        // todo: ew?
        receipt.attestation.attestation, signer);
    }
    async *track(receipt, timeout) {
        yield* TokenTransfer.track(this.wh, receipt, timeout, this.request.fromChain, this.request.toChain);
    }
    toTransferDetails(params) {
        return {
            token: this.request.source.id,
            from: this.request.from,
            to: this.request.to,
            amount: amount.units(params.normalizedParams.amount),
            ...params.options,
        };
    }
}
//# sourceMappingURL=manual.js.map