@avalabs/bridge-unified
Advanced tools
Comparing version 0.0.0-feat-unified-bridge-cctp-revie-20240111095801 to 0.0.0-fix-address-comparison-20240119104940
# @avalabs/unified-bridge | ||
## 0.0.0-feat-unified-bridge-cctp-revie-20240111095801 | ||
## 0.0.0-fix-address-comparison-20240119104940 | ||
### Patch Changes | ||
- d363bd8: fix: lowercase addresses for comparison | ||
## 2.0.0 | ||
### Major Changes | ||
@@ -13,3 +19,3 @@ | ||
- 54757d4: Make sourceProvider optional, add bridged asset denomination info | ||
- ea5ce6f: update and validate startBlockNumber while tracking | ||
- b8f102b: update and validate startBlockNumber while tracking | ||
@@ -16,0 +22,0 @@ ## 1.0.1 |
@@ -125,2 +125,11 @@ import { Address } from 'viem'; | ||
}; | ||
declare enum BridgeSignatureReason { | ||
AllowanceApproval = "allowance-approval", | ||
TokensTransfer = "tokens-transfer" | ||
} | ||
type BridgeStepDetails = { | ||
currentSignature: number; | ||
requiredSignatures: number; | ||
currentSignatureReason: BridgeSignatureReason; | ||
}; | ||
type TransferParams = { | ||
@@ -135,2 +144,3 @@ asset: BridgeAsset; | ||
targetProvider?: Provider; | ||
onStepChange?: (stepDetails: BridgeStepDetails) => void; | ||
sign?: Signer; | ||
@@ -201,2 +211,2 @@ }; | ||
export { Asset, AssetFeeMap, BridgeAsset, BridgeConfig, BridgeService, BridgeServiceConfig, BridgeServiceFactory, BridgeTransfer, BridgeType, Chain, ChainAssetMap, DestinationInfo, Dispatch, Environment, ErrorCode, ErrorReason, FeeParams, Hex, Provider, Signer, TokenType, TrackingParams, TransactionRequest, TransferParams, _default as caip2, createUnifiedBridgeService }; | ||
export { Asset, AssetFeeMap, BridgeAsset, BridgeConfig, BridgeService, BridgeServiceConfig, BridgeServiceFactory, BridgeSignatureReason, BridgeStepDetails, BridgeTransfer, BridgeType, Chain, ChainAssetMap, DestinationInfo, Dispatch, Environment, ErrorCode, ErrorReason, FeeParams, Hex, Provider, Signer, TokenType, TrackingParams, TransactionRequest, TransferParams, _default as caip2, createUnifiedBridgeService }; |
import { custom, http, createWalletClient, publicActions, isAddress, encodeFunctionData, decodeEventLog } from 'viem'; | ||
import { mergeWith, isArray } from 'lodash'; | ||
var H=(r=>(r.NATIVE="native",r.ERC20="erc20",r))(H||{});var R=(t=>(t.CCTP="cctp",t))(R||{});var V=(r=>(r.PROD="production",r.TEST="test",r))(V||{});var k=(n=>(n[n.BRIDGE_NOT_AVAILABLE=5001]="BRIDGE_NOT_AVAILABLE",n[n.INITIALIZATION_FAILED=5002]="INITIALIZATION_FAILED",n[n.INVALID_PARAMS=5003]="INVALID_PARAMS",n[n.TIMEOUT=5004]="TIMEOUT",n[n.TRANSACTION_REVERTED=5005]="TRANSACTION_REVERTED",n))(k||{}),h=(i=>(i.UNKNOWN="UNKNOWN",i.CONFIG_NOT_AVAILABLE="CONFIG_NOT_AVAILABLE",i.INVALID_PARAMS="INVALID_PARAMS",i.IDENTICAL_CHAINS_PROVIDED="IDENTICAL_CHAINS_PROVIDED",i.INCORRECT_AMOUNT_PROVIDED="INCORRECT_AMOUNT_PROVIDED",i.INCORRECT_ADDRESS_PROVIDED="INCORRECT_ADDRESS_PROVIDED",i.CHAIN_NOT_SUPPORTED="CHAIN_NOT_SUPPORTED",i.ASSET_NOT_SUPPORTED="ASSET_NOT_SUPPORTED",i.CONFIRMATION_COUNT_UNKNOWN="CONFIRMATION_COUNT_UNKNOWN",i))(h||{});var I=class extends Error{constructor(r,a,u){super(r);this.code=a;this.details=u;}};var P=class extends I{constructor(t="UNKNOWN",r){super(t,5001,r),this.name="BridgeUnavailableError";}};var B=class extends I{constructor(t="UNKNOWN",r){super(t,5002,r),this.name="BridgeInitializationError";}};var f=class extends I{constructor(t="INVALID_PARAMS",r){super(t,5003,r),this.name="InvalidParamsError";}};var re={test:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json",production:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json"},K=async e=>{try{return (await(await fetch(re[e])).json()).map(a=>({...a,chainId:`eip155:${a.chainId}`}))}catch(t){throw new B("CONFIG_NOT_AVAILABLE",`Error while fetching CCTP config: ${t.message}`)}},O=e=>{switch(e){case"eip155:43114":case"eip155:43113":return 1e3;default:return 2e4}};async function $(e){await e.ensureHasConfig();let t=e.config.map(r=>r.chainId);return e.config.reduce((r,a)=>(r[a.chainId]=a.tokens.map(u=>({...u,type:"erc20",destinations:t.reduce((n,o)=>(a.chainId!==o&&(n[o]||(n[o]=[]),n[o]?.push("cctp")),n),{})})),r),{})}var ae="^[-a-z0-9]{3,8}$",se="^[-_a-zA-Z0-9]{1,50}$",G=":",ie=e=>{let[t,r]=e.split(G);if(!t||!r)throw new Error("Invalid identifier provided.");if(!new RegExp(ae).test(t))throw new Error("Invalid namespace provided.");if(!new RegExp(se).test(r))throw new Error("Invalid reference provided.");return {namespace:t,reference:r}},oe=({namespace:e,reference:t})=>`${e}${G}${t}`,E={toJSON:ie,toString:oe};var me=e=>{let{reference:t}=E.toJSON(e.chainId);return {id:Number(t),name:e.chainName,nativeCurrency:{decimals:e.networkToken.decimals,symbol:e.networkToken.symbol,name:e.networkToken.name},network:e.chainName,rpcUrls:{default:{http:[e.rpcUrl]},public:{http:[e.rpcUrl]}},...e.utilityAddresses?.multicall&&{contracts:{multicall3:{address:e.utilityAddresses.multicall}}}}},w=({chain:e,provider:t})=>{let r=me(e),a=t?custom(t):http(e.rpcUrl,{batch:!0,retryCount:0});return createWalletClient({chain:r,transport:a}).extend(publicActions)};var N=[{inputs:[{internalType:"address",name:"circleTokenMessenger_",type:"address"},{internalType:"address",name:"burnToken_",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"AlreadyAdmin",type:"error"},{inputs:[],name:"AlreadyFeeCollector",type:"error"},{inputs:[],name:"AlreadySupportedBurnToken",type:"error"},{inputs:[],name:"AmountLessThanFee",type:"error"},{inputs:[],name:"BalanceNotIncreased",type:"error"},{inputs:[],name:"CannotRemoveLastAdmin",type:"error"},{inputs:[],name:"FeePercentageGreaterThanMax",type:"error"},{inputs:[],name:"InvalidAdminAddress",type:"error"},{inputs:[],name:"InvalidFeeCollector",type:"error"},{inputs:[],name:"InvalidMintRecipientAddress",type:"error"},{inputs:[],name:"InvalidTokenAddress",type:"error"},{inputs:[],name:"InvalidTokenMessengerAddress",type:"error"},{inputs:[],name:"MaxFeeLessThanMinFee",type:"error"},{inputs:[],name:"NotAdmin",type:"error"},{inputs:[],name:"NotFeeCollector",type:"error"},{inputs:[],name:"UnSupportedBurnToken",type:"error"},{inputs:[],name:"UnsupportedDomain",type:"error"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],indexed:!1,internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"FeeConfigurationUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"previousOwner",type:"address"},{indexed:!0,internalType:"address",name:"newOwner",type:"address"}],name:"OwnershipTransferred",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Paused",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"address",name:"burnToken",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"address",name:"depositor",type:"address"},{indexed:!1,internalType:"address",name:"mintRecipient",type:"address"},{indexed:!1,internalType:"uint32",name:"destinationDomain",type:"uint32"},{indexed:!1,internalType:"uint256",name:"totalFee",type:"uint256"}],name:"TransferTokens",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Unpaused",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"addAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"addFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"addSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"}],name:"calculateFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessenger",outputs:[{internalType:"contract ICircleTokenMessenger",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessengerAddress",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"collectFees",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"getFeeAmounts",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeeConfiguration",outputs:[{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeePercentage",outputs:[{internalType:"uint32",name:"",type:"uint32"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMaxFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMinFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getTxnFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isAdmin",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isFeeCollector",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"isSupportedBurnToken",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"isSupportedDomain",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"owner",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"pause",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"paused",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"removeAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"removeFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"removeSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"renounceOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"setFeeConfiguration",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"",type:"address"}],name:"supportedBurnTokens",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"newOwner",type:"address"}],name:"transferOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"},{internalType:"address",name:"mintRecipient",type:"address"},{internalType:"address",name:"burnToken",type:"address"}],name:"transferTokens",outputs:[{internalType:"uint64",name:"nonce",type:"uint64"}],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"unpause",outputs:[],stateMutability:"nonpayable",type:"function"}];var _=({sourceChain:e,targetChain:t,amount:r,asset:a},u)=>{if(e.chainId===t.chainId)throw new f("IDENTICAL_CHAINS_PROVIDED");if(r<=0n)throw new f("INCORRECT_AMOUNT_PROVIDED","Amount must be greater than zero");let n=u.find(i=>i.chainId===e.chainId);if(!n)throw new f("CHAIN_NOT_SUPPORTED",`Not supported on source chain "${e.chainId}"`);let o=u.find(i=>i.chainId===t.chainId);if(!o)throw new f("CHAIN_NOT_SUPPORTED",`Not supported on target chain "${t.chainId}"`);let d=n.tokens.find(i=>i.symbol===a.symbol),l=o.tokens.find(i=>i.symbol===a.symbol);if(!d||!l)throw new f("ASSET_NOT_SUPPORTED");return {sourceChainData:n,targetChainData:o,burnToken:d,mintToken:l}};async function W(e,t){await e.ensureHasConfig();let{sourceChain:r,targetChain:a,asset:u,amount:n,provider:o}=t,{sourceChainData:d,targetChainData:l,burnToken:i}=_({sourceChain:r,targetChain:a,asset:u,amount:n},e.config),p=await w({chain:r,provider:o}).readContract({address:d.tokenRouterAddress,abi:N,functionName:"calculateFee",args:[n,l.domain]});return {[i.address]:p}}var F=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_spender",type:"address"},{name:"_value",type:"uint256"}],name:"approve",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"totalSupply",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_from",type:"address"},{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transferFrom",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"decimals",outputs:[{name:"",type:"uint8"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"balanceOf",outputs:[{name:"balance",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[],name:"symbol",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transfer",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"},{name:"_spender",type:"address"}],name:"allowance",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{payable:!0,stateMutability:"payable",type:"fallback"},{anonymous:!1,inputs:[{indexed:!0,name:"owner",type:"address"},{indexed:!0,name:"spender",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"from",type:"address"},{indexed:!0,name:"to",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Transfer",type:"event"}];var ye=async(e,t)=>{let{sourceChain:r,targetChain:a,asset:u,amount:n,fromAddress:o,toAddress:d,sourceProvider:l,sign:i}=t,s=d??o;if(!isAddress(o)||!isAddress(s))throw new f("INCORRECT_ADDRESS_PROVIDED");let{sourceChainData:p,targetChainData:y,burnToken:m}=_({sourceChain:r,targetChain:a,asset:u,amount:n},e.config),c=w({chain:r,provider:l});if(await c.readContract({address:m.address,abi:F,functionName:"allowance",args:[o,p.tokenRouterAddress]})<n)if(i){let T=encodeFunctionData({abi:F,functionName:"approve",args:[p.tokenRouterAddress,n]}),g=await i({from:o,to:m.address,data:T},b=>c.sendRawTransaction({serializedTransaction:b}));await c.waitForTransactionReceipt({hash:g,pollingInterval:1e3});}else {let{request:T}=await c.simulateContract({account:o,address:m.address,abi:F,functionName:"approve",args:[p.tokenRouterAddress,n]}),g=await c.writeContract(T);await c.waitForTransactionReceipt({hash:g,pollingInterval:1e3});}if(i){let T=encodeFunctionData({abi:N,functionName:"transferTokens",args:[n,y.domain,s,m.address]});return i({from:o,to:p.tokenRouterAddress,data:T},g=>c.sendRawTransaction({serializedTransaction:g}))}else {let{request:T}=await c.simulateContract({account:o,address:p.tokenRouterAddress,abi:N,functionName:"transferTokens",args:[n,y.domain,s,m.address]});return c.writeContract(T)}},le=async e=>{try{return await e.getBlockNumber()}catch{return}};async function z(e,t,r){await e.ensureHasConfig();let{minimumConfirmations:a}=e.config.find(p=>p.chainId===t.sourceChain.chainId)??{},{minimumConfirmations:u}=e.config.find(p=>p.chainId===t.targetChain.chainId)??{};if(!a||!u)throw new f("CONFIRMATION_COUNT_UNKNOWN");let n=await e.getFees({...t,provider:t.sourceProvider}),o=(t.asset.address&&n[t.asset.address])??0n,d=await ye(e,t),l=Date.now(),i=w({chain:t.targetChain,provider:t.targetProvider}),s=await le(i);return {type:e.type,environment:r,fromAddress:t.fromAddress,toAddress:t.toAddress??t.fromAddress,amount:t.amount,amountDecimals:t.asset.decimals,symbol:t.asset.symbol,bridgeFee:o,sourceChain:t.sourceChain,sourceStartedAt:l,sourceTxHash:d,sourceConfirmationCount:0,requiredSourceConfirmationCount:a,targetChain:t.targetChain,targetConfirmationCount:0,requiredTargetConfirmationCount:u,startBlockNumber:s}}async function J(e){if(!e.config&&(await e.updateConfig(),!e.config))throw new B("CONFIG_NOT_AVAILABLE")}var S=(e,t)=>e.gasPrice&&BigInt(e.gasPrice*t.gasUsed);var L=async e=>new Promise(t=>{setTimeout(t,e);});var U=({promise:e,delay:t,startAfter:r})=>{let a=!1,u=!1,n=0,o,d,l=p=>{o&&a&&(a=!1,o(p));},i=()=>{u=!0,d&&a&&(a=!1,d("cancelled"));};return {result:new Promise((p,y)=>{a=!0,o=p,d=y;let m=async()=>{if(!(!a||u)){try{if(await e(l),!a||u)return;await L(t);}catch(c){console.error(c.message),n+=1,await L(2**n*t);}await m();}};r?setTimeout(m,r):m();}),cancel:i}};var Y=1e3*60*60*3,X=1024n,Q=5e3,C=(e,t,r)=>{Object.assign(e,Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0))),r({...e});},fe=async(e,t)=>{let{sourceProvider:r,targetProvider:a,updateListener:u,bridgeTransfer:n}=t,o=w({chain:n.sourceChain,provider:r}),d=e.find(y=>y.chainId===n.sourceChain.chainId),l=w({chain:n.targetChain,provider:a}),i=e.find(y=>y.chainId===n.targetChain.chainId),s={...n};if(!d||!i)throw new f("CHAIN_NOT_SUPPORTED");return U({promise:async y=>{if(s.completedAt||s.metadata?.nonce)return y(s);if(s.sourceStartedAt+Y<=Date.now())return C(s,{completedAt:Date.now(),errorCode:5004},u),y(s);let m=await o.getTransactionReceipt({hash:s.sourceTxHash});if(!s.sourceNetworkFee){let v=await o.getTransaction({hash:s.sourceTxHash}),D=S(v,m);D&&C(s,{sourceNetworkFee:D},u);}if(m.status==="reverted")return C(s,{completedAt:Date.now(),errorCode:5005},u),y(s);let c=await o.getTransactionConfirmations({hash:s.sourceTxHash}),A=c>s.sourceConfirmationCount,T=c>=s.requiredSourceConfirmationCount;if(A){let v={};v.sourceConfirmationCount=Number(c),T||(v.startBlockNumber=await l.getBlockNumber()),C(s,v,u);}if(!T)return;s.startBlockNumber||C(s,{startBlockNumber:await l.getBlockNumber()},u);let g=m.logs.find(v=>v.address===d.tokenRouterAddress?decodeEventLog({abi:N,...v}).eventName==="TransferTokens":!1);if(!g)throw new f("INVALID_PARAMS",`unable to find a TransferTokens event in source transaction "${s.sourceTxHash}"`);let x=decodeEventLog({abi:N,eventName:"TransferTokens",...g}).args.nonce;return C(s,{targetStartedAt:Date.now(),metadata:{nonce:x}},u),y(s)},delay:O(d.chainId),startAfter:Q})},Te=async(e,t)=>{let{targetProvider:r,updateListener:a,bridgeTransfer:u}=t,n={...u};if(!u.completedAt&&!u.metadata?.nonce)throw new f("INVALID_PARAMS","nonce is missing");if(!u.startBlockNumber)throw new f("INVALID_PARAMS","startBlockNumber is missing");let o=w({chain:u.targetChain,provider:r}),d=e.find(i=>i.chainId===u.targetChain.chainId);if(!d)throw new f("INVALID_PARAMS",`unknown target chain "${u.targetChain.chainId}"`);return U({promise:async i=>{if(n.completedAt)return i(n);if(!n.startBlockNumber)return C(n,{completedAt:Date.now(),errorCode:5003},a),i(n);if(n.sourceStartedAt+Y<=Date.now())return C(n,{completedAt:Date.now(),errorCode:5004},a),i(n);if(!n.targetTxHash){let c=await o.getBlockNumber(),A=n.startBlockNumber-X,T=A>=0n?A:"earliest",g=n.startBlockNumber+X,b=g<c?g:"latest",x=await o.getLogs({address:d.messageTransmitterAddress,event:{name:"MessageReceived",type:"event",inputs:[{indexed:!0,internalType:"address",name:"caller",type:"address"},{indexed:!1,internalType:"uint32",name:"sourceDomain",type:"uint32"},{indexed:!0,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"bytes32",name:"sender",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"messageBody",type:"bytes"}]},args:{nonce:n.metadata.nonce},fromBlock:T,toBlock:b});if(x[0]?.transactionHash)C(n,{targetTxHash:x[0].transactionHash},a);else {C(n,{startBlockNumber:c},a);return}}let s=await o.getTransactionReceipt({hash:n.targetTxHash});if(!n.targetNetworkFee){let c=await o.getTransaction({hash:n.targetTxHash}),A=S(c,s);A&&C(n,{targetNetworkFee:A},a);}if(s.status==="reverted")return C(n,{completedAt:Date.now(),errorCode:5005},a),i(n);let p=await o.getTransactionConfirmations({hash:n.targetTxHash}),y=p>n.targetConfirmationCount,m=p>=n.requiredTargetConfirmationCount;if(y&&C(n,{targetConfirmationCount:Number(p)},a),!!m)return C(n,{completedAt:Date.now()},a),i(n)},delay:O(d.chainId),startAfter:Q})};function ee(e,t){let r,a=()=>{r?.();};return {result:(async()=>{await e.ensureHasConfig();let{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:l}=t,{result:i,cancel:s}=await fe(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:l});r=s;let p=await i,{result:y,cancel:m}=await Te(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:p});return r=m,y})(),cancel:a}}var te=e=>({type:"cctp",config:null,updateConfig:async function(){this.config=await K(e);},ensureHasConfig:async function(){return J(this)},getAssets:async function(){return $(this)},getFees:async function(t){return W(this,t)},transferAsset:async function(t){return z(this,t,e)},trackTransfer:function(t){return ee(this,t)}});var ge=new Map([["cctp",te]]),ne=(e,t)=>new Map([...ge].filter(([r])=>!t?.includes(r)).map(([r,a])=>[r,a(e)])),M=(e,t,r)=>{let a=t.destinations[r]?.find(u=>e.has(u));if(!a)throw new P;return {type:a,bridge:e.get(a)}};var un=({environment:e,disabledBridgeTypes:t})=>{let r=ne(e,t),a=async()=>{await Promise.allSettled(Array.from(r).map(([,s])=>s.updateConfig()));};return {environment:e,bridges:r,init:async()=>{await a();},updateConfigs:a,getAssets:async()=>(await Promise.all(Array.from(r).map(([,p])=>p.getAssets()))).reduce((p,y)=>{for(let[m,c]of Object.entries(y)){let A=p[m];if(A)for(let T of c){let g=A.findIndex(({symbol:b})=>b===T.symbol);g===-1?A.push(T):mergeWith(A[g],T,(b,x)=>{if(isArray(b))return [...new Set(b.concat(x))]});}else p[m]=c;}return p},{}),getFees:async s=>{let{bridge:p}=M(r,s.asset,s.targetChain.chainId);return p.getFees(s)},canTransferAsset:(s,p)=>{try{return M(r,s,p),!0}catch{return !1}},transferAsset:async s=>{let{bridge:p}=M(r,s.asset,s.targetChain.chainId);return p.transferAsset(s)},trackTransfer:s=>{let p=r.get(s.bridgeTransfer.type);if(!p)throw new P;return p.trackTransfer(s)}}}; | ||
var H=(r=>(r.NATIVE="native",r.ERC20="erc20",r))(H||{});var E=(t=>(t.CCTP="cctp",t))(E||{}),V=(r=>(r.AllowanceApproval="allowance-approval",r.TokensTransfer="tokens-transfer",r))(V||{});var K=(r=>(r.PROD="production",r.TEST="test",r))(K||{});var R=(n=>(n[n.BRIDGE_NOT_AVAILABLE=5001]="BRIDGE_NOT_AVAILABLE",n[n.INITIALIZATION_FAILED=5002]="INITIALIZATION_FAILED",n[n.INVALID_PARAMS=5003]="INVALID_PARAMS",n[n.TIMEOUT=5004]="TIMEOUT",n[n.TRANSACTION_REVERTED=5005]="TRANSACTION_REVERTED",n))(R||{}),v=(i=>(i.UNKNOWN="UNKNOWN",i.CONFIG_NOT_AVAILABLE="CONFIG_NOT_AVAILABLE",i.INVALID_PARAMS="INVALID_PARAMS",i.IDENTICAL_CHAINS_PROVIDED="IDENTICAL_CHAINS_PROVIDED",i.INCORRECT_AMOUNT_PROVIDED="INCORRECT_AMOUNT_PROVIDED",i.INCORRECT_ADDRESS_PROVIDED="INCORRECT_ADDRESS_PROVIDED",i.CHAIN_NOT_SUPPORTED="CHAIN_NOT_SUPPORTED",i.ASSET_NOT_SUPPORTED="ASSET_NOT_SUPPORTED",i.CONFIRMATION_COUNT_UNKNOWN="CONFIRMATION_COUNT_UNKNOWN",i))(v||{});var N=class extends Error{constructor(r,a,p){super(r);this.code=a;this.details=p;}};var P=class extends N{constructor(t="UNKNOWN",r){super(t,5001,r),this.name="BridgeUnavailableError";}};var B=class extends N{constructor(t="UNKNOWN",r){super(t,5002,r),this.name="BridgeInitializationError";}};var T=class extends N{constructor(t="INVALID_PARAMS",r){super(t,5003,r),this.name="InvalidParamsError";}};var ae={test:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json",production:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json"},q=async e=>{try{return (await(await fetch(ae[e])).json()).map(a=>({...a,chainId:`eip155:${a.chainId}`}))}catch(t){throw new B("CONFIG_NOT_AVAILABLE",`Error while fetching CCTP config: ${t.message}`)}},M=e=>{switch(e){case"eip155:43114":case"eip155:43113":return 1e3;default:return 2e4}};async function $(e){await e.ensureHasConfig();let t=e.config.map(r=>r.chainId);return e.config.reduce((r,a)=>(r[a.chainId]=a.tokens.map(p=>({...p,type:"erc20",destinations:t.reduce((n,o)=>(a.chainId!==o&&(n[o]||(n[o]=[]),n[o]?.push("cctp")),n),{})})),r),{})}var se="^[-a-z0-9]{3,8}$",ie="^[-_a-zA-Z0-9]{1,50}$",G=":",oe=e=>{let[t,r]=e.split(G);if(!t||!r)throw new Error("Invalid identifier provided.");if(!new RegExp(se).test(t))throw new Error("Invalid namespace provided.");if(!new RegExp(ie).test(r))throw new Error("Invalid reference provided.");return {namespace:t,reference:r}},pe=({namespace:e,reference:t})=>`${e}${G}${t}`,S={toJSON:oe,toString:pe};var le=e=>{let{reference:t}=S.toJSON(e.chainId);return {id:Number(t),name:e.chainName,nativeCurrency:{decimals:e.networkToken.decimals,symbol:e.networkToken.symbol,name:e.networkToken.name},network:e.chainName,rpcUrls:{default:{http:[e.rpcUrl]},public:{http:[e.rpcUrl]}},...e.utilityAddresses?.multicall&&{contracts:{multicall3:{address:e.utilityAddresses.multicall}}}}},I=({chain:e,provider:t})=>{let r=le(e),a=t?custom(t):http(e.rpcUrl,{batch:!0,retryCount:0});return createWalletClient({chain:r,transport:a}).extend(publicActions)};var x=[{inputs:[{internalType:"address",name:"circleTokenMessenger_",type:"address"},{internalType:"address",name:"burnToken_",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"AlreadyAdmin",type:"error"},{inputs:[],name:"AlreadyFeeCollector",type:"error"},{inputs:[],name:"AlreadySupportedBurnToken",type:"error"},{inputs:[],name:"AmountLessThanFee",type:"error"},{inputs:[],name:"BalanceNotIncreased",type:"error"},{inputs:[],name:"CannotRemoveLastAdmin",type:"error"},{inputs:[],name:"FeePercentageGreaterThanMax",type:"error"},{inputs:[],name:"InvalidAdminAddress",type:"error"},{inputs:[],name:"InvalidFeeCollector",type:"error"},{inputs:[],name:"InvalidMintRecipientAddress",type:"error"},{inputs:[],name:"InvalidTokenAddress",type:"error"},{inputs:[],name:"InvalidTokenMessengerAddress",type:"error"},{inputs:[],name:"MaxFeeLessThanMinFee",type:"error"},{inputs:[],name:"NotAdmin",type:"error"},{inputs:[],name:"NotFeeCollector",type:"error"},{inputs:[],name:"UnSupportedBurnToken",type:"error"},{inputs:[],name:"UnsupportedDomain",type:"error"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],indexed:!1,internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"FeeConfigurationUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"previousOwner",type:"address"},{indexed:!0,internalType:"address",name:"newOwner",type:"address"}],name:"OwnershipTransferred",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Paused",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"address",name:"burnToken",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"address",name:"depositor",type:"address"},{indexed:!1,internalType:"address",name:"mintRecipient",type:"address"},{indexed:!1,internalType:"uint32",name:"destinationDomain",type:"uint32"},{indexed:!1,internalType:"uint256",name:"totalFee",type:"uint256"}],name:"TransferTokens",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Unpaused",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"addAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"addFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"addSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"}],name:"calculateFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessenger",outputs:[{internalType:"contract ICircleTokenMessenger",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessengerAddress",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"collectFees",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"getFeeAmounts",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeeConfiguration",outputs:[{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeePercentage",outputs:[{internalType:"uint32",name:"",type:"uint32"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMaxFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMinFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getTxnFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isAdmin",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isFeeCollector",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"isSupportedBurnToken",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"isSupportedDomain",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"owner",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"pause",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"paused",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"removeAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"removeFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"removeSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"renounceOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"setFeeConfiguration",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"",type:"address"}],name:"supportedBurnTokens",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"newOwner",type:"address"}],name:"transferOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"},{internalType:"address",name:"mintRecipient",type:"address"},{internalType:"address",name:"burnToken",type:"address"}],name:"transferTokens",outputs:[{internalType:"uint64",name:"nonce",type:"uint64"}],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"unpause",outputs:[],stateMutability:"nonpayable",type:"function"}];var _=({sourceChain:e,targetChain:t,amount:r,asset:a},p)=>{if(e.chainId===t.chainId)throw new T("IDENTICAL_CHAINS_PROVIDED");if(r<=0n)throw new T("INCORRECT_AMOUNT_PROVIDED","Amount must be greater than zero");let n=p.find(i=>i.chainId===e.chainId);if(!n)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on source chain "${e.chainId}"`);let o=p.find(i=>i.chainId===t.chainId);if(!o)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on target chain "${t.chainId}"`);let d=n.tokens.find(i=>i.symbol===a.symbol),y=o.tokens.find(i=>i.symbol===a.symbol);if(!d||!y)throw new T("ASSET_NOT_SUPPORTED");return {sourceChainData:n,targetChainData:o,burnToken:d,mintToken:y}};async function W(e,t){await e.ensureHasConfig();let{sourceChain:r,targetChain:a,asset:p,amount:n,provider:o}=t,{sourceChainData:d,targetChainData:y,burnToken:i}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),u=await I({chain:r,provider:o}).readContract({address:d.tokenRouterAddress,abi:x,functionName:"calculateFee",args:[n,y.domain]});return {[i.address]:u}}var D=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_spender",type:"address"},{name:"_value",type:"uint256"}],name:"approve",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"totalSupply",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_from",type:"address"},{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transferFrom",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"decimals",outputs:[{name:"",type:"uint8"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"balanceOf",outputs:[{name:"balance",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[],name:"symbol",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transfer",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"},{name:"_spender",type:"address"}],name:"allowance",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{payable:!0,stateMutability:"payable",type:"fallback"},{anonymous:!1,inputs:[{indexed:!0,name:"owner",type:"address"},{indexed:!0,name:"spender",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"from",type:"address"},{indexed:!0,name:"to",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Transfer",type:"event"}];var ye=async(e,t)=>{let{sourceChain:r,targetChain:a,asset:p,amount:n,fromAddress:o,toAddress:d,sourceProvider:y,onStepChange:i,sign:s}=t,u=d??o;if(!isAddress(o)||!isAddress(u))throw new T("INCORRECT_ADDRESS_PROVIDED");let{sourceChainData:c,targetChainData:f,burnToken:l}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),m=I({chain:r,provider:y}),b=await m.readContract({address:l.address,abi:D,functionName:"allowance",args:[o,c.tokenRouterAddress]})<n,h=b?2:1;if(b)if(i?.({currentSignature:1,currentSignatureReason:"allowance-approval",requiredSignatures:h}),s){let g=encodeFunctionData({abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await s({from:o,to:l.address,data:g},k=>m.sendRawTransaction({serializedTransaction:k}));await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}else {let{request:g}=await m.simulateContract({account:o,address:l.address,abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await m.writeContract(g);await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}if(i?.({currentSignature:b?2:1,currentSignatureReason:"tokens-transfer",requiredSignatures:h}),s){let g=encodeFunctionData({abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return s({from:o,to:c.tokenRouterAddress,data:g},A=>m.sendRawTransaction({serializedTransaction:A}))}else {let{request:g}=await m.simulateContract({account:o,address:c.tokenRouterAddress,abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return m.writeContract(g)}},fe=async e=>{try{return await e.getBlockNumber()}catch{return}};async function J(e,t,r){await e.ensureHasConfig();let{minimumConfirmations:a}=e.config.find(u=>u.chainId===t.sourceChain.chainId)??{},{minimumConfirmations:p}=e.config.find(u=>u.chainId===t.targetChain.chainId)??{};if(!a||!p)throw new T("CONFIRMATION_COUNT_UNKNOWN");let n=await e.getFees({...t,provider:t.sourceProvider}),o=(t.asset.address&&n[t.asset.address])??0n,d=await ye(e,t),y=Date.now(),i=I({chain:t.targetChain,provider:t.targetProvider}),s=await fe(i);return {type:e.type,environment:r,fromAddress:t.fromAddress,toAddress:t.toAddress??t.fromAddress,amount:t.amount,amountDecimals:t.asset.decimals,symbol:t.asset.symbol,bridgeFee:o,sourceChain:t.sourceChain,sourceStartedAt:y,sourceTxHash:d,sourceConfirmationCount:0,requiredSourceConfirmationCount:a,targetChain:t.targetChain,targetConfirmationCount:0,requiredTargetConfirmationCount:p,startBlockNumber:s}}async function Z(e){if(!e.config&&(await e.updateConfig(),!e.config))throw new B("CONFIG_NOT_AVAILABLE")}var O=(e,t)=>e.gasPrice&&BigInt(e.gasPrice*t.gasUsed);var L=async e=>new Promise(t=>{setTimeout(t,e);});var U=({promise:e,delay:t,startAfter:r})=>{let a=!1,p=!1,n=0,o,d,y=u=>{o&&a&&(a=!1,o(u));},i=()=>{p=!0,d&&a&&(a=!1,d("cancelled"));};return {result:new Promise((u,c)=>{a=!0,o=u,d=c;let f=async()=>{if(!(!a||p)){try{if(await e(y),!a||p)return;await L(t);}catch(l){console.error(l.message),n+=1,await L(2**n*t);}await f();}};r?setTimeout(f,r):f();}),cancel:i}};var Q=1e3*60*60*3,Y=1024n,ee=5e3,C=(e,t,r)=>{Object.assign(e,Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0))),r({...e});},Te=async(e,t)=>{let{sourceProvider:r,targetProvider:a,updateListener:p,bridgeTransfer:n}=t,o=I({chain:n.sourceChain,provider:r}),d=e.find(c=>c.chainId===n.sourceChain.chainId),y=I({chain:n.targetChain,provider:a}),i=e.find(c=>c.chainId===n.targetChain.chainId),s={...n};if(!d||!i)throw new T("CHAIN_NOT_SUPPORTED");return U({promise:async c=>{if(s.completedAt||s.metadata?.nonce)return c(s);if(s.sourceStartedAt+Q<=Date.now())return C(s,{completedAt:Date.now(),errorCode:5004},p),c(s);let f=await o.getTransactionReceipt({hash:s.sourceTxHash});if(!s.sourceNetworkFee){let A=await o.getTransaction({hash:s.sourceTxHash}),k=O(A,f);k&&C(s,{sourceNetworkFee:k},p);}if(f.status==="reverted")return C(s,{completedAt:Date.now(),errorCode:5005},p),c(s);let l=await o.getTransactionConfirmations({hash:s.sourceTxHash}),m=l>s.sourceConfirmationCount,w=l>=s.requiredSourceConfirmationCount;if(m){let A={};A.sourceConfirmationCount=Number(l),w||(A.startBlockNumber=await y.getBlockNumber()),C(s,A,p);}if(!w)return;s.startBlockNumber||C(s,{startBlockNumber:await y.getBlockNumber()},p);let b=f.logs.find(A=>A.address.toLowerCase()===d.tokenRouterAddress.toLowerCase()?decodeEventLog({abi:x,...A}).eventName==="TransferTokens":!1);if(!b)throw new T("INVALID_PARAMS",`unable to find a TransferTokens event in source transaction "${s.sourceTxHash}"`);let g=decodeEventLog({abi:x,eventName:"TransferTokens",...b}).args.nonce;return C(s,{targetStartedAt:Date.now(),metadata:{nonce:g}},p),c(s)},delay:M(d.chainId),startAfter:ee})},ge=async(e,t)=>{let{targetProvider:r,updateListener:a,bridgeTransfer:p}=t,n={...p};if(!p.completedAt&&!p.metadata?.nonce)throw new T("INVALID_PARAMS","nonce is missing");if(!p.startBlockNumber)throw new T("INVALID_PARAMS","startBlockNumber is missing");let o=I({chain:p.targetChain,provider:r}),d=e.find(i=>i.chainId===p.targetChain.chainId);if(!d)throw new T("INVALID_PARAMS",`unknown target chain "${p.targetChain.chainId}"`);return U({promise:async i=>{if(n.completedAt)return i(n);if(!n.startBlockNumber)return C(n,{completedAt:Date.now(),errorCode:5003},a),i(n);if(n.sourceStartedAt+Q<=Date.now())return C(n,{completedAt:Date.now(),errorCode:5004},a),i(n);if(!n.targetTxHash){let l=await o.getBlockNumber(),m=n.startBlockNumber-Y,w=m>=0n?m:"earliest",b=n.startBlockNumber+Y,h=b<l?b:"latest",g=await o.getLogs({address:d.messageTransmitterAddress,event:{name:"MessageReceived",type:"event",inputs:[{indexed:!0,internalType:"address",name:"caller",type:"address"},{indexed:!1,internalType:"uint32",name:"sourceDomain",type:"uint32"},{indexed:!0,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"bytes32",name:"sender",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"messageBody",type:"bytes"}]},args:{nonce:n.metadata.nonce},fromBlock:w,toBlock:h});if(g[0]?.transactionHash)C(n,{targetTxHash:g[0].transactionHash},a);else {C(n,{startBlockNumber:l},a);return}}let s=await o.getTransactionReceipt({hash:n.targetTxHash});if(!n.targetNetworkFee){let l=await o.getTransaction({hash:n.targetTxHash}),m=O(l,s);m&&C(n,{targetNetworkFee:m},a);}if(s.status==="reverted")return C(n,{completedAt:Date.now(),errorCode:5005},a),i(n);let u=await o.getTransactionConfirmations({hash:n.targetTxHash}),c=u>n.targetConfirmationCount,f=u>=n.requiredTargetConfirmationCount;if(c&&C(n,{targetConfirmationCount:Number(u)},a),!!f)return C(n,{completedAt:Date.now()},a),i(n)},delay:M(d.chainId),startAfter:ee})};function te(e,t){let r,a=()=>{r?.();};return {result:(async()=>{await e.ensureHasConfig();let{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y}=t,{result:i,cancel:s}=await Te(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y});r=s;let u=await i,{result:c,cancel:f}=await ge(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:u});return r=f,c})(),cancel:a}}var ne=e=>({type:"cctp",config:null,updateConfig:async function(){this.config=await q(e);},ensureHasConfig:async function(){return Z(this)},getAssets:async function(){return $(this)},getFees:async function(t){return W(this,t)},transferAsset:async function(t){return J(this,t,e)},trackTransfer:function(t){return te(this,t)}});var Ae=new Map([["cctp",ne]]),re=(e,t)=>new Map([...Ae].filter(([r])=>!t?.includes(r)).map(([r,a])=>[r,a(e)])),F=(e,t,r)=>{let a=t.destinations[r]?.find(p=>e.has(p));if(!a)throw new P;return {type:a,bridge:e.get(a)}};var dn=({environment:e,disabledBridgeTypes:t})=>{let r=re(e,t),a=async()=>{await Promise.allSettled(Array.from(r).map(([,s])=>s.updateConfig()));};return {environment:e,bridges:r,init:async()=>{await a();},updateConfigs:a,getAssets:async()=>(await Promise.all(Array.from(r).map(([,u])=>u.getAssets()))).reduce((u,c)=>{for(let[f,l]of Object.entries(c)){let m=u[f];if(m)for(let w of l){let b=m.findIndex(({symbol:h})=>h===w.symbol);b===-1?m.push(w):mergeWith(m[b],w,(h,g)=>{if(isArray(h))return [...new Set(h.concat(g))]});}else u[f]=l;}return u},{}),getFees:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.getFees(s)},canTransferAsset:(s,u)=>{try{return F(r,s,u),!0}catch{return !1}},transferAsset:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.transferAsset(s)},trackTransfer:s=>{let u=r.get(s.bridgeTransfer.type);if(!u)throw new P;return u.trackTransfer(s)}}}; | ||
export { R as BridgeType, V as Environment, k as ErrorCode, h as ErrorReason, H as TokenType, E as caip2, un as createUnifiedBridgeService }; | ||
export { V as BridgeSignatureReason, E as BridgeType, K as Environment, R as ErrorCode, v as ErrorReason, H as TokenType, S as caip2, dn as createUnifiedBridgeService }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@avalabs/bridge-unified", | ||
"version": "0.0.0-feat-unified-bridge-cctp-revie-20240111095801", | ||
"main": "dist/index.js", | ||
"version": "0.0.0-fix-address-comparison-20240119104940", | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.js", | ||
"typings": "dist/index.d.ts", | ||
"type": "module", | ||
@@ -18,3 +20,3 @@ "dependencies": { | ||
"@internal/tsup-config": "0.0.1", | ||
"eslint-config-custom": "0.0.0-feat-unified-bridge-cctp-revie-20240111095801" | ||
"eslint-config-custom": "0.1.0" | ||
}, | ||
@@ -21,0 +23,0 @@ "scripts": { |
@@ -138,3 +138,3 @@ import { decodeEventLog, type Address } from 'viem'; | ||
const transferEventLog = txReceipt.logs.find((log) => { | ||
if (log.address === sourceChainData.tokenRouterAddress) { | ||
if (log.address.toLowerCase() === sourceChainData.tokenRouterAddress.toLowerCase()) { | ||
const event = decodeEventLog({ | ||
@@ -141,0 +141,0 @@ abi: TOKEN_ROUTER_ABI, |
@@ -9,2 +9,3 @@ import { encodeFunctionData, isAddress } from 'viem'; | ||
type Signer, | ||
BridgeSignatureReason, | ||
} from '../../../types'; | ||
@@ -53,2 +54,3 @@ import { getClientForChain } from '../../../utils/client'; | ||
}; | ||
const onStepChangeSpy = jest.fn(); | ||
@@ -64,2 +66,3 @@ const getTransferParams = (props?: Partial<TransferParams>) => | ||
targetProvider: targetProviderMock, | ||
onStepChange: onStepChangeSpy, | ||
...(props ?? {}), | ||
@@ -188,2 +191,14 @@ }) as TransferParams; | ||
}); | ||
expect(onStepChangeSpy).toHaveBeenCalledTimes(2); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(1, { | ||
currentSignature: 1, | ||
requiredSignatures: 2, | ||
currentSignatureReason: BridgeSignatureReason.AllowanceApproval, | ||
}); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(2, { | ||
currentSignature: 2, | ||
requiredSignatures: 2, | ||
currentSignatureReason: BridgeSignatureReason.TokensTransfer, | ||
}); | ||
}); | ||
@@ -262,2 +277,14 @@ | ||
}); | ||
expect(onStepChangeSpy).toHaveBeenCalledTimes(2); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(1, { | ||
currentSignature: 1, | ||
requiredSignatures: 2, | ||
currentSignatureReason: BridgeSignatureReason.AllowanceApproval, | ||
}); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(2, { | ||
currentSignature: 2, | ||
requiredSignatures: 2, | ||
currentSignatureReason: BridgeSignatureReason.TokensTransfer, | ||
}); | ||
}); | ||
@@ -335,2 +362,9 @@ }); | ||
}); | ||
expect(onStepChangeSpy).toHaveBeenCalledTimes(1); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(1, { | ||
currentSignature: 1, | ||
requiredSignatures: 1, | ||
currentSignatureReason: BridgeSignatureReason.TokensTransfer, | ||
}); | ||
}); | ||
@@ -392,4 +426,11 @@ | ||
expect(sourceClientMock.writeContract).toHaveBeenCalledWith(bridgeTxRequest); | ||
expect(onStepChangeSpy).toHaveBeenCalledTimes(1); | ||
expect(onStepChangeSpy).toHaveBeenNthCalledWith(1, { | ||
currentSignature: 1, | ||
requiredSignatures: 1, | ||
currentSignatureReason: BridgeSignatureReason.TokensTransfer, | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -9,2 +9,3 @@ import { encodeFunctionData, isAddress, type PublicClient } from 'viem'; | ||
type BridgeTransfer, | ||
BridgeSignatureReason, | ||
} from '../../../types'; | ||
@@ -26,2 +27,3 @@ import { getClientForChain } from '../../../utils/client'; | ||
sourceProvider, | ||
onStepChange, | ||
sign, | ||
@@ -48,3 +50,12 @@ } = params; | ||
if (allowance < amount) { | ||
const isAllowanceApprovalRequired = allowance < amount; | ||
const requiredSignatures = isAllowanceApprovalRequired ? 2 : 1; // if approval is required, we'll need 2 signatures | ||
if (isAllowanceApprovalRequired) { | ||
onStepChange?.({ | ||
currentSignature: 1, | ||
currentSignatureReason: BridgeSignatureReason.AllowanceApproval, | ||
requiredSignatures, | ||
}); | ||
if (sign) { | ||
@@ -81,2 +92,8 @@ const data = encodeFunctionData({ | ||
onStepChange?.({ | ||
currentSignature: isAllowanceApprovalRequired ? 2 : 1, | ||
currentSignatureReason: BridgeSignatureReason.TokensTransfer, | ||
requiredSignatures, | ||
}); | ||
if (sign) { | ||
@@ -83,0 +100,0 @@ const data = encodeFunctionData({ |
@@ -21,2 +21,13 @@ import type { AssetFeeMap, BridgeAsset, ChainAssetMap } from './asset'; | ||
export enum BridgeSignatureReason { | ||
AllowanceApproval = 'allowance-approval', | ||
TokensTransfer = 'tokens-transfer', | ||
} | ||
export type BridgeStepDetails = { | ||
currentSignature: number; | ||
requiredSignatures: number; | ||
currentSignatureReason: BridgeSignatureReason; | ||
}; | ||
export type TransferParams = { | ||
@@ -31,2 +42,3 @@ asset: BridgeAsset; | ||
targetProvider?: Provider; | ||
onStepChange?: (stepDetails: BridgeStepDetails) => void; | ||
sign?: Signer; | ||
@@ -33,0 +45,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
387229
4820