Respond to Offer Manually Using TS interface
This guide explains how to respond to an offer manually by interacting with the contract interface using TypeScript. The process involves verifying the contract state, deploying the response contract, and sending the requested assets to the seller’s offer contract.
Steps to Respond to an Offer
Find Router Address: The first step is to find the current router address. In the current version of the contract, only one router can exist, but this may change in the future.
const router = provider.open(await MultiSwapRouter.fromInit()); if (!await provider.isContractDeployed(router.address)){ throw "Router not deployed"; }Enter Offer Address: You'll need the address of the seller's offer contract. Ask the user to input the offer address, then fetch the offer contract.
const offerAddress = await ui.inputAddress("Offer Address:"); const sellerSwap = provider.open(await MultiSwap.fromAddress(offerAddress)); if (!await provider.isContractDeployed(sellerSwap.address)){ throw "Seller swap not deployed at address"; }Check Contract State: Fetch the current state of the offer contract to ensure it is waiting for a buyer. The contract should be in
StateReadyToSwap(state 2). And not be expired at the time of the offer.To be extra safe one could check the
sellerData.expiration_time_secondsand limit users from sending transactions in last 10 minuteslet sellerData = await sellerSwap.getData(); let offeredItems = sellerData.offered_items; let requestedItems = sellerData.requested_items; let state = sellerData.state; if (state !== 2n) { throw "Contract is not waiting to bond"; } if (sellerData.is_expired){ throw "Contract is expired" }Calculate Minimum Value: Use the router to calculate the minimum value required to initiate the response.
const minValue = await router.getCalculateMinValue(requestedItems);Find Query ID: Loop through potential
queryIdvalues to find a valid one for the response contract, ensuring it doesn't interfere with any existing contracts.let queryId = 0n; let buyerSwap: OpenedContract<MultiSwap>; while (true) { buyerSwap = provider.open(await MultiSwap.fromInit( router.address, provider.sender().address!, queryId, false, // responder (not initiator) requestedItems, offeredItems )); if (!await provider.isContractDeployed(buyerSwap.address)){ break; } queryId = queryId + 1n; }Deploy the Response Contract: If the response contract is not already deployed, send the necessary initialization transaction to deploy the response contract.
Send Requested NFTs and Jettons: The next step is to send the requested NFTs and Jettons to the buyer’s contract. This should be done in a transaction, possibly with TonConnect if supporting multi-message transactions.
Usually NFTs and Jettons take 0.07 ton to be transferred and also to trigger the swap contract Do not forget to specify response_destination in order to get some funds back
forward_amountshould be set to0.02 ton
Confirm the Transaction: After sending the assets, confirm the transaction is complete. The contract should now be waiting to finalize the swap.
let buyerData = await buyerSwap.getData(); let state = buyerData.state; if (state !== 4n) { // StateSwapped: 4 throw "Contract did not swap correctly"; }Failed Scenario: In case if seller won't be able to find a buyer or for some reason won't be able to provide all the assets, contract will expire in
expiration_time_secondstimestampThis is only possible on StateFailed or when contract has expired on state
StateAwaitingFunds(1)|StateReadyToSwap(2)To retrieve lost assets, seller should message contract with"withdraw_seller"comment:await sellerSwap.send( provider.sender(), { value: toNano('0.03'), }, "withdraw_seller" );
This guide covers the process of responding to an offer manually using the TypeScript contract interface. After sending the requested NFTs and Jettons, the buyer’s response contract is deployed, and the swap contract is now waiting for confirmation.