Skip to content

Instantly share code, notes, and snippets.

@mfbevan
Created January 16, 2025 04:20
Show Gist options
  • Select an option

  • Save mfbevan/08079dd9c6a46b732f652c8d4ec8b83f to your computer and use it in GitHub Desktop.

Select an option

Save mfbevan/08079dd9c6a46b732f652c8d4ec8b83f to your computer and use it in GitHub Desktop.
Solana Quote Send
import { Options, addressToBytes32 } from "@layerzerolabs/lz-v2-utilities";
import { mplToolbox } from "@metaplex-foundation/mpl-toolbox";
import { publicKey, signerIdentity } from "@metaplex-foundation/umi";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import {} from "@metaplex-foundation/umi-rpc-web3js";
import { createSignerFromWalletAdapter } from "@metaplex-foundation/umi-signer-wallet-adapters";
import { toWeb3JsInstruction } from "@metaplex-foundation/umi-web3js-adapters";
import { solanaDevnetChain, solanaMainnetChain } from "@packages-lib/constants";
import {
isSolanaDevnetEndpoint,
isSolanaEndpoint,
} from "@packages-lib/front-end-helpers";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { WalletContextState, useWallet } from "@solana/wallet-adapter-react";
import { Connection, Transaction, PublicKey } from "@solana/web3.js";
import { useMutation, useQuery } from "@tanstack/react-query";
import { formatUnits, parseUnits } from "ethers/lib/utils";
import { quoteSend } from "./solana-oft/umi/instructions/quoteSend";
import { send } from "./solana-oft/umi/instructions/send";
import { createOFTProgramRepo } from "./solana-oft/umi/programs";
import { addComputeUnitInstructions } from "./solana-oft/umi/programs/lz";
import { LZBridgeTxHandlerProps } from "./types";
const COMPUTE_UNIT_PRICE_SCALE_FACTOR = 4;
// TODO: pull this from the db asset
const MINT = "CiuH3kcRXJhdikbZsjfpvFaMaGVSCmFodWcwizjhhXcY";
const ESCROW = "N3pbaDnicH7Z8o4HQc7QUx9MR7s8cNrzm2Rnd3XPmia";
const OFT_PROGRAM_ID = "FGrGEthyEeu5vmb84u7TG6HGWeHUrpim7y8jDCjrxCsT";
const OFT_STORE = "UWVUEwjkUWRMSfrsUgi37KoDEGS3ApBPMw3sLDmxxtw";
const PEER = "Fte168xVZNfWBLYhrmSBqXY8XSgbVzeC5EKZjHzSr5JU";
const TOKEN_SOURCE = "J7iKVtDngK8jr5ZZdSi9GNexan74V2N6cPsWyHbo4kZD"; // TODO: pull this dynamically
const EVENT_AUTHORITY = "Ak4eNSq749m1CtghNh8bjbj5MrreYGuHLLXevgdeiSki"; // TODO: not sure where this comes from
export const quoteFromSolana = async (
solanaWallet: WalletContextState,
{ wallet, amount, fromChain, toChain }: LZBridgeTxHandlerProps
): Promise<{ nativeFee: bigint; lzTokenFee: bigint }> => {
if (!amount || !fromChain || !toChain || !wallet || !solanaWallet) {
return { nativeFee: BigInt(0), lzTokenFee: BigInt(0) };
}
const { rpc } = isSolanaDevnetEndpoint(toChain.lzChainId)
? solanaDevnetChain
: solanaMainnetChain;
const umi = createUmi(rpc, { commitment: "processed" }).use(mplToolbox());
const signer = createSignerFromWalletAdapter(solanaWallet);
umi.use(signerIdentity(signer));
const params = {
tokenMint: publicKey(MINT),
peer: publicKey(PEER),
oftStore: publicKey(OFT_STORE),
params: {
dstEid: toChain.lzChainId,
to: Array.from(addressToBytes32(wallet.address)),
amountLd: parseUnits(amount.toString(), 9).toBigInt(),
minAmountLd: BigInt(1),
options: Options.newOptions().toBytes(),
composeMsg: null,
payInLzToken: false,
},
};
const txBuilder = quoteSend({ programs: createOFTProgramRepo() }, params);
const ix = toWeb3JsInstruction(txBuilder.getInstructions()[0]);
const connection = new Connection(umi.rpc.getEndpoint(), "confirmed");
const tx = new Transaction().add(ix);
tx.feePayer = new PublicKey(signer.publicKey);
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
const result = await connection.simulateTransaction(tx, undefined, true);
return {
nativeFee: BigInt(0),
lzTokenFee: BigInt(0),
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment