UNPKG

@arcana/ca-sdk

Version:

Arcana Network's chain abstraction SDK for unified balance in Web3 apps

105 lines (104 loc) 4.25 kB
import { bn, CHAIN_IDS } from "fuels"; import { encodeFunctionData } from "viem"; import ERC20ABI from "../abi/erc20"; import { ZERO_ADDRESS } from "../constants"; import { getLogger } from "../logger"; import { convertIntent, equalFold, mulDecimals } from "../utils"; const logger = getLogger(); class TransferQuery { constructor(input, init, switchChain, createEVMHandler, createFuelHandler, evmAddress, chainList, fuelAccount) { this.input = input; this.init = init; this.switchChain = switchChain; this.createEVMHandler = createEVMHandler; this.createFuelHandler = createFuelHandler; this.evmAddress = evmAddress; this.chainList = chainList; this.fuelAccount = fuelAccount; this.handlerResponse = null; this.exec = async () => { if (!this.handlerResponse?.handler) { throw new Error("ca not applicable"); } await this.handlerResponse.handler.process(); logger.debug("TransferQuery:Exec", { state: "processing completed, going to processTx()", }); return this.handlerResponse.processTx(); }; this.simulate = async () => { if (!this.handlerResponse?.handler) { throw new Error("ca not applicable"); } const response = await this.handlerResponse.handler.buildIntent(); if (!response) { throw new Error("ca not applicable"); } return { intent: convertIntent(response.intent, response.token, this.chainList), token: response.token, }; }; } async initHandler() { if (!this.handlerResponse) { const input = this.input; await this.init(); logger.debug("SendQueryBuilder.exec", { c: input.chainID, p: input, }); if (input.to && input.amount !== undefined && input.token && input.chainID) { const tokenInfo = this.chainList.getTokenInfoBySymbol(input.chainID, input.token); if (!tokenInfo) { throw new Error("Token not supported on this chain."); } const amount = mulDecimals(input.amount, tokenInfo.decimals); logger.debug("transfer:2", { amount, tokenInfo }); if (input.chainID === CHAIN_IDS.fuel.mainnet) { if (this.fuelAccount) { const tx = await this.fuelAccount.createTransfer(input.to, bn(amount.toString()), tokenInfo.contractAddress); this.handlerResponse = await this.createFuelHandler(tx, { bridge: false, gas: 0n, skipTx: false, }); } else { throw new Error("Fuel connector is not set"); } } else { await this.switchChain(input.chainID); const isNative = equalFold(tokenInfo.contractAddress, ZERO_ADDRESS); const p = { from: this.evmAddress, to: input.to, }; if (isNative) { p.value = `0x${amount.toString(16)}`; } else { p.to = tokenInfo.contractAddress; p.data = encodeFunctionData({ abi: ERC20ABI, args: [input.to, amount], functionName: "transfer", }); } this.handlerResponse = await this.createEVMHandler(p, { bridge: false, gas: 0n, skipTx: false, }); } return; } throw new Error("transfer: missing params"); } } } export { TransferQuery };