"use strict";
// This script is used to initiate a Solana deposit. useful in testing.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const anchor = __importStar(require("@coral-xyz/anchor"));
const anchor_1 = require("@coral-xyz/anchor");
const spl_token_1 = require("@solana/spl-token");
const web3_js_1 = require("@solana/web3.js");
const yargs_1 = __importDefault(require("yargs"));
const helpers_1 = require("yargs/helpers");
const web3_v1_1 = require("../../src/svm/web3-v1");
// Set up the provider
const provider = anchor_1.AnchorProvider.env();
anchor.setProvider(provider);
const program = (0, web3_v1_1.getSpokePoolProgram)(provider);
const programId = program.programId;
console.log("SVM-Spoke Program ID:", programId.toString());
// Parse arguments
const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
    .option("seed", { type: "string", demandOption: true, describe: "Seed for the state account PDA" })
    .option("recipient", { type: "string", demandOption: true, describe: "Recipient public key" })
    .option("inputToken", { type: "string", demandOption: true, describe: "Input token public key" })
    .option("outputToken", { type: "string", demandOption: true, describe: "Output token public key" })
    .option("inputAmount", { type: "number", demandOption: true, describe: "Input amount" })
    .option("outputAmount", { type: "number", demandOption: true, describe: "Output amount" })
    .option("destinationChainId", { type: "string", demandOption: true, describe: "Destination chain ID" })
    .option("integratorId", { type: "string", demandOption: false, describe: "integrator ID" }).argv;
async function deposit() {
    const resolvedArgv = await argv;
    const seed = new anchor_1.BN(resolvedArgv.seed);
    const recipient = new web3_js_1.PublicKey(resolvedArgv.recipient);
    const inputToken = new web3_js_1.PublicKey(resolvedArgv.inputToken);
    const outputToken = new web3_js_1.PublicKey(resolvedArgv.outputToken);
    const inputAmount = new anchor_1.BN(resolvedArgv.inputAmount);
    const outputAmount = new anchor_1.BN(resolvedArgv.outputAmount);
    const destinationChainId = new anchor_1.BN(resolvedArgv.destinationChainId);
    const exclusiveRelayer = web3_js_1.PublicKey.default;
    const quoteTimestamp = Math.floor(Date.now() / 1000) - 1;
    const fillDeadline = quoteTimestamp + 3600; // 1 hour from now
    const exclusivityDeadline = 0;
    const message = Buffer.from([]); // Convert to Buffer
    console.log("integratorId", resolvedArgv.integratorId);
    const integratorId = resolvedArgv.integratorId || "";
    // Define the state account PDA
    const [statePda, _] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("state"), seed.toArrayLike(Buffer, "le", 8)], programId);
    // Define the route account PDA
    const [routePda] = web3_js_1.PublicKey.findProgramAddressSync([
        Buffer.from("route"),
        inputToken.toBytes(),
        seed.toArrayLike(Buffer, "le", 8),
        destinationChainId.toArrayLike(Buffer, "le", 8),
    ], programId);
    // Define the signer (replace with your actual signer)
    const signer = provider.wallet.payer;
    // Find ATA for the input token to be stored by state (vault). This was created when the route was enabled.
    const vault = (0, spl_token_1.getAssociatedTokenAddressSync)(inputToken, statePda, true, spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID);
    console.log("Depositing V3...");
    console.table([
        { property: "seed", value: seed.toString() },
        { property: "recipient", value: recipient.toString() },
        { property: "inputToken", value: inputToken.toString() },
        { property: "outputToken", value: outputToken.toString() },
        { property: "inputAmount", value: inputAmount.toString() },
        { property: "outputAmount", value: outputAmount.toString() },
        { property: "destinationChainId", value: destinationChainId.toString() },
        { property: "quoteTimestamp", value: quoteTimestamp.toString() },
        { property: "fillDeadline", value: fillDeadline.toString() },
        { property: "exclusivityDeadline", value: exclusivityDeadline.toString() },
        { property: "message", value: message.toString("hex") },
        { property: "integratorId", value: integratorId },
        { property: "programId", value: programId.toString() },
        { property: "providerPublicKey", value: provider.wallet.publicKey.toString() },
        { property: "statePda", value: statePda.toString() },
        { property: "routePda", value: routePda.toString() },
        { property: "vault", value: vault.toString() },
    ]);
    const userTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(inputToken, signer.publicKey);
    const tokenDecimals = (await (0, spl_token_1.getMint)(provider.connection, inputToken, undefined, spl_token_1.TOKEN_PROGRAM_ID)).decimals;
    // Delegate state PDA to pull depositor tokens.
    const approveIx = await (0, spl_token_1.createApproveCheckedInstruction)(userTokenAccount, inputToken, statePda, signer.publicKey, BigInt(inputAmount.toString()), tokenDecimals, undefined, spl_token_1.TOKEN_PROGRAM_ID);
    const depositIx = await program.methods.deposit(signer.publicKey, recipient, inputToken, outputToken, inputAmount, outputAmount, destinationChainId, exclusiveRelayer, quoteTimestamp, fillDeadline, exclusivityDeadline, message)
        .accounts({
        state: statePda,
        route: routePda,
        signer: signer.publicKey,
        userTokenAccount,
        vault: vault,
        tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
        mint: inputToken,
    })
        .instruction();
    // Create a custom instruction with arbitrary data
    const depositTx = new web3_js_1.Transaction().add(approveIx, depositIx);
    if (integratorId !== "") {
        const MemoIx = new web3_js_1.TransactionInstruction({
            keys: [{ pubkey: signer.publicKey, isSigner: true, isWritable: true }],
            data: Buffer.from(integratorId, "utf-8"),
            programId: new web3_js_1.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), // Memo program ID
        });
        depositTx.add(MemoIx);
    }
    const tx = await (0, web3_js_1.sendAndConfirmTransaction)(provider.connection, depositTx, [signer]);
    console.log("Transaction signature:", tx);
}
// Run the depositV3 function
deposit();
