In this section, you will learn how to approve tokens for spending, which is a crucial step before interacting with decentralized exchanges or smart contracts. When interacting with a decentralized exchange (like Motoswap), you must first approve the contract to spend your tokens on your behalf.
Step 1: Install Required Packages
Ensure you have the necessary dependencies installed in your project:
To approve token spending, you need to interact with the token's smart contract (following the OP_20 standard) and give permission to the decentralized exchange (or any other contract) to spend tokens on your behalf.
import { IInteractionParameters, TransactionFactory, Wallet,} from"@btc-vision/transaction";import { getContract, IOP_20Contract, OP_20_ABI, UTXO } from"opnet";/** * Approves tokens for spending on the OP_NET metaprotocol. * * @param{Wallet} walletGet - The wallet object containing keypairs and addresses. * @param{string} tokenAddress - The address of the token (OP_20 standard). * @param{bigint} approveAmount - The amount of tokens to approve for spending. * @param{UTXO[]} utxos - The UTXOs for funding the transaction. * @returns Approval transaction result */asyncfunctionapproveToken( walletGet:Wallet, tokenAddress:string, approveAmount:bigint, utxos:UTXO[]) {try {// Get the token contract using the OP_20 ABIconstcontract=getContract<IOP_20Contract>( tokenAddress,OP_20_ABI, provider,walletGet.p2tr );// The address of the decentralized exchange or contract that will spend the tokensconstrouterAddress="bcrt1q9yd6mk324k0q4krmlxjky0pk65ul6hkf4u35e6"; // Actual router address on regtest// Check the current allowance (how much the router is allowed to spend)constcurrentAllowance=awaitcontract.allowance(walletGet.p2tr, routerAddress );if ("error"in currentAllowance) {thrownewError(currentAllowance.error); }constremainingAllowance=BigInt(currentAllowance.decoded[0].toString());// Only approve if the current allowance is less than the amount to approveif (remainingAllowance >= approveAmount) {return { success:true, message:"Token is already approved." }; }// Approve the maximum possible amount (or the amount you want)constmaxApprovalAmount=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" );constapproveTx=awaitcontract.approve(routerAddress, maxApprovalAmount);if ("error"in approveTx) {thrownewError(approveTx.error); }// Create transaction parameters for the approval interactionconstinteractionParameters:IInteractionParameters= { from:walletGet.p2tr, to:contract.address.toString(), utxos,// UTXOs to fund the transaction signer:walletGet.keypair,// Wallet's keypair for signing the transaction network,// The BitcoinJS network feeRate:100,// Fee rate in satoshis per byte priorityFee:330n,// Priority fee for faster transaction calldata:approveTx.calldata asBuffer,// The calldata for the approve interaction };// Create and sign the transactionconsttransactionFactory=newTransactionFactory();constsignedTx=awaittransactionFactory.signInteraction( interactionParameters );// Broadcast the transactionconstlimitedProvider=newOPNetLimitedProvider("https://regtest.opnet.org" ); // Initialize the OP_NET limited providerconstfirstTxBroadcast=awaitlimitedProvider.broadcastTransaction( signedTx[0],false );if (!firstTxBroadcast ||!firstTxBroadcast.success) {thrownewError("First transaction broadcast failed."); }constsecondTxBroadcast=awaitlimitedProvider.broadcastTransaction( signedTx[1],false );if (!secondTxBroadcast ||!secondTxBroadcast.success) {thrownewError("Second transaction broadcast failed."); }return { success:true }; } catch (error) {console.error("Token approval failed:", error);return { success:false, message: error }; }}// Example usage:asyncfunctionmain() {constwalletWif="your-wallet-private-key-in-wif-format"; // Replace with your WIF private keyconstwalletGet=Wallet.fromWif(walletWif, network); // Import wallet using WIF formatconsttokenAddress="your-token-address"; // Replace with your token's addressconstapproveAmount=100_000n; // Amount of tokens to approve for spendingconstutxos=awaitgetUTXOs(walletGet.addresses, rpcUrl, approveAmount); // Fetch UTXOs for the approvalconstresult=awaitapproveToken( walletGet, tokenAddress, approveAmount, utxos );if (result.success) {console.log("Token successfully approved for spending."); } else {console.error("Approval failed:",result.message); }}main();