import { sign, poseidonHashMany } from "@scure/starknet";
async function sendStarknetTransfer(
to: string,
amount: number,
address: string,
publicKey: string,
privateKey: string,
): Promise<string> {
const amountWei = BigInt(Math.round(amount * 10 ** 18));
const amountLow = feltToHex(amountWei & ((BigInt(1) << BigInt(128)) - BigInt(1)));
const amountHigh = feltToHex(amountWei >> BigInt(128));
const nonce = await getNonce(address);
const STRK_TOKEN = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"; // trufflehog:ignore
const transferSelector = BigInt(
"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", // trufflehog:ignore
);
const calldata = [
"0x1",
STRK_TOKEN,
feltToHex(transferSelector),
"0x3",
to,
amountLow,
amountHigh,
];
const chainId = BigInt("0x534e5f5345504f4c4941"); // SN_SEPOLIA
const calldataFelts = calldata.map(c => BigInt(c));
const resourceBounds = poseidonHashMany([
BigInt("0x4c315f47415300000000000000000000"),
BigInt(0x2000), BigInt("0x1000000000000"),
BigInt("0x4c325f47415300000000000000000000"),
BigInt(0x200000), BigInt("0x10000000000"),
BigInt("0x4c315f444154415f47415300000000000000000000"),
BigInt(0x2000), BigInt("0x100000"),
]);
const txHash = poseidonHashMany([
BigInt("0x696e766f6b65"),
BigInt(3),
BigInt(address),
poseidonHashMany([BigInt(0), resourceBounds]),
poseidonHashMany([]),
chainId,
nonce,
BigInt(0),
poseidonHashMany([]),
poseidonHashMany(calldataFelts),
]);
const sig = sign(feltToHex(txHash), strip0x(privateKey));
const result = await starknetRpc("starknet_addInvokeTransaction", {
invoke_transaction: {
type: "INVOKE",
version: "0x3",
signature: [feltToHex(sig.r), feltToHex(sig.s)],
nonce: feltToHex(nonce),
sender_address: address,
calldata,
resource_bounds: {
l1_gas: { max_amount: "0x2000", max_price_per_unit: "0x1000000000000" },
l2_gas: { max_amount: "0x200000", max_price_per_unit: "0x10000000000" },
l1_data_gas: { max_amount: "0x2000", max_price_per_unit: "0x100000" },
},
tip: "0x0",
paymaster_data: [],
account_deployment_data: [],
nonce_data_availability_mode: "L1",
fee_data_availability_mode: "L1",
},
});
return result.transaction_hash;
}