import { sha256 } from "@noble/hashes/sha2";
import bs58 from "bs58";
async function sendNearTransfer(
recipient: string,
amountNear: number,
nearAddress: string,
): Promise<string> {
const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "SOL")!;
const pubkey = bs58.decode(wallet.address);
const [wholePart, fracPart = ""] = amountNear.toString().split(".");
const paddedFrac = fracPart.padEnd(24, "0").slice(0, 24);
const amountYocto = BigInt(wholePart + paddedFrac);
const [accessKeyResult, blockResult] = await Promise.all([
nearRpc("query", {
request_type: "view_access_key",
finality: "final",
account_id: nearAddress,
public_key: `ed25519:${bs58.encode(pubkey)}`,
}),
nearRpc("block", { finality: "final" }),
]);
const nonce = BigInt(accessKeyResult.nonce) + BigInt(1);
const blockHash = bs58.decode(blockResult.header.hash);
const txBytes = concatBytes(
borshString(nearAddress),
borshU8(0), // PublicKey variant: ed25519
pubkey, // 32-byte pubkey
borshU64(nonce),
borshString(recipient),
blockHash, // 32-byte block hash
borshU32(1), // number of actions
borshU8(3), // Transfer action variant
borshU128(amountYocto),
);
const txHash = sha256(txBytes);
const { signedMessage } = await dynamicClient.wallets.signMessage({
wallet,
message: bytesToHex(txHash),
});
const sigBytes = decodeSig(signedMessage);
const signedTxBytes = concatBytes(txBytes, borshU8(0), sigBytes);
const signedTxBase64 = btoa(String.fromCharCode(...signedTxBytes));
const result = await nearRpc("broadcast_tx_commit", [signedTxBase64]);
return result.transaction.hash;
}