"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CosmwasmEvmSigner = exports.CosmwasmSigner = exports.getCosmwasmSigner = void 0;
const cosmwasm_stargate_1 = require("@cosmjs/cosmwasm-stargate");
const proto_signing_1 = require("@cosmjs/proto-signing");
const sdk_ts_1 = require("@injectivelabs/sdk-ts");
const connect_sdk_1 = require("@wormhole-foundation/connect-sdk");
const tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
const constants_1 = require("./constants");
const platform_1 = require("./platform");
async function getCosmwasmSigner(rpc, mnemonic) {
    const [network, chain] = await platform_1.CosmwasmPlatform.chainFromRpc(rpc);
    // Use the EVM signer for Evmos and Injective only
    if (constants_1.evmLikeChains.includes(chain)) {
        return new CosmwasmEvmSigner(chain, network, mnemonic);
    }
    // Otherwise use the default signer
    const signer = await proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
        prefix: (0, constants_1.chainToAddressPrefix)(chain),
    });
    const acct = (await signer.getAccounts())[0];
    const signingClient = await cosmwasm_stargate_1.SigningCosmWasmClient.connectWithSigner(connect_sdk_1.rpc.rpcAddress(network, chain), signer);
    return new CosmwasmSigner(chain, signingClient, acct.address);
}
exports.getCosmwasmSigner = getCosmwasmSigner;
class CosmwasmSigner {
    _chain;
    _signer;
    _account;
    constructor(_chain, _signer, _account) {
        this._chain = _chain;
        this._signer = _signer;
        this._account = _account;
    }
    chain() {
        return this._chain;
    }
    address() {
        return this._account;
    }
    async sign(tx) {
        const signed = [];
        for (const txn of tx) {
            const { description, transaction } = txn;
            console.log(`Signing: ${description} for ${this.address()}`);
            const txRaw = await this._signer.sign(this.address(), transaction.msgs, transaction.fee, transaction.memo);
            const encoded = tx_1.TxRaw.encode(txRaw).finish();
            signed.push(encoded);
        }
        return signed;
    }
}
exports.CosmwasmSigner = CosmwasmSigner;
class CosmwasmEvmSigner {
    _chain;
    _chainId;
    key;
    prefix;
    _rpc;
    constructor(_chain, _network, _mnemonic) {
        this._chain = _chain;
        this._rpc = new sdk_ts_1.ChainRestAuthApi((0, constants_1.cosmwasmNetworkChainToRestUrls)(_network, _chain));
        this._chainId = connect_sdk_1.nativeChainIds.networkChainToNativeChainId(_network, _chain);
        this.prefix = (0, constants_1.chainToAddressPrefix)(_chain);
        this.key = sdk_ts_1.PrivateKey.fromMnemonic(_mnemonic);
    }
    chain() {
        return this._chain;
    }
    address() {
        return this.key.toAddress().toBech32(this.prefix);
    }
    async sign(txns) {
        const pubKey = this.key.toPublicKey().toBase64();
        const { sequence, accountNumber } = await this.getSignerData();
        const signed = [];
        for (const tx of txns) {
            const { description, transaction } = tx;
            console.log(`Signing ${description} for ${this.address()}`);
            // need to set contractAddress and msg
            const message = transaction.msgs.map((m) => {
                const f = {
                    ...m.value,
                    msg: JSON.parse(connect_sdk_1.encoding.bytes.decode(m.value.msg)),
                    contractAddress: m.value.contract,
                };
                return new sdk_ts_1.MsgExecuteContract(f);
            });
            const { signBytes, txRaw } = (0, sdk_ts_1.createTransaction)({
                message,
                pubKey,
                sequence,
                accountNumber,
                chainId: this._chainId,
                memo: transaction.memo,
                fee: sdk_ts_1.DEFAULT_STD_FEE,
            });
            // @ts-ignore -- sign wants a `Buffer` but we give it uint8array
            txRaw.signatures = [await this.key.sign(signBytes)];
            signed.push(connect_sdk_1.encoding.b64.decode(sdk_ts_1.TxClient.encode(txRaw)));
        }
        return signed;
    }
    async getSignerData() {
        const address = this.address();
        const { account } = await this._rpc.fetchAccount(address);
        const accountNumber = parseInt(account.base_account.account_number, 10);
        const sequence = parseInt(account.base_account.sequence, 10);
        return { address, sequence, accountNumber };
    }
}
exports.CosmwasmEvmSigner = CosmwasmEvmSigner;
//# sourceMappingURL=signer.js.map