@@ -9,6 +9,23 @@ import { parseDecimalToUnits } from '../solana/utils'
99
1010import { assertStarknetEid , getStarknetAccountFromEnv } from './utils'
1111
12+ // STRK token address on Starknet mainnet
13+ const STRK_TOKEN_ADDRESS = '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'
14+
15+ // Minimal ERC20 ABI for approve
16+ const ERC20_ABI = [
17+ {
18+ name : 'approve' ,
19+ type : 'function' ,
20+ inputs : [
21+ { name : 'spender' , type : 'core::starknet::contract_address::ContractAddress' } ,
22+ { name : 'amount' , type : 'core::integer::u256' } ,
23+ ] ,
24+ outputs : [ { type : 'core::bool' } ] ,
25+ state_mutability : 'external' ,
26+ } ,
27+ ]
28+
1229/**
1330 * Convert hex string to a string for Cairo ByteArray.
1431 * In starknet.js v8, ByteArray parameters accept plain strings.
@@ -72,7 +89,17 @@ export async function sendStarknet({
7289 }
7390
7491 const feeQuote = await oftContract . quote_send ( sendParam , false )
75- const call = await oftContract . populateTransaction . send (
92+
93+ // Create STRK approval for the native fee (with 10% buffer for price fluctuation)
94+ const feeWithBuffer = ( BigInt ( feeQuote . native_fee ) * 110n ) / 100n
95+ const strkContract = new Contract ( {
96+ abi : ERC20_ABI as any ,
97+ address : STRK_TOKEN_ADDRESS ,
98+ providerOrAccount : account ,
99+ } )
100+ const approveCall = strkContract . populateTransaction . approve ( oftAddress , { low : feeWithBuffer , high : 0n } )
101+
102+ const sendCall = oftContract . populateTransaction . send (
76103 sendParam ,
77104 {
78105 native_fee : feeQuote . native_fee ,
@@ -81,7 +108,8 @@ export async function sendStarknet({
81108 account . address
82109 )
83110
84- const response = await account . execute ( [ call ] )
111+ // Execute approval and send in a single multicall
112+ const response = await account . execute ( [ approveCall , sendCall ] )
85113 const txHash = response . transaction_hash
86114 await provider . waitForTransaction ( txHash )
87115
0 commit comments