"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenBridgeRoute = void 0;
const sdk_base_1 = require("@wormhole-foundation/sdk-base");
const tokenTransfer_1 = require("../../protocols/tokenTransfer");
const types_1 = require("../../types");
const wormhole_1 = require("../../wormhole");
const route_1 = require("../route");
class TokenBridgeRoute extends route_1.ManualRoute {
    static meta = {
        name: "ManualTokenBridge",
    };
    static supportedNetworks() {
        return ["Mainnet", "Testnet"];
    }
    // get the list of chains this route supports
    static supportedChains(network) {
        return sdk_base_1.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_1.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_1.TokenTransfer.lookupDestinationToken(fromChain, toChain, sourceToken)];
    }
    static isProtocolSupported(chain) {
        return chain.supportsTokenBridge();
    }
    getDefaultOptions() {
        return { payload: undefined };
    }
    async validate(params) {
        const amt = sdk_base_1.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_1.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_1.TokenTransfer.transfer(this.request.fromChain, transfer, signer);
        const msg = await tokenTransfer_1.TokenTransfer.getTransferMessage(this.request.fromChain, txids[txids.length - 1].txid);
        return {
            from: transfer.from.chain,
            to: transfer.to.chain,
            state: types_1.TransferState.SourceFinalized,
            originTxs: txids,
            attestation: { id: msg },
        };
    }
    async complete(signer, receipt) {
        if (!(0, types_1.isAttested)(receipt))
            throw new Error("The source must be finalized in order to complete the transfer");
        return await tokenTransfer_1.TokenTransfer.redeem(this.request.toChain, 
        // todo: ew?
        receipt.attestation.attestation, signer);
    }
    async *track(receipt, timeout) {
        yield* tokenTransfer_1.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: sdk_base_1.amount.units(params.normalizedParams.amount),
            ...params.options,
        };
    }
}
exports.TokenBridgeRoute = TokenBridgeRoute;
//# sourceMappingURL=manual.js.map