@avalabs/fusion-sdk 0.11.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/transfer-service/markr/_handlers/transfer-asset.cjs +1 -1
- package/dist/transfer-service/markr/_handlers/transfer-asset.cjs.map +1 -1
- package/dist/transfer-service/markr/_handlers/transfer-asset.js +1 -1
- package/dist/transfer-service/markr/_handlers/transfer-asset.js.map +1 -1
- package/dist/transfer-service/markr/constants.cjs +1 -1
- package/dist/transfer-service/markr/constants.cjs.map +1 -1
- package/dist/transfer-service/markr/constants.js +1 -1
- package/dist/transfer-service/markr/constants.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../constants.cjs`),t=require(`../../../errors.cjs`),n=require(`../../../utils/caip.cjs`),r=require(`../../../_utils/chain.cjs`),i=require(`../../_utils.cjs`),a=require(`../_api.cjs`),o=require(`../../../utils/sol-address.cjs`),s=require(`../_utils.cjs`),c=require(`../_type-guards.cjs`),l=require(`../_solana-utils.cjs`),u=require(`./estimate-native-fee.cjs`),d=require(`../constants.cjs`);let f=require(`viem`);function p({apiOptions:n,appId:i,environment:a,evmSigner:o,solanaSigner:s}){return async({quote:c,gasSettings:l,fallbackToDefaultOnBatchFailure:u,onStepChange:d})=>{if(c.serviceType!==e.ServiceType.MARKR)throw new t.SdkError(t.ErrorReason.INCORRECT_PROVIDER_PROVIDED,t.ErrorCode.INVALID_PARAMS);let f=Math.floor(Date.now()/1e3);if(c.expiresAt<=f)throw new t.SdkError(t.ErrorReason.QUOTE_EXPIRED,t.ErrorCode.INVALID_PARAMS);let p=c.sourceChain.chainId;if(r.isSolanaNamespace(p))return h({apiOptions:n,appId:i,environment:a,solanaSigner:s,quote:c,onStepChange:d});if(r.isEvmNamespace(p))return m({apiOptions:n,appId:i,environment:a,evmSigner:o,quote:c,gasSettings:l,fallbackToDefaultOnBatchFailure:u,onStepChange:d});throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Unsupported source chain namespace: ${p}`})}}async function m({apiOptions:r,appId:o,environment:l,evmSigner:d,quote:p,gasSettings:m,fallbackToDefaultOnBatchFailure:h,onStepChange:_}){let v=p.fromAddress;if(!(0,f.isAddress)(v))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`fromAddress is not a valid EVM address.`});let y=s.calculateMarkrMinimumAmountOut({amountOut:p.amountOut,assetOut:p.assetOut,slippageBps:p.slippageBps}),b=i.getEvmClientForChain({chain:p.sourceChain}),x=s.assetToAddressString(p.assetIn,p.sourceChain.chainId),S=s.assetToAddressString(p.assetOut,p.targetChain.chainId);if(!(0,f.isAddress)(x))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`assetIn address is not a valid EVM address.`});let C=x,w=s.isTokenAddressNative(C),T=p.sourceChain.chainId.toLowerCase()!==p.targetChain.chainId.toLowerCase(),{address:E}=await a.markrGetSpenderAddress(r,{chainId:n.caip2ToEip155ChainId(p.sourceChain.chainId),crossChainSwap:T,quoteId:p.id});if(!w&&!E)throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Missing Markr spender address for source chain ${p.sourceChain.chainId}.`});let D=!1,O;if(!w&&E&&await b.readContract({address:C,abi:f.erc20Abi,functionName:`allowance`,args:[v,E]})<p.amountIn){D=!0;let e=(0,f.encodeFunctionData)({abi:f.erc20Abi,functionName:`approve`,args:[E,p.amountIn]}),r;try{r=i.applyFeeUnitsBpsMargin(await b.estimateGas({account:v,to:C,data:e,value:0n}),m?.estimateGasMarginBps)}catch(e){throw new t.SdkError(`Error during gas estimation`,t.ErrorCode.VIEM_ERROR,{cause:e,details:`Failed to estimate gas for ERC20 approval transaction.`})}O={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:e,from:v,gas:r,to:C,value:0n,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}}}let k=g({approvalRequest:O,requiresApprovalSignature:D,signBatch:d.signBatch,sourceChainId:p.sourceChain.chainId,targetChainId:p.targetChain.chainId}),A=await a.markrSwap(r,{amountIn:p.amountIn.toString(),appId:o,minAmountOut:y.toString(),tokenIn:x,tokenOut:S,uuid:p.id});if(!c.isEvmSwapResponse(A))throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.`});let j=(t,n=Date.now())=>{let r=p.sourceChain.chainId===p.targetChain.chainId;return{amountIn:p.amountIn,amountOut:p.amountOut,environment:l,fees:p.fees,fromAddress:p.fromAddress,id:p.id,partnerFeeBps:p.partnerFeeBps,sourceAsset:p.assetIn,sourceChain:p.sourceChain,status:`source-pending`,targetAsset:p.assetOut,targetChain:p.targetChain,toAddress:p.toAddress,type:e.ServiceType.MARKR,source:{confirmationCount:0,requiredConfirmationCount:r?1:2,startedAtMs:n,txHash:t}}};if(k&&O){let r={currentSignature:1,currentSignatureReason:e.TransferSignatureReason.TokensTransfer,quote:p,requiredSignatures:1},i=d.signBatch;if(!i)throw new t.SdkError(`One-click batch signer is not available.`,t.ErrorCode.SIGNING_FAILED);let a={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:A.data,from:v,gas:void 0,to:A.to,value:A.value,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}};_?.(r);try{let e=(await i([O,a],async e=>b.sendRawTransaction({serializedTransaction:e}),r)).at(-1);if(!e)throw new t.SdkError(`One-click batch signing returned no transaction hashes.`,t.ErrorCode.SIGNING_FAILED);return j(e)}catch(e){if(!h)throw e}}if(D&&O){let n={currentSignature:1,currentSignatureReason:e.TransferSignatureReason.AllowanceApproval,quote:p,requiredSignatures:2};_?.(n);let r=await d.sign(O,async e=>b.sendRawTransaction({serializedTransaction:e}),n);if((await b.waitForTransactionReceipt({hash:r})).status===`reverted`)return i.makeFailedTransferFromQuote(p,{environment:l,errorCode:t.ErrorCode.TRANSACTION_REVERTED,errorReason:`ERC20 approval transaction was reverted`})}let M=await u._estimateGasFromSwapResponse({crossChain:T,fromAddress:v,feeUnitsMarginBps:m?.estimateGasMarginBps,sourceClient:b,swap:A}),N={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:A.data,from:v,gas:M,to:A.to,value:A.value,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}},P={currentSignature:D?2:1,currentSignatureReason:e.TransferSignatureReason.TokensTransfer,quote:p,requiredSignatures:D?2:1};_?.(P);let F=Date.now();return j(await d.sign(N,async e=>b.sendRawTransaction({serializedTransaction:e}),P),F)}async function h({apiOptions:n,appId:r,environment:u,solanaSigner:f,quote:p,onStepChange:m}){if(!f)throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`solanaSigner is required for Solana transfers but was not provided.`});if(!o.isSolAddress(p.fromAddress))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`fromAddress is not a valid Solana address.`});let h=s.calculateMarkrMinimumAmountOut({amountOut:p.amountOut,assetOut:p.assetOut,slippageBps:p.slippageBps}),g=s.assetToAddressString(p.assetIn,p.sourceChain.chainId),_=s.assetToAddressString(p.assetOut,p.targetChain.chainId),v=await a.markrSwap(n,{amountIn:p.amountIn.toString(),appId:r,minAmountOut:h.toString(),tokenIn:g,tokenOut:_,userPublicKey:p.fromAddress,uuid:p.id});if(!c.isSolanaSwapResponse(v))throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.`});let y=await l.refreshSolanaSwapTransactionBlockhash(v.swapTransaction,i.getSolanaRpcForChain({chain:p.sourceChain}))
|
|
1
|
+
require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../constants.cjs`),t=require(`../../../errors.cjs`),n=require(`../../../utils/caip.cjs`),r=require(`../../../_utils/chain.cjs`),i=require(`../../_utils.cjs`),a=require(`../_api.cjs`),o=require(`../../../utils/sol-address.cjs`),s=require(`../_utils.cjs`),c=require(`../_type-guards.cjs`),l=require(`../_solana-utils.cjs`),u=require(`./estimate-native-fee.cjs`),d=require(`../constants.cjs`);let f=require(`viem`);function p({apiOptions:n,appId:i,environment:a,evmSigner:o,solanaSigner:s}){return async({quote:c,gasSettings:l,fallbackToDefaultOnBatchFailure:u,onStepChange:d})=>{if(c.serviceType!==e.ServiceType.MARKR)throw new t.SdkError(t.ErrorReason.INCORRECT_PROVIDER_PROVIDED,t.ErrorCode.INVALID_PARAMS);let f=Math.floor(Date.now()/1e3);if(c.expiresAt<=f)throw new t.SdkError(t.ErrorReason.QUOTE_EXPIRED,t.ErrorCode.INVALID_PARAMS);let p=c.sourceChain.chainId;if(r.isSolanaNamespace(p))return h({apiOptions:n,appId:i,environment:a,solanaSigner:s,quote:c,onStepChange:d});if(r.isEvmNamespace(p))return m({apiOptions:n,appId:i,environment:a,evmSigner:o,quote:c,gasSettings:l,fallbackToDefaultOnBatchFailure:u,onStepChange:d});throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Unsupported source chain namespace: ${p}`})}}async function m({apiOptions:r,appId:o,environment:l,evmSigner:d,quote:p,gasSettings:m,fallbackToDefaultOnBatchFailure:h,onStepChange:_}){let v=p.fromAddress;if(!(0,f.isAddress)(v))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`fromAddress is not a valid EVM address.`});let y=s.calculateMarkrMinimumAmountOut({amountOut:p.amountOut,assetOut:p.assetOut,slippageBps:p.slippageBps}),b=i.getEvmClientForChain({chain:p.sourceChain}),x=s.assetToAddressString(p.assetIn,p.sourceChain.chainId),S=s.assetToAddressString(p.assetOut,p.targetChain.chainId);if(!(0,f.isAddress)(x))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`assetIn address is not a valid EVM address.`});let C=x,w=s.isTokenAddressNative(C),T=p.sourceChain.chainId.toLowerCase()!==p.targetChain.chainId.toLowerCase(),{address:E}=await a.markrGetSpenderAddress(r,{chainId:n.caip2ToEip155ChainId(p.sourceChain.chainId),crossChainSwap:T,quoteId:p.id});if(!w&&!E)throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Missing Markr spender address for source chain ${p.sourceChain.chainId}.`});let D=!1,O;if(!w&&E&&await b.readContract({address:C,abi:f.erc20Abi,functionName:`allowance`,args:[v,E]})<p.amountIn){D=!0;let e=(0,f.encodeFunctionData)({abi:f.erc20Abi,functionName:`approve`,args:[E,p.amountIn]}),r;try{r=i.applyFeeUnitsBpsMargin(await b.estimateGas({account:v,to:C,data:e,value:0n}),m?.estimateGasMarginBps)}catch(e){throw new t.SdkError(`Error during gas estimation`,t.ErrorCode.VIEM_ERROR,{cause:e,details:`Failed to estimate gas for ERC20 approval transaction.`})}O={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:e,from:v,gas:r,to:C,value:0n,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}}}let k=g({approvalRequest:O,requiresApprovalSignature:D,signBatch:d.signBatch,sourceChainId:p.sourceChain.chainId,targetChainId:p.targetChain.chainId}),A=await a.markrSwap(r,{amountIn:p.amountIn.toString(),appId:o,minAmountOut:y.toString(),tokenIn:x,tokenOut:S,uuid:p.id});if(!c.isEvmSwapResponse(A))throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.`});let j=(t,n=Date.now())=>{let r=p.sourceChain.chainId===p.targetChain.chainId;return{amountIn:p.amountIn,amountOut:p.amountOut,environment:l,fees:p.fees,fromAddress:p.fromAddress,id:p.id,partnerFeeBps:p.partnerFeeBps,sourceAsset:p.assetIn,sourceChain:p.sourceChain,status:`source-pending`,targetAsset:p.assetOut,targetChain:p.targetChain,toAddress:p.toAddress,type:e.ServiceType.MARKR,source:{confirmationCount:0,requiredConfirmationCount:r?1:2,startedAtMs:n,txHash:t}}};if(k&&O){let r={currentSignature:1,currentSignatureReason:e.TransferSignatureReason.TokensTransfer,quote:p,requiredSignatures:1},i=d.signBatch;if(!i)throw new t.SdkError(`One-click batch signer is not available.`,t.ErrorCode.SIGNING_FAILED);let a={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:A.data,from:v,gas:void 0,to:A.to,value:A.value,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}};_?.(r);try{let e=(await i([O,a],async e=>b.sendRawTransaction({serializedTransaction:e}),r)).at(-1);if(!e)throw new t.SdkError(`One-click batch signing returned no transaction hashes.`,t.ErrorCode.SIGNING_FAILED);return j(e)}catch(e){if(!h)throw e}}if(D&&O){let n={currentSignature:1,currentSignatureReason:e.TransferSignatureReason.AllowanceApproval,quote:p,requiredSignatures:2};_?.(n);let r=await d.sign(O,async e=>b.sendRawTransaction({serializedTransaction:e}),n);if((await b.waitForTransactionReceipt({hash:r})).status===`reverted`)return i.makeFailedTransferFromQuote(p,{environment:l,errorCode:t.ErrorCode.TRANSACTION_REVERTED,errorReason:`ERC20 approval transaction was reverted`})}let M=await u._estimateGasFromSwapResponse({crossChain:T,fromAddress:v,feeUnitsMarginBps:m?.estimateGasMarginBps,sourceClient:b,swap:A}),N={chainId:n.caip2ToEip155HexChainId(p.sourceChain.chainId),data:A.data,from:v,gas:M,to:A.to,value:A.value,...m?.maxFeePerGas===void 0?null:{maxFeePerGas:m.maxFeePerGas,maxPriorityFeePerGas:m.maxPriorityFeePerGas}},P={currentSignature:D?2:1,currentSignatureReason:e.TransferSignatureReason.TokensTransfer,quote:p,requiredSignatures:D?2:1};_?.(P);let F=Date.now();return j(await d.sign(N,async e=>b.sendRawTransaction({serializedTransaction:e}),P),F)}async function h({apiOptions:n,appId:r,environment:u,solanaSigner:f,quote:p,onStepChange:m}){if(!f)throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`solanaSigner is required for Solana transfers but was not provided.`});if(!o.isSolAddress(p.fromAddress))throw new t.SdkError(t.ErrorReason.INVALID_PARAMS,t.ErrorCode.INVALID_PARAMS,{details:`fromAddress is not a valid Solana address.`});let h=s.calculateMarkrMinimumAmountOut({amountOut:p.amountOut,assetOut:p.assetOut,slippageBps:p.slippageBps}),g=s.assetToAddressString(p.assetIn,p.sourceChain.chainId),_=s.assetToAddressString(p.assetOut,p.targetChain.chainId),v=await a.markrSwap(n,{amountIn:p.amountIn.toString(),appId:r,minAmountOut:h.toString(),tokenIn:g,tokenOut:_,userPublicKey:p.fromAddress,uuid:p.id});if(!c.isSolanaSwapResponse(v))throw new t.SdkError(t.ErrorReason.CHAIN_NOT_SUPPORTED,t.ErrorCode.INVALID_PARAMS,{details:`Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.`});console.debug(`[Fusion SDK] Original swap transaction (base64):`,v.swapTransaction);let y=await l.refreshSolanaSwapTransactionBlockhash(v.swapTransaction,i.getSolanaRpcForChain({chain:p.sourceChain}));console.debug(`[Fusion SDK] Refreshed swap transaction with new blockhash (base64):`,y);let b={currentSignature:1,currentSignatureReason:e.TransferSignatureReason.TokensTransfer,quote:p,requiredSignatures:1};m?.(b);let x=Date.now(),S=await f.signAndSend({account:p.fromAddress,serializedTx:y},b),C=p.sourceChain.chainId.toLowerCase()!==p.targetChain.chainId.toLowerCase();return{amountIn:p.amountIn,amountOut:p.amountOut,environment:u,fees:p.fees,fromAddress:p.fromAddress,id:p.id,partnerFeeBps:p.partnerFeeBps,sourceAsset:p.assetIn,sourceChain:p.sourceChain,status:`source-pending`,targetAsset:p.assetOut,targetChain:p.targetChain,toAddress:p.toAddress,type:e.ServiceType.MARKR,source:{confirmationCount:0,requiredConfirmationCount:C?2:d.SOLANA_REQUIRED_CONFIRMATIONS,startedAtMs:x,txHash:S}}}function g({approvalRequest:e,requiresApprovalSignature:t,signBatch:n,sourceChainId:i,targetChainId:a}){return r.isEvmNamespace(i)&&r.isEvmNamespace(a)&&i===a&&t&&e!==void 0&&typeof n==`function`}exports.transferAssetFactory=p;
|
|
2
2
|
//# sourceMappingURL=transfer-asset.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer-asset.cjs","names":["ServiceType","SdkError","ErrorReason","ErrorCode","isSolanaNamespace","isEvmNamespace","calculateMarkrMinimumAmountOut","getEvmClientForChain","assetToAddressString","isTokenAddressNative","markrGetSpenderAddress","caip2ToEip155ChainId","erc20Abi","applyFeeUnitsBpsMargin","caip2ToEip155HexChainId","markrSwap","isEvmSwapResponse","TransferSignatureReason","makeFailedTransferFromQuote","_estimateGasFromSwapResponse","isSolAddress","isSolanaSwapResponse","refreshSolanaSwapTransactionBlockhash","getSolanaRpcForChain","SOLANA_REQUIRED_CONFIRMATIONS"],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { encodeFunctionData, erc20Abi, isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ServiceType, TransferSignatureReason } from '../../../constants';\nimport type { Environment } from '../../../constants';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\nimport type { EvmSigner, EvmTransactionRequest, SolanaSigner } from '../../../types/signer';\nimport type { Transfer, TransferStepDetails } from '../../../types/transfer';\nimport { caip2ToEip155ChainId, caip2ToEip155HexChainId } from '../../../utils/caip';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport {\n applyFeeUnitsBpsMargin,\n getEvmClientForChain,\n getSolanaRpcForChain,\n makeFailedTransferFromQuote,\n} from '../../_utils';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport { assetToAddressString, calculateMarkrMinimumAmountOut, isTokenAddressNative } from '../_utils';\nimport { isEvmSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../_solana-utils';\n\nexport interface TransferAssetFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n solanaSigner?: SolanaSigner;\n}\n\nexport function transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n}: TransferAssetFactoryConfig): TransferService['transferAsset'] {\n return async ({ quote, gasSettings, fallbackToDefaultOnBatchFailure, onStepChange }) => {\n if (quote.serviceType !== ServiceType.MARKR) {\n throw new SdkError(ErrorReason.INCORRECT_PROVIDER_PROVIDED, ErrorCode.INVALID_PARAMS);\n }\n\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n throw new SdkError(ErrorReason.QUOTE_EXPIRED, ErrorCode.INVALID_PARAMS);\n }\n\n const sourceChainId = quote.sourceChain.chainId;\n\n if (isSolanaNamespace(sourceChainId)) {\n return _executeSvmTransfer({ apiOptions, appId, environment, solanaSigner, quote, onStepChange });\n }\n\n if (isEvmNamespace(sourceChainId)) {\n return _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n });\n }\n\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Unsupported source chain namespace: ${sourceChainId}`,\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// EVM transfer path\n// ---------------------------------------------------------------------------\n\ninterface EvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n gasSettings?: Parameters<TransferService['transferAsset']>[0]['gasSettings'];\n fallbackToDefaultOnBatchFailure?: Parameters<TransferService['transferAsset']>[0]['fallbackToDefaultOnBatchFailure'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n}: EvmTransferParams): Promise<Transfer> {\n const fromAddress = quote.fromAddress;\n\n if (!isAddress(fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid EVM address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const sourceClient = getEvmClientForChain({ chain: quote.sourceChain });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n if (!isAddress(tokenInAddressString)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'assetIn address is not a valid EVM address.',\n });\n }\n\n const tokenInAddress = tokenInAddressString;\n const isTokenInNative = isTokenAddressNative(tokenInAddress);\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n const { address: spenderAddress } = await markrGetSpenderAddress(apiOptions, {\n chainId: caip2ToEip155ChainId(quote.sourceChain.chainId),\n crossChainSwap: isCrossChainSwap,\n quoteId: quote.id,\n });\n\n if (!isTokenInNative && !spenderAddress) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Missing Markr spender address for source chain ${quote.sourceChain.chainId}.`,\n });\n }\n\n let requiresApprovalSignature = false;\n let approvalRequest: EvmTransactionRequest | undefined;\n\n if (!isTokenInNative && spenderAddress) {\n const allowance = await sourceClient.readContract({\n address: tokenInAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [fromAddress, spenderAddress],\n });\n\n if (allowance < quote.amountIn) {\n requiresApprovalSignature = true;\n\n const approvalData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, quote.amountIn],\n });\n\n let approvalGasWithMargin: bigint | undefined;\n\n try {\n const approvalGasEstimate = await sourceClient.estimateGas({\n account: fromAddress,\n to: tokenInAddress,\n data: approvalData,\n value: 0n,\n });\n\n approvalGasWithMargin = applyFeeUnitsBpsMargin(approvalGasEstimate, gasSettings?.estimateGasMarginBps);\n } catch (err) {\n throw new SdkError('Error during gas estimation', ErrorCode.VIEM_ERROR, {\n cause: err,\n details: 'Failed to estimate gas for ERC20 approval transaction.',\n });\n }\n\n approvalRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: approvalData,\n from: fromAddress,\n gas: approvalGasWithMargin,\n to: tokenInAddress,\n value: 0n,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n }\n }\n\n const maybeOneClickBatch = isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch: evmSigner.signBatch,\n sourceChainId: quote.sourceChain.chainId,\n targetChainId: quote.targetChain.chainId,\n });\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n uuid: quote.id,\n });\n\n if (!isEvmSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.',\n });\n }\n\n const makePendingTransfer = (txHash: `0x${string}`, startedAtMs: number = Date.now()): Transfer => {\n const isSameChainTransfer = quote.sourceChain.chainId === quote.targetChain.chainId;\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isSameChainTransfer ? 1 : 2,\n startedAtMs,\n txHash,\n },\n };\n };\n\n if (maybeOneClickBatch && approvalRequest) {\n const batchStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n const signBatch = evmSigner.signBatch;\n\n if (!signBatch) {\n throw new SdkError('One-click batch signer is not available.', ErrorCode.SIGNING_FAILED);\n }\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n // Gas is purposely left undefined here.\n // We can't estimate the gas because we aren't executing the\n // approval tx. It's up to the wallet to correctly handle gas estimation.\n gas: undefined,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n onStepChange?.(batchStep);\n\n try {\n const txHashes = await signBatch(\n [approvalRequest, swapRequest],\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n batchStep,\n );\n\n const swapTxHash = txHashes.at(-1);\n\n if (!swapTxHash) {\n throw new SdkError('One-click batch signing returned no transaction hashes.', ErrorCode.SIGNING_FAILED);\n }\n\n return makePendingTransfer(swapTxHash);\n } catch (error) {\n if (!fallbackToDefaultOnBatchFailure) {\n throw error;\n }\n }\n }\n\n if (requiresApprovalSignature && approvalRequest) {\n const approvalStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n };\n\n onStepChange?.(approvalStep);\n\n const approvalTxHash = await evmSigner.sign(\n approvalRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n approvalStep,\n );\n\n const approvalReceipt = await sourceClient.waitForTransactionReceipt({ hash: approvalTxHash });\n\n if (approvalReceipt.status === 'reverted') {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n }\n\n const swapGasWithMargin = await _estimateGasFromSwapResponse({\n crossChain: isCrossChainSwap,\n fromAddress,\n feeUnitsMarginBps: gasSettings?.estimateGasMarginBps,\n sourceClient,\n swap,\n });\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n gas: swapGasWithMargin,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n const step: TransferStepDetails = {\n currentSignature: requiresApprovalSignature ? 2 : 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: requiresApprovalSignature ? 2 : 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await evmSigner.sign(\n swapRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n step,\n );\n\n return makePendingTransfer(txHash, startedAtMs);\n}\n\n// ---------------------------------------------------------------------------\n// SVM (Solana) transfer path\n// ---------------------------------------------------------------------------\n\ninterface SvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n solanaSigner?: SolanaSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeSvmTransfer({\n apiOptions,\n appId,\n environment,\n solanaSigner,\n quote,\n onStepChange,\n}: SvmTransferParams): Promise<Transfer> {\n if (!solanaSigner) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'solanaSigner is required for Solana transfers but was not provided.',\n });\n }\n\n if (!isSolAddress(quote.fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid Solana address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n userPublicKey: quote.fromAddress,\n uuid: quote.id,\n });\n\n if (!isSolanaSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.',\n });\n }\n\n const swapTransactionBase64 = await refreshSolanaSwapTransactionBlockhash(\n swap.swapTransaction,\n getSolanaRpcForChain({ chain: quote.sourceChain }),\n );\n\n const step: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await solanaSigner.signAndSend(\n {\n account: quote.fromAddress,\n serializedTx: swapTransactionBase64,\n },\n step,\n );\n\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isCrossChainSwap ? 2 : SOLANA_REQUIRED_CONFIRMATIONS,\n startedAtMs,\n txHash,\n },\n };\n}\n\n/**\n * Determines whether one-click swap eligibility criteria is met.\n *\n * Only same-chain EVM swaps are currently eligible.\n */\nfunction isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch,\n sourceChainId,\n targetChainId,\n}: {\n approvalRequest?: EvmTransactionRequest;\n requiresApprovalSignature: boolean;\n signBatch?: EvmSigner['signBatch'];\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n}): boolean {\n return (\n isEvmNamespace(sourceChainId) &&\n isEvmNamespace(targetChainId) &&\n sourceChainId === targetChainId &&\n requiresApprovalSignature &&\n approvalRequest !== undefined &&\n typeof signBatch === 'function'\n );\n}\n"],"mappings":"seAgCA,SAAgB,EAAqB,CACnC,aACA,QACA,cACA,YACA,gBAC+D,CAC/D,OAAO,MAAO,CAAE,QAAO,cAAa,kCAAiC,kBAAmB,CACtF,GAAI,EAAM,cAAgBA,EAAAA,YAAY,MACpC,MAAM,IAAIC,EAAAA,SAASC,EAAAA,YAAY,4BAA6BC,EAAAA,UAAU,eAAe,CAGvF,IAAM,EAAM,KAAK,MAAM,KAAK,KAAK,CAAG,IAAM,CAE1C,GAAI,EAAM,WAAa,EACrB,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,cAAeC,EAAAA,UAAU,eAAe,CAGzE,IAAM,EAAgB,EAAM,YAAY,QAExC,GAAIC,EAAAA,kBAAkB,EAAc,CAClC,OAAO,EAAoB,CAAE,aAAY,QAAO,cAAa,eAAc,QAAO,eAAc,CAAC,CAGnG,GAAIC,EAAAA,eAAe,EAAc,CAC/B,OAAO,EAAoB,CACzB,aACA,QACA,cACA,YACA,QACA,cACA,kCACA,eACD,CAAC,CAGJ,MAAM,IAAIJ,EAAAA,SAASC,EAAAA,YAAY,oBAAqBC,EAAAA,UAAU,eAAgB,CAC5E,QAAS,uCAAuC,IACjD,CAAC,EAmBN,eAAe,EAAoB,CACjC,aACA,QACA,cACA,YACA,QACA,cACA,kCACA,gBACuC,CACvC,IAAM,EAAc,EAAM,YAE1B,GAAI,EAAA,EAAA,EAAA,WAAW,EAAY,CACzB,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,eAAgBC,EAAAA,UAAU,eAAgB,CACvE,QAAS,0CACV,CAAC,CAGJ,IAAM,EAAeG,EAAAA,+BAA+B,CAClD,UAAW,EAAM,UACjB,SAAU,EAAM,SAChB,YAAa,EAAM,YACpB,CAAC,CAEI,EAAeC,EAAAA,qBAAqB,CAAE,MAAO,EAAM,YAAa,CAAC,CAEjE,EAAuBC,EAAAA,qBAAqB,EAAM,QAAS,EAAM,YAAY,QAAQ,CACrF,EAAwBA,EAAAA,qBAAqB,EAAM,SAAU,EAAM,YAAY,QAAQ,CAE7F,GAAI,EAAA,EAAA,EAAA,WAAW,EAAqB,CAClC,MAAM,IAAIP,EAAAA,SAASC,EAAAA,YAAY,eAAgBC,EAAAA,UAAU,eAAgB,CACvE,QAAS,8CACV,CAAC,CAGJ,IAAM,EAAiB,EACjB,EAAkBM,EAAAA,qBAAqB,EAAe,CACtD,EAAmB,EAAM,YAAY,QAAQ,aAAa,GAAK,EAAM,YAAY,QAAQ,aAAa,CAEtG,CAAE,QAAS,GAAmB,MAAMC,EAAAA,uBAAuB,EAAY,CAC3E,QAASC,EAAAA,qBAAqB,EAAM,YAAY,QAAQ,CACxD,eAAgB,EAChB,QAAS,EAAM,GAChB,CAAC,CAEF,GAAI,CAAC,GAAmB,CAAC,EACvB,MAAM,IAAIV,EAAAA,SAASC,EAAAA,YAAY,oBAAqBC,EAAAA,UAAU,eAAgB,CAC5E,QAAS,kDAAkD,EAAM,YAAY,QAAQ,GACtF,CAAC,CAGJ,IAAI,EAA4B,GAC5B,EAEJ,GAAI,CAAC,GAAmB,GACJ,MAAM,EAAa,aAAa,CAChD,QAAS,EACT,IAAKS,EAAAA,SACL,aAAc,YACd,KAAM,CAAC,EAAa,EAAe,CACpC,CAAC,CAEc,EAAM,SAAU,CAC9B,EAA4B,GAE5B,IAAM,GAAA,EAAA,EAAA,oBAAkC,CACtC,IAAKA,EAAAA,SACL,aAAc,UACd,KAAM,CAAC,EAAgB,EAAM,SAAS,CACvC,CAAC,CAEE,EAEJ,GAAI,CAQF,EAAwBC,EAAAA,uBAPI,MAAM,EAAa,YAAY,CACzD,QAAS,EACT,GAAI,EACJ,KAAM,EACN,MAAO,GACR,CAAC,CAEkE,GAAa,qBAAqB,OAC/F,EAAK,CACZ,MAAM,IAAIZ,EAAAA,SAAS,8BAA+BE,EAAAA,UAAU,WAAY,CACtE,MAAO,EACP,QAAS,yDACV,CAAC,CAGJ,EAAkB,CAChB,QAASW,EAAAA,wBAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EACN,KAAM,EACN,IAAK,EACL,GAAI,EACJ,MAAO,GACP,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAIL,IAAM,EAAqB,EAAwB,CACjD,kBACA,4BACA,UAAW,EAAU,UACrB,cAAe,EAAM,YAAY,QACjC,cAAe,EAAM,YAAY,QAClC,CAAC,CAEI,EAAO,MAAMC,EAAAA,UAAU,EAAY,CACvC,SAAU,EAAM,SAAS,UAAU,CACnC,QACA,aAAc,EAAa,UAAU,CACrC,QAAS,EACT,SAAU,EACV,KAAM,EAAM,GACb,CAAC,CAEF,GAAI,CAACC,EAAAA,kBAAkB,EAAK,CAC1B,MAAM,IAAIf,EAAAA,SAASC,EAAAA,YAAY,oBAAqBC,EAAAA,UAAU,eAAgB,CAC5E,QAAS,qGACV,CAAC,CAGJ,IAAM,GAAuB,EAAuB,EAAsB,KAAK,KAAK,GAAe,CACjG,IAAM,EAAsB,EAAM,YAAY,UAAY,EAAM,YAAY,QAE5E,MAAO,CACL,SAAU,EAAM,SAChB,UAAW,EAAM,UACjB,cACA,KAAM,EAAM,KACZ,YAAa,EAAM,YACnB,GAAI,EAAM,GACV,cAAe,EAAM,cACrB,YAAa,EAAM,QACnB,YAAa,EAAM,YACnB,OAAQ,iBACR,YAAa,EAAM,SACnB,YAAa,EAAM,YACnB,UAAW,EAAM,UACjB,KAAMH,EAAAA,YAAY,MAClB,OAAQ,CACN,kBAAmB,EACnB,0BAA2B,EAAsB,EAAI,EACrD,cACA,SACD,CACF,EAGH,GAAI,GAAsB,EAAiB,CACzC,IAAM,EAAiC,CACrC,iBAAkB,EAClB,uBAAwBiB,EAAAA,wBAAwB,eAChD,QACA,mBAAoB,EACrB,CAEK,EAAY,EAAU,UAE5B,GAAI,CAAC,EACH,MAAM,IAAIhB,EAAAA,SAAS,2CAA4CE,EAAAA,UAAU,eAAe,CAG1F,IAAM,EAAqC,CACzC,QAASW,EAAAA,wBAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EAAK,KACX,KAAM,EAIN,IAAK,IAAA,GACL,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAED,IAAe,EAAU,CAEzB,GAAI,CAOF,IAAM,GANW,MAAM,EACrB,CAAC,EAAiB,EAAY,CAC9B,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,EAE2B,GAAG,GAAG,CAElC,GAAI,CAAC,EACH,MAAM,IAAIb,EAAAA,SAAS,0DAA2DE,EAAAA,UAAU,eAAe,CAGzG,OAAO,EAAoB,EAAW,OAC/B,EAAO,CACd,GAAI,CAAC,EACH,MAAM,GAKZ,GAAI,GAA6B,EAAiB,CAChD,IAAM,EAAoC,CACxC,iBAAkB,EAClB,uBAAwBc,EAAAA,wBAAwB,kBAChD,QACA,mBAAoB,EACrB,CAED,IAAe,EAAa,CAE5B,IAAM,EAAiB,MAAM,EAAU,KACrC,EACA,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,CAID,IAFwB,MAAM,EAAa,0BAA0B,CAAE,KAAM,EAAgB,CAAC,EAE1E,SAAW,WAC7B,OAAOC,EAAAA,4BAA4B,EAAO,CACxC,cACA,UAAWf,EAAAA,UAAU,qBACrB,YAAa,0CACd,CAAC,CAIN,IAAM,EAAoB,MAAMgB,EAAAA,6BAA6B,CAC3D,WAAY,EACZ,cACA,kBAAmB,GAAa,qBAChC,eACA,OACD,CAAC,CAEI,EAAqC,CACzC,QAASL,EAAAA,wBAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EAAK,KACX,KAAM,EACN,IAAK,EACL,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAEK,EAA4B,CAChC,iBAAkB,EAA4B,EAAI,EAClD,uBAAwBG,EAAAA,wBAAwB,eAChD,QACA,mBAAoB,EAA4B,EAAI,EACrD,CAED,IAAe,EAAK,CAEpB,IAAM,EAAc,KAAK,KAAK,CAQ9B,OAAO,EANQ,MAAM,EAAU,KAC7B,EACA,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,CAEkC,EAAY,CAgBjD,eAAe,EAAoB,CACjC,aACA,QACA,cACA,eACA,QACA,gBACuC,CACvC,GAAI,CAAC,EACH,MAAM,IAAIhB,EAAAA,SAASC,EAAAA,YAAY,eAAgBC,EAAAA,UAAU,eAAgB,CACvE,QAAS,sEACV,CAAC,CAGJ,GAAI,CAACiB,EAAAA,aAAa,EAAM,YAAY,CAClC,MAAM,IAAInB,EAAAA,SAASC,EAAAA,YAAY,eAAgBC,EAAAA,UAAU,eAAgB,CACvE,QAAS,6CACV,CAAC,CAGJ,IAAM,EAAeG,EAAAA,+BAA+B,CAClD,UAAW,EAAM,UACjB,SAAU,EAAM,SAChB,YAAa,EAAM,YACpB,CAAC,CAEI,EAAuBE,EAAAA,qBAAqB,EAAM,QAAS,EAAM,YAAY,QAAQ,CACrF,EAAwBA,EAAAA,qBAAqB,EAAM,SAAU,EAAM,YAAY,QAAQ,CAEvF,EAAO,MAAMO,EAAAA,UAAU,EAAY,CACvC,SAAU,EAAM,SAAS,UAAU,CACnC,QACA,aAAc,EAAa,UAAU,CACrC,QAAS,EACT,SAAU,EACV,cAAe,EAAM,YACrB,KAAM,EAAM,GACb,CAAC,CAEF,GAAI,CAACM,EAAAA,qBAAqB,EAAK,CAC7B,MAAM,IAAIpB,EAAAA,SAASC,EAAAA,YAAY,oBAAqBC,EAAAA,UAAU,eAAgB,CAC5E,QAAS,qGACV,CAAC,CAGJ,IAAM,EAAwB,MAAMmB,EAAAA,sCAClC,EAAK,gBACLC,EAAAA,qBAAqB,CAAE,MAAO,EAAM,YAAa,CAAC,CACnD,CAEK,EAA4B,CAChC,iBAAkB,EAClB,uBAAwBN,EAAAA,wBAAwB,eAChD,QACA,mBAAoB,EACrB,CAED,IAAe,EAAK,CAEpB,IAAM,EAAc,KAAK,KAAK,CAExB,EAAS,MAAM,EAAa,YAChC,CACE,QAAS,EAAM,YACf,aAAc,EACf,CACD,EACD,CAEK,EAAmB,EAAM,YAAY,QAAQ,aAAa,GAAK,EAAM,YAAY,QAAQ,aAAa,CAE5G,MAAO,CACL,SAAU,EAAM,SAChB,UAAW,EAAM,UACjB,cACA,KAAM,EAAM,KACZ,YAAa,EAAM,YACnB,GAAI,EAAM,GACV,cAAe,EAAM,cACrB,YAAa,EAAM,QACnB,YAAa,EAAM,YACnB,OAAQ,iBACR,YAAa,EAAM,SACnB,YAAa,EAAM,YACnB,UAAW,EAAM,UACjB,KAAMjB,EAAAA,YAAY,MAClB,OAAQ,CACN,kBAAmB,EACnB,0BAA2B,EAAmB,EAAIwB,EAAAA,8BAClD,cACA,SACD,CACF,CAQH,SAAS,EAAwB,CAC/B,kBACA,4BACA,YACA,gBACA,iBAOU,CACV,OACEnB,EAAAA,eAAe,EAAc,EAC7BA,EAAAA,eAAe,EAAc,EAC7B,IAAkB,GAClB,GACA,IAAoB,IAAA,IACpB,OAAO,GAAc"}
|
|
1
|
+
{"version":3,"file":"transfer-asset.cjs","names":["ServiceType","SdkError","ErrorReason","ErrorCode","isSolanaNamespace","isEvmNamespace","calculateMarkrMinimumAmountOut","getEvmClientForChain","assetToAddressString","isTokenAddressNative","markrGetSpenderAddress","caip2ToEip155ChainId","erc20Abi","applyFeeUnitsBpsMargin","caip2ToEip155HexChainId","markrSwap","isEvmSwapResponse","TransferSignatureReason","makeFailedTransferFromQuote","_estimateGasFromSwapResponse","isSolAddress","isSolanaSwapResponse","refreshSolanaSwapTransactionBlockhash","getSolanaRpcForChain","SOLANA_REQUIRED_CONFIRMATIONS"],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { encodeFunctionData, erc20Abi, isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ServiceType, TransferSignatureReason } from '../../../constants';\nimport type { Environment } from '../../../constants';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\nimport type { EvmSigner, EvmTransactionRequest, SolanaSigner } from '../../../types/signer';\nimport type { Transfer, TransferStepDetails } from '../../../types/transfer';\nimport { caip2ToEip155ChainId, caip2ToEip155HexChainId } from '../../../utils/caip';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport {\n applyFeeUnitsBpsMargin,\n getEvmClientForChain,\n getSolanaRpcForChain,\n makeFailedTransferFromQuote,\n} from '../../_utils';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport { assetToAddressString, calculateMarkrMinimumAmountOut, isTokenAddressNative } from '../_utils';\nimport { isEvmSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../_solana-utils';\n\nexport interface TransferAssetFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n solanaSigner?: SolanaSigner;\n}\n\nexport function transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n}: TransferAssetFactoryConfig): TransferService['transferAsset'] {\n return async ({ quote, gasSettings, fallbackToDefaultOnBatchFailure, onStepChange }) => {\n if (quote.serviceType !== ServiceType.MARKR) {\n throw new SdkError(ErrorReason.INCORRECT_PROVIDER_PROVIDED, ErrorCode.INVALID_PARAMS);\n }\n\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n throw new SdkError(ErrorReason.QUOTE_EXPIRED, ErrorCode.INVALID_PARAMS);\n }\n\n const sourceChainId = quote.sourceChain.chainId;\n\n if (isSolanaNamespace(sourceChainId)) {\n return _executeSvmTransfer({ apiOptions, appId, environment, solanaSigner, quote, onStepChange });\n }\n\n if (isEvmNamespace(sourceChainId)) {\n return _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n });\n }\n\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Unsupported source chain namespace: ${sourceChainId}`,\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// EVM transfer path\n// ---------------------------------------------------------------------------\n\ninterface EvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n gasSettings?: Parameters<TransferService['transferAsset']>[0]['gasSettings'];\n fallbackToDefaultOnBatchFailure?: Parameters<TransferService['transferAsset']>[0]['fallbackToDefaultOnBatchFailure'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n}: EvmTransferParams): Promise<Transfer> {\n const fromAddress = quote.fromAddress;\n\n if (!isAddress(fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid EVM address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const sourceClient = getEvmClientForChain({ chain: quote.sourceChain });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n if (!isAddress(tokenInAddressString)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'assetIn address is not a valid EVM address.',\n });\n }\n\n const tokenInAddress = tokenInAddressString;\n const isTokenInNative = isTokenAddressNative(tokenInAddress);\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n const { address: spenderAddress } = await markrGetSpenderAddress(apiOptions, {\n chainId: caip2ToEip155ChainId(quote.sourceChain.chainId),\n crossChainSwap: isCrossChainSwap,\n quoteId: quote.id,\n });\n\n if (!isTokenInNative && !spenderAddress) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Missing Markr spender address for source chain ${quote.sourceChain.chainId}.`,\n });\n }\n\n let requiresApprovalSignature = false;\n let approvalRequest: EvmTransactionRequest | undefined;\n\n if (!isTokenInNative && spenderAddress) {\n const allowance = await sourceClient.readContract({\n address: tokenInAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [fromAddress, spenderAddress],\n });\n\n if (allowance < quote.amountIn) {\n requiresApprovalSignature = true;\n\n const approvalData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, quote.amountIn],\n });\n\n let approvalGasWithMargin: bigint | undefined;\n\n try {\n const approvalGasEstimate = await sourceClient.estimateGas({\n account: fromAddress,\n to: tokenInAddress,\n data: approvalData,\n value: 0n,\n });\n\n approvalGasWithMargin = applyFeeUnitsBpsMargin(approvalGasEstimate, gasSettings?.estimateGasMarginBps);\n } catch (err) {\n throw new SdkError('Error during gas estimation', ErrorCode.VIEM_ERROR, {\n cause: err,\n details: 'Failed to estimate gas for ERC20 approval transaction.',\n });\n }\n\n approvalRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: approvalData,\n from: fromAddress,\n gas: approvalGasWithMargin,\n to: tokenInAddress,\n value: 0n,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n }\n }\n\n const maybeOneClickBatch = isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch: evmSigner.signBatch,\n sourceChainId: quote.sourceChain.chainId,\n targetChainId: quote.targetChain.chainId,\n });\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n uuid: quote.id,\n });\n\n if (!isEvmSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.',\n });\n }\n\n const makePendingTransfer = (txHash: `0x${string}`, startedAtMs: number = Date.now()): Transfer => {\n const isSameChainTransfer = quote.sourceChain.chainId === quote.targetChain.chainId;\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isSameChainTransfer ? 1 : 2,\n startedAtMs,\n txHash,\n },\n };\n };\n\n if (maybeOneClickBatch && approvalRequest) {\n const batchStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n const signBatch = evmSigner.signBatch;\n\n if (!signBatch) {\n throw new SdkError('One-click batch signer is not available.', ErrorCode.SIGNING_FAILED);\n }\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n // Gas is purposely left undefined here.\n // We can't estimate the gas because we aren't executing the\n // approval tx. It's up to the wallet to correctly handle gas estimation.\n gas: undefined,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n onStepChange?.(batchStep);\n\n try {\n const txHashes = await signBatch(\n [approvalRequest, swapRequest],\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n batchStep,\n );\n\n const swapTxHash = txHashes.at(-1);\n\n if (!swapTxHash) {\n throw new SdkError('One-click batch signing returned no transaction hashes.', ErrorCode.SIGNING_FAILED);\n }\n\n return makePendingTransfer(swapTxHash);\n } catch (error) {\n if (!fallbackToDefaultOnBatchFailure) {\n throw error;\n }\n }\n }\n\n if (requiresApprovalSignature && approvalRequest) {\n const approvalStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n };\n\n onStepChange?.(approvalStep);\n\n const approvalTxHash = await evmSigner.sign(\n approvalRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n approvalStep,\n );\n\n const approvalReceipt = await sourceClient.waitForTransactionReceipt({ hash: approvalTxHash });\n\n if (approvalReceipt.status === 'reverted') {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n }\n\n const swapGasWithMargin = await _estimateGasFromSwapResponse({\n crossChain: isCrossChainSwap,\n fromAddress,\n feeUnitsMarginBps: gasSettings?.estimateGasMarginBps,\n sourceClient,\n swap,\n });\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n gas: swapGasWithMargin,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n const step: TransferStepDetails = {\n currentSignature: requiresApprovalSignature ? 2 : 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: requiresApprovalSignature ? 2 : 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await evmSigner.sign(\n swapRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n step,\n );\n\n return makePendingTransfer(txHash, startedAtMs);\n}\n\n// ---------------------------------------------------------------------------\n// SVM (Solana) transfer path\n// ---------------------------------------------------------------------------\n\ninterface SvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n solanaSigner?: SolanaSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeSvmTransfer({\n apiOptions,\n appId,\n environment,\n solanaSigner,\n quote,\n onStepChange,\n}: SvmTransferParams): Promise<Transfer> {\n if (!solanaSigner) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'solanaSigner is required for Solana transfers but was not provided.',\n });\n }\n\n if (!isSolAddress(quote.fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid Solana address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n userPublicKey: quote.fromAddress,\n uuid: quote.id,\n });\n\n if (!isSolanaSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.',\n });\n }\n\n // TODO: Cleanup\n console.debug('[Fusion SDK] Original swap transaction (base64):', swap.swapTransaction);\n\n const swapTransactionBase64 = await refreshSolanaSwapTransactionBlockhash(\n swap.swapTransaction,\n getSolanaRpcForChain({ chain: quote.sourceChain }),\n );\n\n // TODO: Cleanup\n console.debug('[Fusion SDK] Refreshed swap transaction with new blockhash (base64):', swapTransactionBase64);\n\n const step: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await solanaSigner.signAndSend(\n {\n account: quote.fromAddress,\n serializedTx: swapTransactionBase64,\n },\n step,\n );\n\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isCrossChainSwap ? 2 : SOLANA_REQUIRED_CONFIRMATIONS,\n startedAtMs,\n txHash,\n },\n };\n}\n\n/**\n * Determines whether one-click swap eligibility criteria is met.\n *\n * Only same-chain EVM swaps are currently eligible.\n */\nfunction isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch,\n sourceChainId,\n targetChainId,\n}: {\n approvalRequest?: EvmTransactionRequest;\n requiresApprovalSignature: boolean;\n signBatch?: EvmSigner['signBatch'];\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n}): boolean {\n return (\n isEvmNamespace(sourceChainId) &&\n isEvmNamespace(targetChainId) &&\n sourceChainId === targetChainId &&\n requiresApprovalSignature &&\n approvalRequest !== undefined &&\n typeof signBatch === 'function'\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ServiceType as e,TransferSignatureReason as t}from"../../../constants.js";import{ErrorCode as n,ErrorReason as r,SdkError as i}from"../../../errors.js";import{caip2ToEip155ChainId as a,caip2ToEip155HexChainId as o}from"../../../utils/caip.js";import{isEvmNamespace as s,isSolanaNamespace as c}from"../../../_utils/chain.js";import{applyFeeUnitsBpsMargin as l,getEvmClientForChain as u,getSolanaRpcForChain as d,makeFailedTransferFromQuote as f}from"../../_utils.js";import{markrGetSpenderAddress as p,markrSwap as m}from"../_api.js";import{isSolAddress as h}from"../../../utils/sol-address.js";import{assetToAddressString as g,calculateMarkrMinimumAmountOut as _,isTokenAddressNative as v}from"../_utils.js";import{isEvmSwapResponse as y,isSolanaSwapResponse as b}from"../_type-guards.js";import{refreshSolanaSwapTransactionBlockhash as x}from"../_solana-utils.js";import{_estimateGasFromSwapResponse as S}from"./estimate-native-fee.js";import{SOLANA_REQUIRED_CONFIRMATIONS as C}from"../constants.js";import{encodeFunctionData as w,erc20Abi as T,isAddress as E}from"viem";function D({apiOptions:t,appId:a,environment:o,evmSigner:l,solanaSigner:u}){return async({quote:d,gasSettings:f,fallbackToDefaultOnBatchFailure:p,onStepChange:m})=>{if(d.serviceType!==e.MARKR)throw new i(r.INCORRECT_PROVIDER_PROVIDED,n.INVALID_PARAMS);let h=Math.floor(Date.now()/1e3);if(d.expiresAt<=h)throw new i(r.QUOTE_EXPIRED,n.INVALID_PARAMS);let g=d.sourceChain.chainId;if(c(g))return k({apiOptions:t,appId:a,environment:o,solanaSigner:u,quote:d,onStepChange:m});if(s(g))return O({apiOptions:t,appId:a,environment:o,evmSigner:l,quote:d,gasSettings:f,fallbackToDefaultOnBatchFailure:p,onStepChange:m});throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Unsupported source chain namespace: ${g}`})}}async function O({apiOptions:s,appId:c,environment:d,evmSigner:h,quote:b,gasSettings:x,fallbackToDefaultOnBatchFailure:C,onStepChange:D}){let O=b.fromAddress;if(!E(O))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`fromAddress is not a valid EVM address.`});let k=_({amountOut:b.amountOut,assetOut:b.assetOut,slippageBps:b.slippageBps}),j=u({chain:b.sourceChain}),M=g(b.assetIn,b.sourceChain.chainId),N=g(b.assetOut,b.targetChain.chainId);if(!E(M))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`assetIn address is not a valid EVM address.`});let P=M,F=v(P),I=b.sourceChain.chainId.toLowerCase()!==b.targetChain.chainId.toLowerCase(),{address:L}=await p(s,{chainId:a(b.sourceChain.chainId),crossChainSwap:I,quoteId:b.id});if(!F&&!L)throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Missing Markr spender address for source chain ${b.sourceChain.chainId}.`});let R=!1,z;if(!F&&L&&await j.readContract({address:P,abi:T,functionName:`allowance`,args:[O,L]})<b.amountIn){R=!0;let e=w({abi:T,functionName:`approve`,args:[L,b.amountIn]}),t;try{t=l(await j.estimateGas({account:O,to:P,data:e,value:0n}),x?.estimateGasMarginBps)}catch(e){throw new i(`Error during gas estimation`,n.VIEM_ERROR,{cause:e,details:`Failed to estimate gas for ERC20 approval transaction.`})}z={chainId:o(b.sourceChain.chainId),data:e,from:O,gas:t,to:P,value:0n,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}}}let B=A({approvalRequest:z,requiresApprovalSignature:R,signBatch:h.signBatch,sourceChainId:b.sourceChain.chainId,targetChainId:b.targetChain.chainId}),V=await m(s,{amountIn:b.amountIn.toString(),appId:c,minAmountOut:k.toString(),tokenIn:M,tokenOut:N,uuid:b.id});if(!y(V))throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.`});let H=(t,n=Date.now())=>{let r=b.sourceChain.chainId===b.targetChain.chainId;return{amountIn:b.amountIn,amountOut:b.amountOut,environment:d,fees:b.fees,fromAddress:b.fromAddress,id:b.id,partnerFeeBps:b.partnerFeeBps,sourceAsset:b.assetIn,sourceChain:b.sourceChain,status:`source-pending`,targetAsset:b.assetOut,targetChain:b.targetChain,toAddress:b.toAddress,type:e.MARKR,source:{confirmationCount:0,requiredConfirmationCount:r?1:2,startedAtMs:n,txHash:t}}};if(B&&z){let e={currentSignature:1,currentSignatureReason:t.TokensTransfer,quote:b,requiredSignatures:1},r=h.signBatch;if(!r)throw new i(`One-click batch signer is not available.`,n.SIGNING_FAILED);let a={chainId:o(b.sourceChain.chainId),data:V.data,from:O,gas:void 0,to:V.to,value:V.value,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}};D?.(e);try{let t=(await r([z,a],async e=>j.sendRawTransaction({serializedTransaction:e}),e)).at(-1);if(!t)throw new i(`One-click batch signing returned no transaction hashes.`,n.SIGNING_FAILED);return H(t)}catch(e){if(!C)throw e}}if(R&&z){let e={currentSignature:1,currentSignatureReason:t.AllowanceApproval,quote:b,requiredSignatures:2};D?.(e);let r=await h.sign(z,async e=>j.sendRawTransaction({serializedTransaction:e}),e);if((await j.waitForTransactionReceipt({hash:r})).status===`reverted`)return f(b,{environment:d,errorCode:n.TRANSACTION_REVERTED,errorReason:`ERC20 approval transaction was reverted`})}let U=await S({crossChain:I,fromAddress:O,feeUnitsMarginBps:x?.estimateGasMarginBps,sourceClient:j,swap:V}),W={chainId:o(b.sourceChain.chainId),data:V.data,from:O,gas:U,to:V.to,value:V.value,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}},G={currentSignature:R?2:1,currentSignatureReason:t.TokensTransfer,quote:b,requiredSignatures:R?2:1};D?.(G);let K=Date.now();return H(await h.sign(W,async e=>j.sendRawTransaction({serializedTransaction:e}),G),K)}async function k({apiOptions:a,appId:o,environment:s,solanaSigner:c,quote:l,onStepChange:u}){if(!c)throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`solanaSigner is required for Solana transfers but was not provided.`});if(!h(l.fromAddress))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`fromAddress is not a valid Solana address.`});let f=_({amountOut:l.amountOut,assetOut:l.assetOut,slippageBps:l.slippageBps}),p=g(l.assetIn,l.sourceChain.chainId),v=g(l.assetOut,l.targetChain.chainId),y=await m(a,{amountIn:l.amountIn.toString(),appId:o,minAmountOut:f.toString(),tokenIn:p,tokenOut:v,userPublicKey:l.fromAddress,uuid:l.id});if(!b(y))throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.`});let S=await x(y.swapTransaction,d({chain:l.sourceChain}))
|
|
1
|
+
import{ServiceType as e,TransferSignatureReason as t}from"../../../constants.js";import{ErrorCode as n,ErrorReason as r,SdkError as i}from"../../../errors.js";import{caip2ToEip155ChainId as a,caip2ToEip155HexChainId as o}from"../../../utils/caip.js";import{isEvmNamespace as s,isSolanaNamespace as c}from"../../../_utils/chain.js";import{applyFeeUnitsBpsMargin as l,getEvmClientForChain as u,getSolanaRpcForChain as d,makeFailedTransferFromQuote as f}from"../../_utils.js";import{markrGetSpenderAddress as p,markrSwap as m}from"../_api.js";import{isSolAddress as h}from"../../../utils/sol-address.js";import{assetToAddressString as g,calculateMarkrMinimumAmountOut as _,isTokenAddressNative as v}from"../_utils.js";import{isEvmSwapResponse as y,isSolanaSwapResponse as b}from"../_type-guards.js";import{refreshSolanaSwapTransactionBlockhash as x}from"../_solana-utils.js";import{_estimateGasFromSwapResponse as S}from"./estimate-native-fee.js";import{SOLANA_REQUIRED_CONFIRMATIONS as C}from"../constants.js";import{encodeFunctionData as w,erc20Abi as T,isAddress as E}from"viem";function D({apiOptions:t,appId:a,environment:o,evmSigner:l,solanaSigner:u}){return async({quote:d,gasSettings:f,fallbackToDefaultOnBatchFailure:p,onStepChange:m})=>{if(d.serviceType!==e.MARKR)throw new i(r.INCORRECT_PROVIDER_PROVIDED,n.INVALID_PARAMS);let h=Math.floor(Date.now()/1e3);if(d.expiresAt<=h)throw new i(r.QUOTE_EXPIRED,n.INVALID_PARAMS);let g=d.sourceChain.chainId;if(c(g))return k({apiOptions:t,appId:a,environment:o,solanaSigner:u,quote:d,onStepChange:m});if(s(g))return O({apiOptions:t,appId:a,environment:o,evmSigner:l,quote:d,gasSettings:f,fallbackToDefaultOnBatchFailure:p,onStepChange:m});throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Unsupported source chain namespace: ${g}`})}}async function O({apiOptions:s,appId:c,environment:d,evmSigner:h,quote:b,gasSettings:x,fallbackToDefaultOnBatchFailure:C,onStepChange:D}){let O=b.fromAddress;if(!E(O))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`fromAddress is not a valid EVM address.`});let k=_({amountOut:b.amountOut,assetOut:b.assetOut,slippageBps:b.slippageBps}),j=u({chain:b.sourceChain}),M=g(b.assetIn,b.sourceChain.chainId),N=g(b.assetOut,b.targetChain.chainId);if(!E(M))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`assetIn address is not a valid EVM address.`});let P=M,F=v(P),I=b.sourceChain.chainId.toLowerCase()!==b.targetChain.chainId.toLowerCase(),{address:L}=await p(s,{chainId:a(b.sourceChain.chainId),crossChainSwap:I,quoteId:b.id});if(!F&&!L)throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Missing Markr spender address for source chain ${b.sourceChain.chainId}.`});let R=!1,z;if(!F&&L&&await j.readContract({address:P,abi:T,functionName:`allowance`,args:[O,L]})<b.amountIn){R=!0;let e=w({abi:T,functionName:`approve`,args:[L,b.amountIn]}),t;try{t=l(await j.estimateGas({account:O,to:P,data:e,value:0n}),x?.estimateGasMarginBps)}catch(e){throw new i(`Error during gas estimation`,n.VIEM_ERROR,{cause:e,details:`Failed to estimate gas for ERC20 approval transaction.`})}z={chainId:o(b.sourceChain.chainId),data:e,from:O,gas:t,to:P,value:0n,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}}}let B=A({approvalRequest:z,requiresApprovalSignature:R,signBatch:h.signBatch,sourceChainId:b.sourceChain.chainId,targetChainId:b.targetChain.chainId}),V=await m(s,{amountIn:b.amountIn.toString(),appId:c,minAmountOut:k.toString(),tokenIn:M,tokenOut:N,uuid:b.id});if(!y(V))throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.`});let H=(t,n=Date.now())=>{let r=b.sourceChain.chainId===b.targetChain.chainId;return{amountIn:b.amountIn,amountOut:b.amountOut,environment:d,fees:b.fees,fromAddress:b.fromAddress,id:b.id,partnerFeeBps:b.partnerFeeBps,sourceAsset:b.assetIn,sourceChain:b.sourceChain,status:`source-pending`,targetAsset:b.assetOut,targetChain:b.targetChain,toAddress:b.toAddress,type:e.MARKR,source:{confirmationCount:0,requiredConfirmationCount:r?1:2,startedAtMs:n,txHash:t}}};if(B&&z){let e={currentSignature:1,currentSignatureReason:t.TokensTransfer,quote:b,requiredSignatures:1},r=h.signBatch;if(!r)throw new i(`One-click batch signer is not available.`,n.SIGNING_FAILED);let a={chainId:o(b.sourceChain.chainId),data:V.data,from:O,gas:void 0,to:V.to,value:V.value,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}};D?.(e);try{let t=(await r([z,a],async e=>j.sendRawTransaction({serializedTransaction:e}),e)).at(-1);if(!t)throw new i(`One-click batch signing returned no transaction hashes.`,n.SIGNING_FAILED);return H(t)}catch(e){if(!C)throw e}}if(R&&z){let e={currentSignature:1,currentSignatureReason:t.AllowanceApproval,quote:b,requiredSignatures:2};D?.(e);let r=await h.sign(z,async e=>j.sendRawTransaction({serializedTransaction:e}),e);if((await j.waitForTransactionReceipt({hash:r})).status===`reverted`)return f(b,{environment:d,errorCode:n.TRANSACTION_REVERTED,errorReason:`ERC20 approval transaction was reverted`})}let U=await S({crossChain:I,fromAddress:O,feeUnitsMarginBps:x?.estimateGasMarginBps,sourceClient:j,swap:V}),W={chainId:o(b.sourceChain.chainId),data:V.data,from:O,gas:U,to:V.to,value:V.value,...x?.maxFeePerGas===void 0?null:{maxFeePerGas:x.maxFeePerGas,maxPriorityFeePerGas:x.maxPriorityFeePerGas}},G={currentSignature:R?2:1,currentSignatureReason:t.TokensTransfer,quote:b,requiredSignatures:R?2:1};D?.(G);let K=Date.now();return H(await h.sign(W,async e=>j.sendRawTransaction({serializedTransaction:e}),G),K)}async function k({apiOptions:a,appId:o,environment:s,solanaSigner:c,quote:l,onStepChange:u}){if(!c)throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`solanaSigner is required for Solana transfers but was not provided.`});if(!h(l.fromAddress))throw new i(r.INVALID_PARAMS,n.INVALID_PARAMS,{details:`fromAddress is not a valid Solana address.`});let f=_({amountOut:l.amountOut,assetOut:l.assetOut,slippageBps:l.slippageBps}),p=g(l.assetIn,l.sourceChain.chainId),v=g(l.assetOut,l.targetChain.chainId),y=await m(a,{amountIn:l.amountIn.toString(),appId:o,minAmountOut:f.toString(),tokenIn:p,tokenOut:v,userPublicKey:l.fromAddress,uuid:l.id});if(!b(y))throw new i(r.CHAIN_NOT_SUPPORTED,n.INVALID_PARAMS,{details:`Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.`});console.debug(`[Fusion SDK] Original swap transaction (base64):`,y.swapTransaction);let S=await x(y.swapTransaction,d({chain:l.sourceChain}));console.debug(`[Fusion SDK] Refreshed swap transaction with new blockhash (base64):`,S);let w={currentSignature:1,currentSignatureReason:t.TokensTransfer,quote:l,requiredSignatures:1};u?.(w);let T=Date.now(),E=await c.signAndSend({account:l.fromAddress,serializedTx:S},w),D=l.sourceChain.chainId.toLowerCase()!==l.targetChain.chainId.toLowerCase();return{amountIn:l.amountIn,amountOut:l.amountOut,environment:s,fees:l.fees,fromAddress:l.fromAddress,id:l.id,partnerFeeBps:l.partnerFeeBps,sourceAsset:l.assetIn,sourceChain:l.sourceChain,status:`source-pending`,targetAsset:l.assetOut,targetChain:l.targetChain,toAddress:l.toAddress,type:e.MARKR,source:{confirmationCount:0,requiredConfirmationCount:D?2:C,startedAtMs:T,txHash:E}}}function A({approvalRequest:e,requiresApprovalSignature:t,signBatch:n,sourceChainId:r,targetChainId:i}){return s(r)&&s(i)&&r===i&&t&&e!==void 0&&typeof n==`function`}export{D as transferAssetFactory};
|
|
2
2
|
//# sourceMappingURL=transfer-asset.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer-asset.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { encodeFunctionData, erc20Abi, isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ServiceType, TransferSignatureReason } from '../../../constants';\nimport type { Environment } from '../../../constants';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\nimport type { EvmSigner, EvmTransactionRequest, SolanaSigner } from '../../../types/signer';\nimport type { Transfer, TransferStepDetails } from '../../../types/transfer';\nimport { caip2ToEip155ChainId, caip2ToEip155HexChainId } from '../../../utils/caip';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport {\n applyFeeUnitsBpsMargin,\n getEvmClientForChain,\n getSolanaRpcForChain,\n makeFailedTransferFromQuote,\n} from '../../_utils';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport { assetToAddressString, calculateMarkrMinimumAmountOut, isTokenAddressNative } from '../_utils';\nimport { isEvmSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../_solana-utils';\n\nexport interface TransferAssetFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n solanaSigner?: SolanaSigner;\n}\n\nexport function transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n}: TransferAssetFactoryConfig): TransferService['transferAsset'] {\n return async ({ quote, gasSettings, fallbackToDefaultOnBatchFailure, onStepChange }) => {\n if (quote.serviceType !== ServiceType.MARKR) {\n throw new SdkError(ErrorReason.INCORRECT_PROVIDER_PROVIDED, ErrorCode.INVALID_PARAMS);\n }\n\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n throw new SdkError(ErrorReason.QUOTE_EXPIRED, ErrorCode.INVALID_PARAMS);\n }\n\n const sourceChainId = quote.sourceChain.chainId;\n\n if (isSolanaNamespace(sourceChainId)) {\n return _executeSvmTransfer({ apiOptions, appId, environment, solanaSigner, quote, onStepChange });\n }\n\n if (isEvmNamespace(sourceChainId)) {\n return _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n });\n }\n\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Unsupported source chain namespace: ${sourceChainId}`,\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// EVM transfer path\n// ---------------------------------------------------------------------------\n\ninterface EvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n gasSettings?: Parameters<TransferService['transferAsset']>[0]['gasSettings'];\n fallbackToDefaultOnBatchFailure?: Parameters<TransferService['transferAsset']>[0]['fallbackToDefaultOnBatchFailure'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n}: EvmTransferParams): Promise<Transfer> {\n const fromAddress = quote.fromAddress;\n\n if (!isAddress(fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid EVM address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const sourceClient = getEvmClientForChain({ chain: quote.sourceChain });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n if (!isAddress(tokenInAddressString)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'assetIn address is not a valid EVM address.',\n });\n }\n\n const tokenInAddress = tokenInAddressString;\n const isTokenInNative = isTokenAddressNative(tokenInAddress);\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n const { address: spenderAddress } = await markrGetSpenderAddress(apiOptions, {\n chainId: caip2ToEip155ChainId(quote.sourceChain.chainId),\n crossChainSwap: isCrossChainSwap,\n quoteId: quote.id,\n });\n\n if (!isTokenInNative && !spenderAddress) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Missing Markr spender address for source chain ${quote.sourceChain.chainId}.`,\n });\n }\n\n let requiresApprovalSignature = false;\n let approvalRequest: EvmTransactionRequest | undefined;\n\n if (!isTokenInNative && spenderAddress) {\n const allowance = await sourceClient.readContract({\n address: tokenInAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [fromAddress, spenderAddress],\n });\n\n if (allowance < quote.amountIn) {\n requiresApprovalSignature = true;\n\n const approvalData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, quote.amountIn],\n });\n\n let approvalGasWithMargin: bigint | undefined;\n\n try {\n const approvalGasEstimate = await sourceClient.estimateGas({\n account: fromAddress,\n to: tokenInAddress,\n data: approvalData,\n value: 0n,\n });\n\n approvalGasWithMargin = applyFeeUnitsBpsMargin(approvalGasEstimate, gasSettings?.estimateGasMarginBps);\n } catch (err) {\n throw new SdkError('Error during gas estimation', ErrorCode.VIEM_ERROR, {\n cause: err,\n details: 'Failed to estimate gas for ERC20 approval transaction.',\n });\n }\n\n approvalRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: approvalData,\n from: fromAddress,\n gas: approvalGasWithMargin,\n to: tokenInAddress,\n value: 0n,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n }\n }\n\n const maybeOneClickBatch = isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch: evmSigner.signBatch,\n sourceChainId: quote.sourceChain.chainId,\n targetChainId: quote.targetChain.chainId,\n });\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n uuid: quote.id,\n });\n\n if (!isEvmSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.',\n });\n }\n\n const makePendingTransfer = (txHash: `0x${string}`, startedAtMs: number = Date.now()): Transfer => {\n const isSameChainTransfer = quote.sourceChain.chainId === quote.targetChain.chainId;\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isSameChainTransfer ? 1 : 2,\n startedAtMs,\n txHash,\n },\n };\n };\n\n if (maybeOneClickBatch && approvalRequest) {\n const batchStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n const signBatch = evmSigner.signBatch;\n\n if (!signBatch) {\n throw new SdkError('One-click batch signer is not available.', ErrorCode.SIGNING_FAILED);\n }\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n // Gas is purposely left undefined here.\n // We can't estimate the gas because we aren't executing the\n // approval tx. It's up to the wallet to correctly handle gas estimation.\n gas: undefined,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n onStepChange?.(batchStep);\n\n try {\n const txHashes = await signBatch(\n [approvalRequest, swapRequest],\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n batchStep,\n );\n\n const swapTxHash = txHashes.at(-1);\n\n if (!swapTxHash) {\n throw new SdkError('One-click batch signing returned no transaction hashes.', ErrorCode.SIGNING_FAILED);\n }\n\n return makePendingTransfer(swapTxHash);\n } catch (error) {\n if (!fallbackToDefaultOnBatchFailure) {\n throw error;\n }\n }\n }\n\n if (requiresApprovalSignature && approvalRequest) {\n const approvalStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n };\n\n onStepChange?.(approvalStep);\n\n const approvalTxHash = await evmSigner.sign(\n approvalRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n approvalStep,\n );\n\n const approvalReceipt = await sourceClient.waitForTransactionReceipt({ hash: approvalTxHash });\n\n if (approvalReceipt.status === 'reverted') {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n }\n\n const swapGasWithMargin = await _estimateGasFromSwapResponse({\n crossChain: isCrossChainSwap,\n fromAddress,\n feeUnitsMarginBps: gasSettings?.estimateGasMarginBps,\n sourceClient,\n swap,\n });\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n gas: swapGasWithMargin,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n const step: TransferStepDetails = {\n currentSignature: requiresApprovalSignature ? 2 : 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: requiresApprovalSignature ? 2 : 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await evmSigner.sign(\n swapRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n step,\n );\n\n return makePendingTransfer(txHash, startedAtMs);\n}\n\n// ---------------------------------------------------------------------------\n// SVM (Solana) transfer path\n// ---------------------------------------------------------------------------\n\ninterface SvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n solanaSigner?: SolanaSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeSvmTransfer({\n apiOptions,\n appId,\n environment,\n solanaSigner,\n quote,\n onStepChange,\n}: SvmTransferParams): Promise<Transfer> {\n if (!solanaSigner) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'solanaSigner is required for Solana transfers but was not provided.',\n });\n }\n\n if (!isSolAddress(quote.fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid Solana address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n userPublicKey: quote.fromAddress,\n uuid: quote.id,\n });\n\n if (!isSolanaSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.',\n });\n }\n\n const swapTransactionBase64 = await refreshSolanaSwapTransactionBlockhash(\n swap.swapTransaction,\n getSolanaRpcForChain({ chain: quote.sourceChain }),\n );\n\n const step: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await solanaSigner.signAndSend(\n {\n account: quote.fromAddress,\n serializedTx: swapTransactionBase64,\n },\n step,\n );\n\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isCrossChainSwap ? 2 : SOLANA_REQUIRED_CONFIRMATIONS,\n startedAtMs,\n txHash,\n },\n };\n}\n\n/**\n * Determines whether one-click swap eligibility criteria is met.\n *\n * Only same-chain EVM swaps are currently eligible.\n */\nfunction isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch,\n sourceChainId,\n targetChainId,\n}: {\n approvalRequest?: EvmTransactionRequest;\n requiresApprovalSignature: boolean;\n signBatch?: EvmSigner['signBatch'];\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n}): boolean {\n return (\n isEvmNamespace(sourceChainId) &&\n isEvmNamespace(targetChainId) &&\n sourceChainId === targetChainId &&\n requiresApprovalSignature &&\n approvalRequest !== undefined &&\n typeof signBatch === 'function'\n );\n}\n"],"mappings":"ujCAgCA,SAAgB,EAAqB,CACnC,aACA,QACA,cACA,YACA,gBAC+D,CAC/D,OAAO,MAAO,CAAE,QAAO,cAAa,kCAAiC,kBAAmB,CACtF,GAAI,EAAM,cAAgB,EAAY,MACpC,MAAM,IAAI,EAAS,EAAY,4BAA6B,EAAU,eAAe,CAGvF,IAAM,EAAM,KAAK,MAAM,KAAK,KAAK,CAAG,IAAM,CAE1C,GAAI,EAAM,WAAa,EACrB,MAAM,IAAI,EAAS,EAAY,cAAe,EAAU,eAAe,CAGzE,IAAM,EAAgB,EAAM,YAAY,QAExC,GAAI,EAAkB,EAAc,CAClC,OAAO,EAAoB,CAAE,aAAY,QAAO,cAAa,eAAc,QAAO,eAAc,CAAC,CAGnG,GAAI,EAAe,EAAc,CAC/B,OAAO,EAAoB,CACzB,aACA,QACA,cACA,YACA,QACA,cACA,kCACA,eACD,CAAC,CAGJ,MAAM,IAAI,EAAS,EAAY,oBAAqB,EAAU,eAAgB,CAC5E,QAAS,uCAAuC,IACjD,CAAC,EAmBN,eAAe,EAAoB,CACjC,aACA,QACA,cACA,YACA,QACA,cACA,kCACA,gBACuC,CACvC,IAAM,EAAc,EAAM,YAE1B,GAAI,CAAC,EAAU,EAAY,CACzB,MAAM,IAAI,EAAS,EAAY,eAAgB,EAAU,eAAgB,CACvE,QAAS,0CACV,CAAC,CAGJ,IAAM,EAAe,EAA+B,CAClD,UAAW,EAAM,UACjB,SAAU,EAAM,SAChB,YAAa,EAAM,YACpB,CAAC,CAEI,EAAe,EAAqB,CAAE,MAAO,EAAM,YAAa,CAAC,CAEjE,EAAuB,EAAqB,EAAM,QAAS,EAAM,YAAY,QAAQ,CACrF,EAAwB,EAAqB,EAAM,SAAU,EAAM,YAAY,QAAQ,CAE7F,GAAI,CAAC,EAAU,EAAqB,CAClC,MAAM,IAAI,EAAS,EAAY,eAAgB,EAAU,eAAgB,CACvE,QAAS,8CACV,CAAC,CAGJ,IAAM,EAAiB,EACjB,EAAkB,EAAqB,EAAe,CACtD,EAAmB,EAAM,YAAY,QAAQ,aAAa,GAAK,EAAM,YAAY,QAAQ,aAAa,CAEtG,CAAE,QAAS,GAAmB,MAAM,EAAuB,EAAY,CAC3E,QAAS,EAAqB,EAAM,YAAY,QAAQ,CACxD,eAAgB,EAChB,QAAS,EAAM,GAChB,CAAC,CAEF,GAAI,CAAC,GAAmB,CAAC,EACvB,MAAM,IAAI,EAAS,EAAY,oBAAqB,EAAU,eAAgB,CAC5E,QAAS,kDAAkD,EAAM,YAAY,QAAQ,GACtF,CAAC,CAGJ,IAAI,EAA4B,GAC5B,EAEJ,GAAI,CAAC,GAAmB,GACJ,MAAM,EAAa,aAAa,CAChD,QAAS,EACT,IAAK,EACL,aAAc,YACd,KAAM,CAAC,EAAa,EAAe,CACpC,CAAC,CAEc,EAAM,SAAU,CAC9B,EAA4B,GAE5B,IAAM,EAAe,EAAmB,CACtC,IAAK,EACL,aAAc,UACd,KAAM,CAAC,EAAgB,EAAM,SAAS,CACvC,CAAC,CAEE,EAEJ,GAAI,CAQF,EAAwB,EAPI,MAAM,EAAa,YAAY,CACzD,QAAS,EACT,GAAI,EACJ,KAAM,EACN,MAAO,GACR,CAAC,CAEkE,GAAa,qBAAqB,OAC/F,EAAK,CACZ,MAAM,IAAI,EAAS,8BAA+B,EAAU,WAAY,CACtE,MAAO,EACP,QAAS,yDACV,CAAC,CAGJ,EAAkB,CAChB,QAAS,EAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EACN,KAAM,EACN,IAAK,EACL,GAAI,EACJ,MAAO,GACP,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAIL,IAAM,EAAqB,EAAwB,CACjD,kBACA,4BACA,UAAW,EAAU,UACrB,cAAe,EAAM,YAAY,QACjC,cAAe,EAAM,YAAY,QAClC,CAAC,CAEI,EAAO,MAAM,EAAU,EAAY,CACvC,SAAU,EAAM,SAAS,UAAU,CACnC,QACA,aAAc,EAAa,UAAU,CACrC,QAAS,EACT,SAAU,EACV,KAAM,EAAM,GACb,CAAC,CAEF,GAAI,CAAC,EAAkB,EAAK,CAC1B,MAAM,IAAI,EAAS,EAAY,oBAAqB,EAAU,eAAgB,CAC5E,QAAS,qGACV,CAAC,CAGJ,IAAM,GAAuB,EAAuB,EAAsB,KAAK,KAAK,GAAe,CACjG,IAAM,EAAsB,EAAM,YAAY,UAAY,EAAM,YAAY,QAE5E,MAAO,CACL,SAAU,EAAM,SAChB,UAAW,EAAM,UACjB,cACA,KAAM,EAAM,KACZ,YAAa,EAAM,YACnB,GAAI,EAAM,GACV,cAAe,EAAM,cACrB,YAAa,EAAM,QACnB,YAAa,EAAM,YACnB,OAAQ,iBACR,YAAa,EAAM,SACnB,YAAa,EAAM,YACnB,UAAW,EAAM,UACjB,KAAM,EAAY,MAClB,OAAQ,CACN,kBAAmB,EACnB,0BAA2B,EAAsB,EAAI,EACrD,cACA,SACD,CACF,EAGH,GAAI,GAAsB,EAAiB,CACzC,IAAM,EAAiC,CACrC,iBAAkB,EAClB,uBAAwB,EAAwB,eAChD,QACA,mBAAoB,EACrB,CAEK,EAAY,EAAU,UAE5B,GAAI,CAAC,EACH,MAAM,IAAI,EAAS,2CAA4C,EAAU,eAAe,CAG1F,IAAM,EAAqC,CACzC,QAAS,EAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EAAK,KACX,KAAM,EAIN,IAAK,IAAA,GACL,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAED,IAAe,EAAU,CAEzB,GAAI,CAOF,IAAM,GANW,MAAM,EACrB,CAAC,EAAiB,EAAY,CAC9B,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,EAE2B,GAAG,GAAG,CAElC,GAAI,CAAC,EACH,MAAM,IAAI,EAAS,0DAA2D,EAAU,eAAe,CAGzG,OAAO,EAAoB,EAAW,OAC/B,EAAO,CACd,GAAI,CAAC,EACH,MAAM,GAKZ,GAAI,GAA6B,EAAiB,CAChD,IAAM,EAAoC,CACxC,iBAAkB,EAClB,uBAAwB,EAAwB,kBAChD,QACA,mBAAoB,EACrB,CAED,IAAe,EAAa,CAE5B,IAAM,EAAiB,MAAM,EAAU,KACrC,EACA,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,CAID,IAFwB,MAAM,EAAa,0BAA0B,CAAE,KAAM,EAAgB,CAAC,EAE1E,SAAW,WAC7B,OAAO,EAA4B,EAAO,CACxC,cACA,UAAW,EAAU,qBACrB,YAAa,0CACd,CAAC,CAIN,IAAM,EAAoB,MAAM,EAA6B,CAC3D,WAAY,EACZ,cACA,kBAAmB,GAAa,qBAChC,eACA,OACD,CAAC,CAEI,EAAqC,CACzC,QAAS,EAAwB,EAAM,YAAY,QAAQ,CAC3D,KAAM,EAAK,KACX,KAAM,EACN,IAAK,EACL,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,GAAI,GAAa,eAAiB,IAAA,GAK9B,KAJA,CACE,aAAc,EAAY,aAC1B,qBAAsB,EAAY,qBACnC,CAEN,CAEK,EAA4B,CAChC,iBAAkB,EAA4B,EAAI,EAClD,uBAAwB,EAAwB,eAChD,QACA,mBAAoB,EAA4B,EAAI,EACrD,CAED,IAAe,EAAK,CAEpB,IAAM,EAAc,KAAK,KAAK,CAQ9B,OAAO,EANQ,MAAM,EAAU,KAC7B,EACA,KAAO,IAAiB,EAAa,mBAAmB,CAAE,sBAAuB,EAAc,CAAC,CAChG,EACD,CAEkC,EAAY,CAgBjD,eAAe,EAAoB,CACjC,aACA,QACA,cACA,eACA,QACA,gBACuC,CACvC,GAAI,CAAC,EACH,MAAM,IAAI,EAAS,EAAY,eAAgB,EAAU,eAAgB,CACvE,QAAS,sEACV,CAAC,CAGJ,GAAI,CAAC,EAAa,EAAM,YAAY,CAClC,MAAM,IAAI,EAAS,EAAY,eAAgB,EAAU,eAAgB,CACvE,QAAS,6CACV,CAAC,CAGJ,IAAM,EAAe,EAA+B,CAClD,UAAW,EAAM,UACjB,SAAU,EAAM,SAChB,YAAa,EAAM,YACpB,CAAC,CAEI,EAAuB,EAAqB,EAAM,QAAS,EAAM,YAAY,QAAQ,CACrF,EAAwB,EAAqB,EAAM,SAAU,EAAM,YAAY,QAAQ,CAEvF,EAAO,MAAM,EAAU,EAAY,CACvC,SAAU,EAAM,SAAS,UAAU,CACnC,QACA,aAAc,EAAa,UAAU,CACrC,QAAS,EACT,SAAU,EACV,cAAe,EAAM,YACrB,KAAM,EAAM,GACb,CAAC,CAEF,GAAI,CAAC,EAAqB,EAAK,CAC7B,MAAM,IAAI,EAAS,EAAY,oBAAqB,EAAU,eAAgB,CAC5E,QAAS,qGACV,CAAC,CAGJ,IAAM,EAAwB,MAAM,EAClC,EAAK,gBACL,EAAqB,CAAE,MAAO,EAAM,YAAa,CAAC,CACnD,CAEK,EAA4B,CAChC,iBAAkB,EAClB,uBAAwB,EAAwB,eAChD,QACA,mBAAoB,EACrB,CAED,IAAe,EAAK,CAEpB,IAAM,EAAc,KAAK,KAAK,CAExB,EAAS,MAAM,EAAa,YAChC,CACE,QAAS,EAAM,YACf,aAAc,EACf,CACD,EACD,CAEK,EAAmB,EAAM,YAAY,QAAQ,aAAa,GAAK,EAAM,YAAY,QAAQ,aAAa,CAE5G,MAAO,CACL,SAAU,EAAM,SAChB,UAAW,EAAM,UACjB,cACA,KAAM,EAAM,KACZ,YAAa,EAAM,YACnB,GAAI,EAAM,GACV,cAAe,EAAM,cACrB,YAAa,EAAM,QACnB,YAAa,EAAM,YACnB,OAAQ,iBACR,YAAa,EAAM,SACnB,YAAa,EAAM,YACnB,UAAW,EAAM,UACjB,KAAM,EAAY,MAClB,OAAQ,CACN,kBAAmB,EACnB,0BAA2B,EAAmB,EAAI,EAClD,cACA,SACD,CACF,CAQH,SAAS,EAAwB,CAC/B,kBACA,4BACA,YACA,gBACA,iBAOU,CACV,OACE,EAAe,EAAc,EAC7B,EAAe,EAAc,EAC7B,IAAkB,GAClB,GACA,IAAoB,IAAA,IACpB,OAAO,GAAc"}
|
|
1
|
+
{"version":3,"file":"transfer-asset.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { encodeFunctionData, erc20Abi, isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ServiceType, TransferSignatureReason } from '../../../constants';\nimport type { Environment } from '../../../constants';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\nimport type { EvmSigner, EvmTransactionRequest, SolanaSigner } from '../../../types/signer';\nimport type { Transfer, TransferStepDetails } from '../../../types/transfer';\nimport { caip2ToEip155ChainId, caip2ToEip155HexChainId } from '../../../utils/caip';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport {\n applyFeeUnitsBpsMargin,\n getEvmClientForChain,\n getSolanaRpcForChain,\n makeFailedTransferFromQuote,\n} from '../../_utils';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport { assetToAddressString, calculateMarkrMinimumAmountOut, isTokenAddressNative } from '../_utils';\nimport { isEvmSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../_solana-utils';\n\nexport interface TransferAssetFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n solanaSigner?: SolanaSigner;\n}\n\nexport function transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n}: TransferAssetFactoryConfig): TransferService['transferAsset'] {\n return async ({ quote, gasSettings, fallbackToDefaultOnBatchFailure, onStepChange }) => {\n if (quote.serviceType !== ServiceType.MARKR) {\n throw new SdkError(ErrorReason.INCORRECT_PROVIDER_PROVIDED, ErrorCode.INVALID_PARAMS);\n }\n\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n throw new SdkError(ErrorReason.QUOTE_EXPIRED, ErrorCode.INVALID_PARAMS);\n }\n\n const sourceChainId = quote.sourceChain.chainId;\n\n if (isSolanaNamespace(sourceChainId)) {\n return _executeSvmTransfer({ apiOptions, appId, environment, solanaSigner, quote, onStepChange });\n }\n\n if (isEvmNamespace(sourceChainId)) {\n return _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n });\n }\n\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Unsupported source chain namespace: ${sourceChainId}`,\n });\n };\n}\n\n// ---------------------------------------------------------------------------\n// EVM transfer path\n// ---------------------------------------------------------------------------\n\ninterface EvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n gasSettings?: Parameters<TransferService['transferAsset']>[0]['gasSettings'];\n fallbackToDefaultOnBatchFailure?: Parameters<TransferService['transferAsset']>[0]['fallbackToDefaultOnBatchFailure'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeEvmTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n gasSettings,\n fallbackToDefaultOnBatchFailure,\n onStepChange,\n}: EvmTransferParams): Promise<Transfer> {\n const fromAddress = quote.fromAddress;\n\n if (!isAddress(fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid EVM address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const sourceClient = getEvmClientForChain({ chain: quote.sourceChain });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n if (!isAddress(tokenInAddressString)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'assetIn address is not a valid EVM address.',\n });\n }\n\n const tokenInAddress = tokenInAddressString;\n const isTokenInNative = isTokenAddressNative(tokenInAddress);\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n const { address: spenderAddress } = await markrGetSpenderAddress(apiOptions, {\n chainId: caip2ToEip155ChainId(quote.sourceChain.chainId),\n crossChainSwap: isCrossChainSwap,\n quoteId: quote.id,\n });\n\n if (!isTokenInNative && !spenderAddress) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: `Missing Markr spender address for source chain ${quote.sourceChain.chainId}.`,\n });\n }\n\n let requiresApprovalSignature = false;\n let approvalRequest: EvmTransactionRequest | undefined;\n\n if (!isTokenInNative && spenderAddress) {\n const allowance = await sourceClient.readContract({\n address: tokenInAddress,\n abi: erc20Abi,\n functionName: 'allowance',\n args: [fromAddress, spenderAddress],\n });\n\n if (allowance < quote.amountIn) {\n requiresApprovalSignature = true;\n\n const approvalData = encodeFunctionData({\n abi: erc20Abi,\n functionName: 'approve',\n args: [spenderAddress, quote.amountIn],\n });\n\n let approvalGasWithMargin: bigint | undefined;\n\n try {\n const approvalGasEstimate = await sourceClient.estimateGas({\n account: fromAddress,\n to: tokenInAddress,\n data: approvalData,\n value: 0n,\n });\n\n approvalGasWithMargin = applyFeeUnitsBpsMargin(approvalGasEstimate, gasSettings?.estimateGasMarginBps);\n } catch (err) {\n throw new SdkError('Error during gas estimation', ErrorCode.VIEM_ERROR, {\n cause: err,\n details: 'Failed to estimate gas for ERC20 approval transaction.',\n });\n }\n\n approvalRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: approvalData,\n from: fromAddress,\n gas: approvalGasWithMargin,\n to: tokenInAddress,\n value: 0n,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n }\n }\n\n const maybeOneClickBatch = isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch: evmSigner.signBatch,\n sourceChainId: quote.sourceChain.chainId,\n targetChainId: quote.targetChain.chainId,\n });\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n uuid: quote.id,\n });\n\n if (!isEvmSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-EVM swap response from Markr, but only EVM swaps are supported for this source chain.',\n });\n }\n\n const makePendingTransfer = (txHash: `0x${string}`, startedAtMs: number = Date.now()): Transfer => {\n const isSameChainTransfer = quote.sourceChain.chainId === quote.targetChain.chainId;\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isSameChainTransfer ? 1 : 2,\n startedAtMs,\n txHash,\n },\n };\n };\n\n if (maybeOneClickBatch && approvalRequest) {\n const batchStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n const signBatch = evmSigner.signBatch;\n\n if (!signBatch) {\n throw new SdkError('One-click batch signer is not available.', ErrorCode.SIGNING_FAILED);\n }\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n // Gas is purposely left undefined here.\n // We can't estimate the gas because we aren't executing the\n // approval tx. It's up to the wallet to correctly handle gas estimation.\n gas: undefined,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n onStepChange?.(batchStep);\n\n try {\n const txHashes = await signBatch(\n [approvalRequest, swapRequest],\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n batchStep,\n );\n\n const swapTxHash = txHashes.at(-1);\n\n if (!swapTxHash) {\n throw new SdkError('One-click batch signing returned no transaction hashes.', ErrorCode.SIGNING_FAILED);\n }\n\n return makePendingTransfer(swapTxHash);\n } catch (error) {\n if (!fallbackToDefaultOnBatchFailure) {\n throw error;\n }\n }\n }\n\n if (requiresApprovalSignature && approvalRequest) {\n const approvalStep: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n };\n\n onStepChange?.(approvalStep);\n\n const approvalTxHash = await evmSigner.sign(\n approvalRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n approvalStep,\n );\n\n const approvalReceipt = await sourceClient.waitForTransactionReceipt({ hash: approvalTxHash });\n\n if (approvalReceipt.status === 'reverted') {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n }\n\n const swapGasWithMargin = await _estimateGasFromSwapResponse({\n crossChain: isCrossChainSwap,\n fromAddress,\n feeUnitsMarginBps: gasSettings?.estimateGasMarginBps,\n sourceClient,\n swap,\n });\n\n const swapRequest: EvmTransactionRequest = {\n chainId: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n data: swap.data,\n from: fromAddress,\n gas: swapGasWithMargin,\n to: swap.to,\n value: swap.value,\n ...(gasSettings?.maxFeePerGas !== undefined\n ? {\n maxFeePerGas: gasSettings.maxFeePerGas,\n maxPriorityFeePerGas: gasSettings.maxPriorityFeePerGas,\n }\n : null),\n };\n\n const step: TransferStepDetails = {\n currentSignature: requiresApprovalSignature ? 2 : 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: requiresApprovalSignature ? 2 : 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await evmSigner.sign(\n swapRequest,\n async (signedTxHash) => sourceClient.sendRawTransaction({ serializedTransaction: signedTxHash }),\n step,\n );\n\n return makePendingTransfer(txHash, startedAtMs);\n}\n\n// ---------------------------------------------------------------------------\n// SVM (Solana) transfer path\n// ---------------------------------------------------------------------------\n\ninterface SvmTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n solanaSigner?: SolanaSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeSvmTransfer({\n apiOptions,\n appId,\n environment,\n solanaSigner,\n quote,\n onStepChange,\n}: SvmTransferParams): Promise<Transfer> {\n if (!solanaSigner) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'solanaSigner is required for Solana transfers but was not provided.',\n });\n }\n\n if (!isSolAddress(quote.fromAddress)) {\n throw new SdkError(ErrorReason.INVALID_PARAMS, ErrorCode.INVALID_PARAMS, {\n details: 'fromAddress is not a valid Solana address.',\n });\n }\n\n const minAmountOut = calculateMarkrMinimumAmountOut({\n amountOut: quote.amountOut,\n assetOut: quote.assetOut,\n slippageBps: quote.slippageBps,\n });\n\n const tokenInAddressString = assetToAddressString(quote.assetIn, quote.sourceChain.chainId);\n const tokenOutAddressString = assetToAddressString(quote.assetOut, quote.targetChain.chainId);\n\n const swap = await markrSwap(apiOptions, {\n amountIn: quote.amountIn.toString(),\n appId,\n minAmountOut: minAmountOut.toString(),\n tokenIn: tokenInAddressString,\n tokenOut: tokenOutAddressString,\n userPublicKey: quote.fromAddress,\n uuid: quote.id,\n });\n\n if (!isSolanaSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details: 'Received non-SVM swap response from Markr, but only SVM swaps are supported for this source chain.',\n });\n }\n\n // TODO: Cleanup\n console.debug('[Fusion SDK] Original swap transaction (base64):', swap.swapTransaction);\n\n const swapTransactionBase64 = await refreshSolanaSwapTransactionBlockhash(\n swap.swapTransaction,\n getSolanaRpcForChain({ chain: quote.sourceChain }),\n );\n\n // TODO: Cleanup\n console.debug('[Fusion SDK] Refreshed swap transaction with new blockhash (base64):', swapTransactionBase64);\n\n const step: TransferStepDetails = {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures: 1,\n };\n\n onStepChange?.(step);\n\n const startedAtMs = Date.now();\n\n const txHash = await solanaSigner.signAndSend(\n {\n account: quote.fromAddress,\n serializedTx: swapTransactionBase64,\n },\n step,\n );\n\n const isCrossChainSwap = quote.sourceChain.chainId.toLowerCase() !== quote.targetChain.chainId.toLowerCase();\n\n return {\n amountIn: quote.amountIn,\n amountOut: quote.amountOut,\n environment,\n fees: quote.fees,\n fromAddress: quote.fromAddress,\n id: quote.id,\n partnerFeeBps: quote.partnerFeeBps,\n sourceAsset: quote.assetIn,\n sourceChain: quote.sourceChain,\n status: 'source-pending',\n targetAsset: quote.assetOut,\n targetChain: quote.targetChain,\n toAddress: quote.toAddress,\n type: ServiceType.MARKR,\n source: {\n confirmationCount: 0,\n requiredConfirmationCount: isCrossChainSwap ? 2 : SOLANA_REQUIRED_CONFIRMATIONS,\n startedAtMs,\n txHash,\n },\n };\n}\n\n/**\n * Determines whether one-click swap eligibility criteria is met.\n *\n * Only same-chain EVM swaps are currently eligible.\n */\nfunction isOneClickBatchEligible({\n approvalRequest,\n requiresApprovalSignature,\n signBatch,\n sourceChainId,\n targetChainId,\n}: {\n approvalRequest?: EvmTransactionRequest;\n requiresApprovalSignature: boolean;\n signBatch?: EvmSigner['signBatch'];\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n}): boolean {\n return (\n isEvmNamespace(sourceChainId) &&\n isEvmNamespace(targetChainId) &&\n sourceChainId === targetChainId &&\n requiresApprovalSignature &&\n approvalRequest !== undefined &&\n typeof signBatch === 'function'\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e={fast:2e3,medium:5e3,slow:3e4,verySlow:18e4},t={fast:6e4,medium:20*6e4,slow:120*6e4},n={apechain:50*6e4,arbitrum:17*6e4,astar:35e3,avalanche:1e3,base:18*6e4,berachain:7e3,bitlayer:6e4,blast:20*6e4,bnbchain:5e3,bob:120*6e4,bsquared:20*6e4,celo:1e3,core:6e4,corn:720*6e4,cronos:1e3,cronoszkevm:1860*6e4,ethereum:15*6e4,fraxtal:30*6e4,gnosis:3*6e4,hashkey:60*6e4,ink:120*6e4,kroma:25*6e4,linea:20*6e4,mantle:28*6e4,metis:120*6e4,mindnetwork:60*6e4,mode:37*6e4,monad:48e3,opmainnet:20*6e4,polygon:17*6e4,polygonzkevm:120*6e4,ronin:1e4,scroll:60*6e4,sei:1e3,shibarium:6e4,solana:1e3,sonic:7e3,soneium:27*6e4,treasure:420*6e4,unichain:24*6e4,wemix:1e3,worldchain:40*6e4,xlayer:60*6e4,zircuit:21*6e4,zksync:20*6e4},r={"eip155:1":`ethereum`,"eip155:10":`opmainnet`,"eip155:25":`cronos`,"eip155:56":`bnbchain`,"eip155:100":`gnosis`,"eip155:137":`polygon`,"eip155:324":`zksync`,"eip155:1101":`polygonzkevm`,"eip155:1116":`core`,"eip155:1329":`sei`,"eip155:196":`xlayer`,"eip155:252":`fraxtal`,"eip155:480":`worldchain`,"eip155:59144":`linea`,"eip155:8453":`base`,"eip155:1088":`metis`,"eip155:2020":`ronin`,"eip155:42220":`celo`,"eip155:43114":`avalanche`,"eip155:48900":`zircuit`,"eip155:5000":`mantle`,"eip155:534352":`scroll`,"eip155:42161":`arbitrum`,"eip155:81457":`blast`,"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp":`solana`},i=[{aliases:[`apechain`],chainKey:`apechain`},{aliases:[`arbitrum`],chainKey:`arbitrum`},{aliases:[`astar`],chainKey:`astar`},{aliases:[`avalanche`],chainKey:`avalanche`},{aliases:[`base`],chainKey:`base`},{aliases:[`berachain`],chainKey:`berachain`},{aliases:[`bitlayer`],chainKey:`bitlayer`},{aliases:[`blast`],chainKey:`blast`},{aliases:[`bnbchain`,`bnbsmartchain`,`binancesmartchain`,`binancechain`],chainKey:`bnbchain`},{aliases:[`bob`],chainKey:`bob`},{aliases:[`b2`,`bsquared`],chainKey:`bsquared`},{aliases:[`celo`],chainKey:`celo`},{aliases:[`core`],chainKey:`core`},{aliases:[`corn`],chainKey:`corn`},{aliases:[`cronoszkevm`],chainKey:`cronoszkevm`},{aliases:[`cronos`],chainKey:`cronos`},{aliases:[`ethereum`],chainKey:`ethereum`},{aliases:[`fraxtal`],chainKey:`fraxtal`},{aliases:[`gnosis`],chainKey:`gnosis`},{aliases:[`hashkey`],chainKey:`hashkey`},{aliases:[`ink`],chainKey:`ink`},{aliases:[`kroma`],chainKey:`kroma`},{aliases:[`linea`],chainKey:`linea`},{aliases:[`mantle`],chainKey:`mantle`},{aliases:[`metis`],chainKey:`metis`},{aliases:[`mindnetwork`],chainKey:`mindnetwork`},{aliases:[`mode`],chainKey:`mode`},{aliases:[`monad`],chainKey:`monad`},{aliases:[`opmainnet`,`optimism`],chainKey:`opmainnet`},{aliases:[`polygonzkevm`],chainKey:`polygonzkevm`},{aliases:[`polygon`],chainKey:`polygon`},{aliases:[`ronin`],chainKey:`ronin`},{aliases:[`scroll`],chainKey:`scroll`},{aliases:[`sei`],chainKey:`sei`},{aliases:[`solana`],chainKey:`solana`},{aliases:[`soneium`],chainKey:`soneium`},{aliases:[`sonic`],chainKey:`sonic`},{aliases:[`shibarium`],chainKey:`shibarium`},{aliases:[`treasure`],chainKey:`treasure`},{aliases:[`unichain`],chainKey:`unichain`},{aliases:[`wemix`],chainKey:`wemix`},{aliases:[`worldchain`],chainKey:`worldchain`},{aliases:[`xlayer`],chainKey:`xlayer`},{aliases:[`zircuit`],chainKey:`zircuit`},{aliases:[`zksync`],chainKey:`zksync`}],a={...Object.fromEntries(Object.entries(r).map(([e,t])=>[e,n[t]]))},o=[...i.map(({aliases:e,chainKey:t})=>({aliases:e,finalityMs:n[t]}))];exports.CROSS_CHAIN_POLLING_INTERVAL_MS=e,exports.DEFAULT_MARKR_API_URL=`https://proxy-api.avax.network/proxy/markr`,exports.FINALITY_MS_BY_CHAIN_ID=a,exports.FINALITY_MS_BY_CHAIN_NAME_ALIAS=o,exports.FINALITY_TIER_MAX_FINALITY_MS=t,exports.SOLANA_POLLING_INTERVAL_MS=2500,exports.SOLANA_REQUIRED_CONFIRMATIONS=32,exports.SOLANA_TX_TIMEOUT_MS=12e4;
|
|
1
|
+
const e={fast:2e3,medium:5e3,slow:3e4,verySlow:18e4},t={fast:6e4,medium:20*6e4,slow:120*6e4},n={apechain:50*6e4,arbitrum:17*6e4,astar:35e3,avalanche:1e3,base:18*6e4,berachain:7e3,bitlayer:6e4,blast:20*6e4,bnbchain:5e3,bob:120*6e4,bsquared:20*6e4,celo:1e3,core:6e4,corn:720*6e4,cronos:1e3,cronoszkevm:1860*6e4,ethereum:15*6e4,fraxtal:30*6e4,gnosis:3*6e4,hashkey:60*6e4,ink:120*6e4,kroma:25*6e4,linea:20*6e4,mantle:28*6e4,metis:120*6e4,mindnetwork:60*6e4,mode:37*6e4,monad:48e3,opmainnet:20*6e4,polygon:17*6e4,polygonzkevm:120*6e4,ronin:1e4,scroll:60*6e4,sei:1e3,shibarium:6e4,solana:1e3,sonic:7e3,soneium:27*6e4,treasure:420*6e4,unichain:24*6e4,wemix:1e3,worldchain:40*6e4,xlayer:60*6e4,zircuit:21*6e4,zksync:20*6e4},r={"eip155:1":`ethereum`,"eip155:10":`opmainnet`,"eip155:25":`cronos`,"eip155:56":`bnbchain`,"eip155:100":`gnosis`,"eip155:137":`polygon`,"eip155:324":`zksync`,"eip155:1101":`polygonzkevm`,"eip155:1116":`core`,"eip155:1329":`sei`,"eip155:196":`xlayer`,"eip155:252":`fraxtal`,"eip155:480":`worldchain`,"eip155:59144":`linea`,"eip155:8453":`base`,"eip155:1088":`metis`,"eip155:2020":`ronin`,"eip155:42220":`celo`,"eip155:43114":`avalanche`,"eip155:48900":`zircuit`,"eip155:5000":`mantle`,"eip155:534352":`scroll`,"eip155:42161":`arbitrum`,"eip155:81457":`blast`,"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp":`solana`},i=[{aliases:[`apechain`],chainKey:`apechain`},{aliases:[`arbitrum`],chainKey:`arbitrum`},{aliases:[`astar`],chainKey:`astar`},{aliases:[`avalanche`],chainKey:`avalanche`},{aliases:[`base`],chainKey:`base`},{aliases:[`berachain`],chainKey:`berachain`},{aliases:[`bitlayer`],chainKey:`bitlayer`},{aliases:[`blast`],chainKey:`blast`},{aliases:[`bnbchain`,`bnbsmartchain`,`binancesmartchain`,`binancechain`],chainKey:`bnbchain`},{aliases:[`bob`],chainKey:`bob`},{aliases:[`b2`,`bsquared`],chainKey:`bsquared`},{aliases:[`celo`],chainKey:`celo`},{aliases:[`core`],chainKey:`core`},{aliases:[`corn`],chainKey:`corn`},{aliases:[`cronoszkevm`],chainKey:`cronoszkevm`},{aliases:[`cronos`],chainKey:`cronos`},{aliases:[`ethereum`],chainKey:`ethereum`},{aliases:[`fraxtal`],chainKey:`fraxtal`},{aliases:[`gnosis`],chainKey:`gnosis`},{aliases:[`hashkey`],chainKey:`hashkey`},{aliases:[`ink`],chainKey:`ink`},{aliases:[`kroma`],chainKey:`kroma`},{aliases:[`linea`],chainKey:`linea`},{aliases:[`mantle`],chainKey:`mantle`},{aliases:[`metis`],chainKey:`metis`},{aliases:[`mindnetwork`],chainKey:`mindnetwork`},{aliases:[`mode`],chainKey:`mode`},{aliases:[`monad`],chainKey:`monad`},{aliases:[`opmainnet`,`optimism`],chainKey:`opmainnet`},{aliases:[`polygonzkevm`],chainKey:`polygonzkevm`},{aliases:[`polygon`],chainKey:`polygon`},{aliases:[`ronin`],chainKey:`ronin`},{aliases:[`scroll`],chainKey:`scroll`},{aliases:[`sei`],chainKey:`sei`},{aliases:[`solana`],chainKey:`solana`},{aliases:[`soneium`],chainKey:`soneium`},{aliases:[`sonic`],chainKey:`sonic`},{aliases:[`shibarium`],chainKey:`shibarium`},{aliases:[`treasure`],chainKey:`treasure`},{aliases:[`unichain`],chainKey:`unichain`},{aliases:[`wemix`],chainKey:`wemix`},{aliases:[`worldchain`],chainKey:`worldchain`},{aliases:[`xlayer`],chainKey:`xlayer`},{aliases:[`zircuit`],chainKey:`zircuit`},{aliases:[`zksync`],chainKey:`zksync`}],a={...Object.fromEntries(Object.entries(r).map(([e,t])=>[e,n[t]]))},o=[...i.map(({aliases:e,chainKey:t})=>({aliases:e,finalityMs:n[t]}))];exports.CROSS_CHAIN_POLLING_INTERVAL_MS=e,exports.DEFAULT_MARKR_API_URL=`https://proxy-api.avax.network/proxy/markr-helium`,exports.FINALITY_MS_BY_CHAIN_ID=a,exports.FINALITY_MS_BY_CHAIN_NAME_ALIAS=o,exports.FINALITY_TIER_MAX_FINALITY_MS=t,exports.SOLANA_POLLING_INTERVAL_MS=2500,exports.SOLANA_REQUIRED_CONFIRMATIONS=32,exports.SOLANA_TX_TIMEOUT_MS=12e4;
|
|
2
2
|
//# sourceMappingURL=constants.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/transfer-service/markr/constants.ts"],"sourcesContent":["import type { Caip2ChainId } from '../../types/caip';\n\nexport const DEFAULT_MARKR_API_URL = 'https://proxy-api.avax.network/proxy/markr' as const;\n\n/**\n * Cross-chain polling tiers used by Markr transfer tracking.\n *\n * Tier boundaries are selected from known destination/source finality windows\n * so we poll fast-finality chains more aggressively and avoid excessive RPC\n * traffic on slow-finality chains.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const CROSS_CHAIN_POLLING_INTERVAL_MS = {\n fast: 2_000, // 2 seconds\n medium: 5_000, // 5 seconds\n slow: 30_000, // 30 seconds\n verySlow: 180_000, // 3 minutes\n} as const;\n\n/**\n * Upper bounds (in ms) used to map known finality time to a polling tier.\n *\n * Values greater than `slow` are classified as `verySlow`.\n */\nexport const FINALITY_TIER_MAX_FINALITY_MS: Readonly<Record<'fast' | 'medium' | 'slow', number>> = {\n fast: 60_000,\n medium: 20 * 60_000,\n slow: 2 * 60 * 60_000,\n};\n\nconst FINALITY_MS_BY_CHAIN_KEY = {\n apechain: 50 * 60_000,\n arbitrum: 17 * 60_000,\n astar: 35_000,\n avalanche: 1_000,\n base: 18 * 60_000,\n berachain: 7_000,\n bitlayer: 60_000,\n blast: 20 * 60_000,\n bnbchain: 5_000,\n bob: 2 * 60 * 60_000,\n bsquared: 20 * 60_000,\n celo: 1_000,\n core: 60_000,\n corn: 12 * 60 * 60_000,\n cronos: 1_000,\n cronoszkevm: 31 * 60 * 60_000,\n ethereum: 15 * 60_000,\n fraxtal: 30 * 60_000,\n gnosis: 3 * 60_000,\n hashkey: 60 * 60_000,\n ink: 2 * 60 * 60_000,\n kroma: 25 * 60_000,\n linea: 20 * 60_000,\n mantle: 28 * 60_000,\n metis: 2 * 60 * 60_000,\n mindnetwork: 60 * 60_000,\n mode: 37 * 60_000,\n monad: 48_000,\n opmainnet: 20 * 60_000,\n polygon: 17 * 60_000,\n polygonzkevm: 2 * 60 * 60_000,\n ronin: 10_000,\n scroll: 60 * 60_000,\n sei: 1_000,\n shibarium: 60_000,\n solana: 1_000,\n sonic: 7_000,\n soneium: 27 * 60_000,\n treasure: 7 * 60 * 60_000,\n unichain: 24 * 60_000,\n wemix: 1_000,\n worldchain: 40 * 60_000,\n xlayer: 60 * 60_000,\n zircuit: 21 * 60_000,\n zksync: 20 * 60_000,\n} as const;\n\ntype FinalityChainKey = keyof typeof FINALITY_MS_BY_CHAIN_KEY;\n\nconst FINALITY_CHAIN_KEY_BY_CHAIN_ID = {\n 'eip155:1': 'ethereum',\n 'eip155:10': 'opmainnet',\n 'eip155:25': 'cronos',\n 'eip155:56': 'bnbchain',\n 'eip155:100': 'gnosis',\n 'eip155:137': 'polygon',\n 'eip155:324': 'zksync',\n 'eip155:1101': 'polygonzkevm',\n 'eip155:1116': 'core',\n 'eip155:1329': 'sei',\n 'eip155:196': 'xlayer',\n 'eip155:252': 'fraxtal',\n 'eip155:480': 'worldchain',\n 'eip155:59144': 'linea',\n 'eip155:8453': 'base',\n 'eip155:1088': 'metis',\n 'eip155:2020': 'ronin',\n 'eip155:42220': 'celo',\n 'eip155:43114': 'avalanche',\n 'eip155:48900': 'zircuit',\n 'eip155:5000': 'mantle',\n 'eip155:534352': 'scroll',\n 'eip155:42161': 'arbitrum',\n 'eip155:81457': 'blast',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana',\n} as const satisfies Partial<Record<Caip2ChainId, FinalityChainKey>>;\n\nconst FINALITY_CHAIN_NAME_ALIASES = [\n { aliases: ['apechain'], chainKey: 'apechain' },\n { aliases: ['arbitrum'], chainKey: 'arbitrum' },\n { aliases: ['astar'], chainKey: 'astar' },\n { aliases: ['avalanche'], chainKey: 'avalanche' },\n { aliases: ['base'], chainKey: 'base' },\n { aliases: ['berachain'], chainKey: 'berachain' },\n { aliases: ['bitlayer'], chainKey: 'bitlayer' },\n { aliases: ['blast'], chainKey: 'blast' },\n { aliases: ['bnbchain', 'bnbsmartchain', 'binancesmartchain', 'binancechain'], chainKey: 'bnbchain' },\n { aliases: ['bob'], chainKey: 'bob' },\n { aliases: ['b2', 'bsquared'], chainKey: 'bsquared' },\n { aliases: ['celo'], chainKey: 'celo' },\n { aliases: ['core'], chainKey: 'core' },\n { aliases: ['corn'], chainKey: 'corn' },\n { aliases: ['cronoszkevm'], chainKey: 'cronoszkevm' },\n { aliases: ['cronos'], chainKey: 'cronos' },\n { aliases: ['ethereum'], chainKey: 'ethereum' },\n { aliases: ['fraxtal'], chainKey: 'fraxtal' },\n { aliases: ['gnosis'], chainKey: 'gnosis' },\n { aliases: ['hashkey'], chainKey: 'hashkey' },\n { aliases: ['ink'], chainKey: 'ink' },\n { aliases: ['kroma'], chainKey: 'kroma' },\n { aliases: ['linea'], chainKey: 'linea' },\n { aliases: ['mantle'], chainKey: 'mantle' },\n { aliases: ['metis'], chainKey: 'metis' },\n { aliases: ['mindnetwork'], chainKey: 'mindnetwork' },\n { aliases: ['mode'], chainKey: 'mode' },\n { aliases: ['monad'], chainKey: 'monad' },\n { aliases: ['opmainnet', 'optimism'], chainKey: 'opmainnet' },\n { aliases: ['polygonzkevm'], chainKey: 'polygonzkevm' },\n { aliases: ['polygon'], chainKey: 'polygon' },\n { aliases: ['ronin'], chainKey: 'ronin' },\n { aliases: ['scroll'], chainKey: 'scroll' },\n { aliases: ['sei'], chainKey: 'sei' },\n { aliases: ['solana'], chainKey: 'solana' },\n { aliases: ['soneium'], chainKey: 'soneium' },\n { aliases: ['sonic'], chainKey: 'sonic' },\n { aliases: ['shibarium'], chainKey: 'shibarium' },\n { aliases: ['treasure'], chainKey: 'treasure' },\n { aliases: ['unichain'], chainKey: 'unichain' },\n { aliases: ['wemix'], chainKey: 'wemix' },\n { aliases: ['worldchain'], chainKey: 'worldchain' },\n { aliases: ['xlayer'], chainKey: 'xlayer' },\n { aliases: ['zircuit'], chainKey: 'zircuit' },\n { aliases: ['zksync'], chainKey: 'zksync' },\n] as const satisfies ReadonlyArray<{ aliases: readonly string[]; chainKey: FinalityChainKey }>;\n\n/**\n * Known CAIP-2 chain IDs and their approximate CCIP finality times in\n * milliseconds.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_ID: Partial<Record<Caip2ChainId, number>> = {\n ...Object.fromEntries(\n Object.entries(FINALITY_CHAIN_KEY_BY_CHAIN_ID).map(([chainId, chainKey]) => [\n chainId,\n FINALITY_MS_BY_CHAIN_KEY[chainKey],\n ]),\n ),\n};\n\n/**\n * Chain-name aliases and their approximate CCIP finality times in\n * milliseconds.\n *\n * These aliases are used as a fallback when a chain ID is not present in\n * `FINALITY_MS_BY_CHAIN_ID`.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_NAME_ALIAS: ReadonlyArray<{ aliases: readonly string[]; finalityMs: number }> = [\n ...FINALITY_CHAIN_NAME_ALIASES.map(({ aliases, chainKey }) => ({\n aliases,\n finalityMs: FINALITY_MS_BY_CHAIN_KEY[chainKey],\n })),\n];\n\n// Solana slot time is ~400ms. Polling every 2.5s (~6 slots) balances\n// responsiveness against RPC rate-limits — fast enough to detect finalization\n// promptly, without hammering the endpoint.\nexport const SOLANA_POLLING_INTERVAL_MS = 2_500;\n\n// A Solana blockhash is valid for 150 slots (~60s at 400ms/slot). Validators\n// may hold a transaction for up to ~90s before dropping it. We set a 120s\n// timeout to provide a comfortable buffer above worst-case blockhash expiry,\n// ensuring we don't falsely time out a transaction that is still eligible for\n// inclusion in a block.\nexport const SOLANA_TX_TIMEOUT_MS = 120_000;\n\n// Solana finalizes a block once ≥31 confirmed blocks are built on top of it.\n// `getSignatureStatuses` returns the running `confirmations` count (0 → N),\n// then `null` once the status flips to `finalized`. We use 32 as the\n// required-confirmation target so the progress bar fills smoothly from 0 → 31\n// during polling and snaps to 32 (= done) only when finalization is confirmed.\nexport const SOLANA_REQUIRED_CONFIRMATIONS = 32;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"constants.cjs","names":[],"sources":["../../../src/transfer-service/markr/constants.ts"],"sourcesContent":["import type { Caip2ChainId } from '../../types/caip';\n\nexport const DEFAULT_MARKR_API_URL = 'https://proxy-api.avax.network/proxy/markr-helium' as const;\n\n/**\n * Cross-chain polling tiers used by Markr transfer tracking.\n *\n * Tier boundaries are selected from known destination/source finality windows\n * so we poll fast-finality chains more aggressively and avoid excessive RPC\n * traffic on slow-finality chains.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const CROSS_CHAIN_POLLING_INTERVAL_MS = {\n fast: 2_000, // 2 seconds\n medium: 5_000, // 5 seconds\n slow: 30_000, // 30 seconds\n verySlow: 180_000, // 3 minutes\n} as const;\n\n/**\n * Upper bounds (in ms) used to map known finality time to a polling tier.\n *\n * Values greater than `slow` are classified as `verySlow`.\n */\nexport const FINALITY_TIER_MAX_FINALITY_MS: Readonly<Record<'fast' | 'medium' | 'slow', number>> = {\n fast: 60_000,\n medium: 20 * 60_000,\n slow: 2 * 60 * 60_000,\n};\n\nconst FINALITY_MS_BY_CHAIN_KEY = {\n apechain: 50 * 60_000,\n arbitrum: 17 * 60_000,\n astar: 35_000,\n avalanche: 1_000,\n base: 18 * 60_000,\n berachain: 7_000,\n bitlayer: 60_000,\n blast: 20 * 60_000,\n bnbchain: 5_000,\n bob: 2 * 60 * 60_000,\n bsquared: 20 * 60_000,\n celo: 1_000,\n core: 60_000,\n corn: 12 * 60 * 60_000,\n cronos: 1_000,\n cronoszkevm: 31 * 60 * 60_000,\n ethereum: 15 * 60_000,\n fraxtal: 30 * 60_000,\n gnosis: 3 * 60_000,\n hashkey: 60 * 60_000,\n ink: 2 * 60 * 60_000,\n kroma: 25 * 60_000,\n linea: 20 * 60_000,\n mantle: 28 * 60_000,\n metis: 2 * 60 * 60_000,\n mindnetwork: 60 * 60_000,\n mode: 37 * 60_000,\n monad: 48_000,\n opmainnet: 20 * 60_000,\n polygon: 17 * 60_000,\n polygonzkevm: 2 * 60 * 60_000,\n ronin: 10_000,\n scroll: 60 * 60_000,\n sei: 1_000,\n shibarium: 60_000,\n solana: 1_000,\n sonic: 7_000,\n soneium: 27 * 60_000,\n treasure: 7 * 60 * 60_000,\n unichain: 24 * 60_000,\n wemix: 1_000,\n worldchain: 40 * 60_000,\n xlayer: 60 * 60_000,\n zircuit: 21 * 60_000,\n zksync: 20 * 60_000,\n} as const;\n\ntype FinalityChainKey = keyof typeof FINALITY_MS_BY_CHAIN_KEY;\n\nconst FINALITY_CHAIN_KEY_BY_CHAIN_ID = {\n 'eip155:1': 'ethereum',\n 'eip155:10': 'opmainnet',\n 'eip155:25': 'cronos',\n 'eip155:56': 'bnbchain',\n 'eip155:100': 'gnosis',\n 'eip155:137': 'polygon',\n 'eip155:324': 'zksync',\n 'eip155:1101': 'polygonzkevm',\n 'eip155:1116': 'core',\n 'eip155:1329': 'sei',\n 'eip155:196': 'xlayer',\n 'eip155:252': 'fraxtal',\n 'eip155:480': 'worldchain',\n 'eip155:59144': 'linea',\n 'eip155:8453': 'base',\n 'eip155:1088': 'metis',\n 'eip155:2020': 'ronin',\n 'eip155:42220': 'celo',\n 'eip155:43114': 'avalanche',\n 'eip155:48900': 'zircuit',\n 'eip155:5000': 'mantle',\n 'eip155:534352': 'scroll',\n 'eip155:42161': 'arbitrum',\n 'eip155:81457': 'blast',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana',\n} as const satisfies Partial<Record<Caip2ChainId, FinalityChainKey>>;\n\nconst FINALITY_CHAIN_NAME_ALIASES = [\n { aliases: ['apechain'], chainKey: 'apechain' },\n { aliases: ['arbitrum'], chainKey: 'arbitrum' },\n { aliases: ['astar'], chainKey: 'astar' },\n { aliases: ['avalanche'], chainKey: 'avalanche' },\n { aliases: ['base'], chainKey: 'base' },\n { aliases: ['berachain'], chainKey: 'berachain' },\n { aliases: ['bitlayer'], chainKey: 'bitlayer' },\n { aliases: ['blast'], chainKey: 'blast' },\n { aliases: ['bnbchain', 'bnbsmartchain', 'binancesmartchain', 'binancechain'], chainKey: 'bnbchain' },\n { aliases: ['bob'], chainKey: 'bob' },\n { aliases: ['b2', 'bsquared'], chainKey: 'bsquared' },\n { aliases: ['celo'], chainKey: 'celo' },\n { aliases: ['core'], chainKey: 'core' },\n { aliases: ['corn'], chainKey: 'corn' },\n { aliases: ['cronoszkevm'], chainKey: 'cronoszkevm' },\n { aliases: ['cronos'], chainKey: 'cronos' },\n { aliases: ['ethereum'], chainKey: 'ethereum' },\n { aliases: ['fraxtal'], chainKey: 'fraxtal' },\n { aliases: ['gnosis'], chainKey: 'gnosis' },\n { aliases: ['hashkey'], chainKey: 'hashkey' },\n { aliases: ['ink'], chainKey: 'ink' },\n { aliases: ['kroma'], chainKey: 'kroma' },\n { aliases: ['linea'], chainKey: 'linea' },\n { aliases: ['mantle'], chainKey: 'mantle' },\n { aliases: ['metis'], chainKey: 'metis' },\n { aliases: ['mindnetwork'], chainKey: 'mindnetwork' },\n { aliases: ['mode'], chainKey: 'mode' },\n { aliases: ['monad'], chainKey: 'monad' },\n { aliases: ['opmainnet', 'optimism'], chainKey: 'opmainnet' },\n { aliases: ['polygonzkevm'], chainKey: 'polygonzkevm' },\n { aliases: ['polygon'], chainKey: 'polygon' },\n { aliases: ['ronin'], chainKey: 'ronin' },\n { aliases: ['scroll'], chainKey: 'scroll' },\n { aliases: ['sei'], chainKey: 'sei' },\n { aliases: ['solana'], chainKey: 'solana' },\n { aliases: ['soneium'], chainKey: 'soneium' },\n { aliases: ['sonic'], chainKey: 'sonic' },\n { aliases: ['shibarium'], chainKey: 'shibarium' },\n { aliases: ['treasure'], chainKey: 'treasure' },\n { aliases: ['unichain'], chainKey: 'unichain' },\n { aliases: ['wemix'], chainKey: 'wemix' },\n { aliases: ['worldchain'], chainKey: 'worldchain' },\n { aliases: ['xlayer'], chainKey: 'xlayer' },\n { aliases: ['zircuit'], chainKey: 'zircuit' },\n { aliases: ['zksync'], chainKey: 'zksync' },\n] as const satisfies ReadonlyArray<{ aliases: readonly string[]; chainKey: FinalityChainKey }>;\n\n/**\n * Known CAIP-2 chain IDs and their approximate CCIP finality times in\n * milliseconds.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_ID: Partial<Record<Caip2ChainId, number>> = {\n ...Object.fromEntries(\n Object.entries(FINALITY_CHAIN_KEY_BY_CHAIN_ID).map(([chainId, chainKey]) => [\n chainId,\n FINALITY_MS_BY_CHAIN_KEY[chainKey],\n ]),\n ),\n};\n\n/**\n * Chain-name aliases and their approximate CCIP finality times in\n * milliseconds.\n *\n * These aliases are used as a fallback when a chain ID is not present in\n * `FINALITY_MS_BY_CHAIN_ID`.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_NAME_ALIAS: ReadonlyArray<{ aliases: readonly string[]; finalityMs: number }> = [\n ...FINALITY_CHAIN_NAME_ALIASES.map(({ aliases, chainKey }) => ({\n aliases,\n finalityMs: FINALITY_MS_BY_CHAIN_KEY[chainKey],\n })),\n];\n\n// Solana slot time is ~400ms. Polling every 2.5s (~6 slots) balances\n// responsiveness against RPC rate-limits — fast enough to detect finalization\n// promptly, without hammering the endpoint.\nexport const SOLANA_POLLING_INTERVAL_MS = 2_500;\n\n// A Solana blockhash is valid for 150 slots (~60s at 400ms/slot). Validators\n// may hold a transaction for up to ~90s before dropping it. We set a 120s\n// timeout to provide a comfortable buffer above worst-case blockhash expiry,\n// ensuring we don't falsely time out a transaction that is still eligible for\n// inclusion in a block.\nexport const SOLANA_TX_TIMEOUT_MS = 120_000;\n\n// Solana finalizes a block once ≥31 confirmed blocks are built on top of it.\n// `getSignatureStatuses` returns the running `confirmations` count (0 → N),\n// then `null` once the status flips to `finalized`. We use 32 as the\n// required-confirmation target so the progress bar fills smoothly from 0 → 31\n// during polling and snaps to 32 (= done) only when finalization is confirmed.\nexport const SOLANA_REQUIRED_CONFIRMATIONS = 32;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=`https://proxy-api.avax.network/proxy/markr`,t={fast:2e3,medium:5e3,slow:3e4,verySlow:18e4},n={fast:6e4,medium:20*6e4,slow:120*6e4},r={apechain:50*6e4,arbitrum:17*6e4,astar:35e3,avalanche:1e3,base:18*6e4,berachain:7e3,bitlayer:6e4,blast:20*6e4,bnbchain:5e3,bob:120*6e4,bsquared:20*6e4,celo:1e3,core:6e4,corn:720*6e4,cronos:1e3,cronoszkevm:1860*6e4,ethereum:15*6e4,fraxtal:30*6e4,gnosis:3*6e4,hashkey:60*6e4,ink:120*6e4,kroma:25*6e4,linea:20*6e4,mantle:28*6e4,metis:120*6e4,mindnetwork:60*6e4,mode:37*6e4,monad:48e3,opmainnet:20*6e4,polygon:17*6e4,polygonzkevm:120*6e4,ronin:1e4,scroll:60*6e4,sei:1e3,shibarium:6e4,solana:1e3,sonic:7e3,soneium:27*6e4,treasure:420*6e4,unichain:24*6e4,wemix:1e3,worldchain:40*6e4,xlayer:60*6e4,zircuit:21*6e4,zksync:20*6e4},i={"eip155:1":`ethereum`,"eip155:10":`opmainnet`,"eip155:25":`cronos`,"eip155:56":`bnbchain`,"eip155:100":`gnosis`,"eip155:137":`polygon`,"eip155:324":`zksync`,"eip155:1101":`polygonzkevm`,"eip155:1116":`core`,"eip155:1329":`sei`,"eip155:196":`xlayer`,"eip155:252":`fraxtal`,"eip155:480":`worldchain`,"eip155:59144":`linea`,"eip155:8453":`base`,"eip155:1088":`metis`,"eip155:2020":`ronin`,"eip155:42220":`celo`,"eip155:43114":`avalanche`,"eip155:48900":`zircuit`,"eip155:5000":`mantle`,"eip155:534352":`scroll`,"eip155:42161":`arbitrum`,"eip155:81457":`blast`,"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp":`solana`},a=[{aliases:[`apechain`],chainKey:`apechain`},{aliases:[`arbitrum`],chainKey:`arbitrum`},{aliases:[`astar`],chainKey:`astar`},{aliases:[`avalanche`],chainKey:`avalanche`},{aliases:[`base`],chainKey:`base`},{aliases:[`berachain`],chainKey:`berachain`},{aliases:[`bitlayer`],chainKey:`bitlayer`},{aliases:[`blast`],chainKey:`blast`},{aliases:[`bnbchain`,`bnbsmartchain`,`binancesmartchain`,`binancechain`],chainKey:`bnbchain`},{aliases:[`bob`],chainKey:`bob`},{aliases:[`b2`,`bsquared`],chainKey:`bsquared`},{aliases:[`celo`],chainKey:`celo`},{aliases:[`core`],chainKey:`core`},{aliases:[`corn`],chainKey:`corn`},{aliases:[`cronoszkevm`],chainKey:`cronoszkevm`},{aliases:[`cronos`],chainKey:`cronos`},{aliases:[`ethereum`],chainKey:`ethereum`},{aliases:[`fraxtal`],chainKey:`fraxtal`},{aliases:[`gnosis`],chainKey:`gnosis`},{aliases:[`hashkey`],chainKey:`hashkey`},{aliases:[`ink`],chainKey:`ink`},{aliases:[`kroma`],chainKey:`kroma`},{aliases:[`linea`],chainKey:`linea`},{aliases:[`mantle`],chainKey:`mantle`},{aliases:[`metis`],chainKey:`metis`},{aliases:[`mindnetwork`],chainKey:`mindnetwork`},{aliases:[`mode`],chainKey:`mode`},{aliases:[`monad`],chainKey:`monad`},{aliases:[`opmainnet`,`optimism`],chainKey:`opmainnet`},{aliases:[`polygonzkevm`],chainKey:`polygonzkevm`},{aliases:[`polygon`],chainKey:`polygon`},{aliases:[`ronin`],chainKey:`ronin`},{aliases:[`scroll`],chainKey:`scroll`},{aliases:[`sei`],chainKey:`sei`},{aliases:[`solana`],chainKey:`solana`},{aliases:[`soneium`],chainKey:`soneium`},{aliases:[`sonic`],chainKey:`sonic`},{aliases:[`shibarium`],chainKey:`shibarium`},{aliases:[`treasure`],chainKey:`treasure`},{aliases:[`unichain`],chainKey:`unichain`},{aliases:[`wemix`],chainKey:`wemix`},{aliases:[`worldchain`],chainKey:`worldchain`},{aliases:[`xlayer`],chainKey:`xlayer`},{aliases:[`zircuit`],chainKey:`zircuit`},{aliases:[`zksync`],chainKey:`zksync`}],o={...Object.fromEntries(Object.entries(i).map(([e,t])=>[e,r[t]]))},s=[...a.map(({aliases:e,chainKey:t})=>({aliases:e,finalityMs:r[t]}))],c=2500,l=12e4,u=32;export{t as CROSS_CHAIN_POLLING_INTERVAL_MS,e as DEFAULT_MARKR_API_URL,o as FINALITY_MS_BY_CHAIN_ID,s as FINALITY_MS_BY_CHAIN_NAME_ALIAS,n as FINALITY_TIER_MAX_FINALITY_MS,c as SOLANA_POLLING_INTERVAL_MS,u as SOLANA_REQUIRED_CONFIRMATIONS,l as SOLANA_TX_TIMEOUT_MS};
|
|
1
|
+
const e=`https://proxy-api.avax.network/proxy/markr-helium`,t={fast:2e3,medium:5e3,slow:3e4,verySlow:18e4},n={fast:6e4,medium:20*6e4,slow:120*6e4},r={apechain:50*6e4,arbitrum:17*6e4,astar:35e3,avalanche:1e3,base:18*6e4,berachain:7e3,bitlayer:6e4,blast:20*6e4,bnbchain:5e3,bob:120*6e4,bsquared:20*6e4,celo:1e3,core:6e4,corn:720*6e4,cronos:1e3,cronoszkevm:1860*6e4,ethereum:15*6e4,fraxtal:30*6e4,gnosis:3*6e4,hashkey:60*6e4,ink:120*6e4,kroma:25*6e4,linea:20*6e4,mantle:28*6e4,metis:120*6e4,mindnetwork:60*6e4,mode:37*6e4,monad:48e3,opmainnet:20*6e4,polygon:17*6e4,polygonzkevm:120*6e4,ronin:1e4,scroll:60*6e4,sei:1e3,shibarium:6e4,solana:1e3,sonic:7e3,soneium:27*6e4,treasure:420*6e4,unichain:24*6e4,wemix:1e3,worldchain:40*6e4,xlayer:60*6e4,zircuit:21*6e4,zksync:20*6e4},i={"eip155:1":`ethereum`,"eip155:10":`opmainnet`,"eip155:25":`cronos`,"eip155:56":`bnbchain`,"eip155:100":`gnosis`,"eip155:137":`polygon`,"eip155:324":`zksync`,"eip155:1101":`polygonzkevm`,"eip155:1116":`core`,"eip155:1329":`sei`,"eip155:196":`xlayer`,"eip155:252":`fraxtal`,"eip155:480":`worldchain`,"eip155:59144":`linea`,"eip155:8453":`base`,"eip155:1088":`metis`,"eip155:2020":`ronin`,"eip155:42220":`celo`,"eip155:43114":`avalanche`,"eip155:48900":`zircuit`,"eip155:5000":`mantle`,"eip155:534352":`scroll`,"eip155:42161":`arbitrum`,"eip155:81457":`blast`,"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp":`solana`},a=[{aliases:[`apechain`],chainKey:`apechain`},{aliases:[`arbitrum`],chainKey:`arbitrum`},{aliases:[`astar`],chainKey:`astar`},{aliases:[`avalanche`],chainKey:`avalanche`},{aliases:[`base`],chainKey:`base`},{aliases:[`berachain`],chainKey:`berachain`},{aliases:[`bitlayer`],chainKey:`bitlayer`},{aliases:[`blast`],chainKey:`blast`},{aliases:[`bnbchain`,`bnbsmartchain`,`binancesmartchain`,`binancechain`],chainKey:`bnbchain`},{aliases:[`bob`],chainKey:`bob`},{aliases:[`b2`,`bsquared`],chainKey:`bsquared`},{aliases:[`celo`],chainKey:`celo`},{aliases:[`core`],chainKey:`core`},{aliases:[`corn`],chainKey:`corn`},{aliases:[`cronoszkevm`],chainKey:`cronoszkevm`},{aliases:[`cronos`],chainKey:`cronos`},{aliases:[`ethereum`],chainKey:`ethereum`},{aliases:[`fraxtal`],chainKey:`fraxtal`},{aliases:[`gnosis`],chainKey:`gnosis`},{aliases:[`hashkey`],chainKey:`hashkey`},{aliases:[`ink`],chainKey:`ink`},{aliases:[`kroma`],chainKey:`kroma`},{aliases:[`linea`],chainKey:`linea`},{aliases:[`mantle`],chainKey:`mantle`},{aliases:[`metis`],chainKey:`metis`},{aliases:[`mindnetwork`],chainKey:`mindnetwork`},{aliases:[`mode`],chainKey:`mode`},{aliases:[`monad`],chainKey:`monad`},{aliases:[`opmainnet`,`optimism`],chainKey:`opmainnet`},{aliases:[`polygonzkevm`],chainKey:`polygonzkevm`},{aliases:[`polygon`],chainKey:`polygon`},{aliases:[`ronin`],chainKey:`ronin`},{aliases:[`scroll`],chainKey:`scroll`},{aliases:[`sei`],chainKey:`sei`},{aliases:[`solana`],chainKey:`solana`},{aliases:[`soneium`],chainKey:`soneium`},{aliases:[`sonic`],chainKey:`sonic`},{aliases:[`shibarium`],chainKey:`shibarium`},{aliases:[`treasure`],chainKey:`treasure`},{aliases:[`unichain`],chainKey:`unichain`},{aliases:[`wemix`],chainKey:`wemix`},{aliases:[`worldchain`],chainKey:`worldchain`},{aliases:[`xlayer`],chainKey:`xlayer`},{aliases:[`zircuit`],chainKey:`zircuit`},{aliases:[`zksync`],chainKey:`zksync`}],o={...Object.fromEntries(Object.entries(i).map(([e,t])=>[e,r[t]]))},s=[...a.map(({aliases:e,chainKey:t})=>({aliases:e,finalityMs:r[t]}))],c=2500,l=12e4,u=32;export{t as CROSS_CHAIN_POLLING_INTERVAL_MS,e as DEFAULT_MARKR_API_URL,o as FINALITY_MS_BY_CHAIN_ID,s as FINALITY_MS_BY_CHAIN_NAME_ALIAS,n as FINALITY_TIER_MAX_FINALITY_MS,c as SOLANA_POLLING_INTERVAL_MS,u as SOLANA_REQUIRED_CONFIRMATIONS,l as SOLANA_TX_TIMEOUT_MS};
|
|
2
2
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/transfer-service/markr/constants.ts"],"sourcesContent":["import type { Caip2ChainId } from '../../types/caip';\n\nexport const DEFAULT_MARKR_API_URL = 'https://proxy-api.avax.network/proxy/markr' as const;\n\n/**\n * Cross-chain polling tiers used by Markr transfer tracking.\n *\n * Tier boundaries are selected from known destination/source finality windows\n * so we poll fast-finality chains more aggressively and avoid excessive RPC\n * traffic on slow-finality chains.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const CROSS_CHAIN_POLLING_INTERVAL_MS = {\n fast: 2_000, // 2 seconds\n medium: 5_000, // 5 seconds\n slow: 30_000, // 30 seconds\n verySlow: 180_000, // 3 minutes\n} as const;\n\n/**\n * Upper bounds (in ms) used to map known finality time to a polling tier.\n *\n * Values greater than `slow` are classified as `verySlow`.\n */\nexport const FINALITY_TIER_MAX_FINALITY_MS: Readonly<Record<'fast' | 'medium' | 'slow', number>> = {\n fast: 60_000,\n medium: 20 * 60_000,\n slow: 2 * 60 * 60_000,\n};\n\nconst FINALITY_MS_BY_CHAIN_KEY = {\n apechain: 50 * 60_000,\n arbitrum: 17 * 60_000,\n astar: 35_000,\n avalanche: 1_000,\n base: 18 * 60_000,\n berachain: 7_000,\n bitlayer: 60_000,\n blast: 20 * 60_000,\n bnbchain: 5_000,\n bob: 2 * 60 * 60_000,\n bsquared: 20 * 60_000,\n celo: 1_000,\n core: 60_000,\n corn: 12 * 60 * 60_000,\n cronos: 1_000,\n cronoszkevm: 31 * 60 * 60_000,\n ethereum: 15 * 60_000,\n fraxtal: 30 * 60_000,\n gnosis: 3 * 60_000,\n hashkey: 60 * 60_000,\n ink: 2 * 60 * 60_000,\n kroma: 25 * 60_000,\n linea: 20 * 60_000,\n mantle: 28 * 60_000,\n metis: 2 * 60 * 60_000,\n mindnetwork: 60 * 60_000,\n mode: 37 * 60_000,\n monad: 48_000,\n opmainnet: 20 * 60_000,\n polygon: 17 * 60_000,\n polygonzkevm: 2 * 60 * 60_000,\n ronin: 10_000,\n scroll: 60 * 60_000,\n sei: 1_000,\n shibarium: 60_000,\n solana: 1_000,\n sonic: 7_000,\n soneium: 27 * 60_000,\n treasure: 7 * 60 * 60_000,\n unichain: 24 * 60_000,\n wemix: 1_000,\n worldchain: 40 * 60_000,\n xlayer: 60 * 60_000,\n zircuit: 21 * 60_000,\n zksync: 20 * 60_000,\n} as const;\n\ntype FinalityChainKey = keyof typeof FINALITY_MS_BY_CHAIN_KEY;\n\nconst FINALITY_CHAIN_KEY_BY_CHAIN_ID = {\n 'eip155:1': 'ethereum',\n 'eip155:10': 'opmainnet',\n 'eip155:25': 'cronos',\n 'eip155:56': 'bnbchain',\n 'eip155:100': 'gnosis',\n 'eip155:137': 'polygon',\n 'eip155:324': 'zksync',\n 'eip155:1101': 'polygonzkevm',\n 'eip155:1116': 'core',\n 'eip155:1329': 'sei',\n 'eip155:196': 'xlayer',\n 'eip155:252': 'fraxtal',\n 'eip155:480': 'worldchain',\n 'eip155:59144': 'linea',\n 'eip155:8453': 'base',\n 'eip155:1088': 'metis',\n 'eip155:2020': 'ronin',\n 'eip155:42220': 'celo',\n 'eip155:43114': 'avalanche',\n 'eip155:48900': 'zircuit',\n 'eip155:5000': 'mantle',\n 'eip155:534352': 'scroll',\n 'eip155:42161': 'arbitrum',\n 'eip155:81457': 'blast',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana',\n} as const satisfies Partial<Record<Caip2ChainId, FinalityChainKey>>;\n\nconst FINALITY_CHAIN_NAME_ALIASES = [\n { aliases: ['apechain'], chainKey: 'apechain' },\n { aliases: ['arbitrum'], chainKey: 'arbitrum' },\n { aliases: ['astar'], chainKey: 'astar' },\n { aliases: ['avalanche'], chainKey: 'avalanche' },\n { aliases: ['base'], chainKey: 'base' },\n { aliases: ['berachain'], chainKey: 'berachain' },\n { aliases: ['bitlayer'], chainKey: 'bitlayer' },\n { aliases: ['blast'], chainKey: 'blast' },\n { aliases: ['bnbchain', 'bnbsmartchain', 'binancesmartchain', 'binancechain'], chainKey: 'bnbchain' },\n { aliases: ['bob'], chainKey: 'bob' },\n { aliases: ['b2', 'bsquared'], chainKey: 'bsquared' },\n { aliases: ['celo'], chainKey: 'celo' },\n { aliases: ['core'], chainKey: 'core' },\n { aliases: ['corn'], chainKey: 'corn' },\n { aliases: ['cronoszkevm'], chainKey: 'cronoszkevm' },\n { aliases: ['cronos'], chainKey: 'cronos' },\n { aliases: ['ethereum'], chainKey: 'ethereum' },\n { aliases: ['fraxtal'], chainKey: 'fraxtal' },\n { aliases: ['gnosis'], chainKey: 'gnosis' },\n { aliases: ['hashkey'], chainKey: 'hashkey' },\n { aliases: ['ink'], chainKey: 'ink' },\n { aliases: ['kroma'], chainKey: 'kroma' },\n { aliases: ['linea'], chainKey: 'linea' },\n { aliases: ['mantle'], chainKey: 'mantle' },\n { aliases: ['metis'], chainKey: 'metis' },\n { aliases: ['mindnetwork'], chainKey: 'mindnetwork' },\n { aliases: ['mode'], chainKey: 'mode' },\n { aliases: ['monad'], chainKey: 'monad' },\n { aliases: ['opmainnet', 'optimism'], chainKey: 'opmainnet' },\n { aliases: ['polygonzkevm'], chainKey: 'polygonzkevm' },\n { aliases: ['polygon'], chainKey: 'polygon' },\n { aliases: ['ronin'], chainKey: 'ronin' },\n { aliases: ['scroll'], chainKey: 'scroll' },\n { aliases: ['sei'], chainKey: 'sei' },\n { aliases: ['solana'], chainKey: 'solana' },\n { aliases: ['soneium'], chainKey: 'soneium' },\n { aliases: ['sonic'], chainKey: 'sonic' },\n { aliases: ['shibarium'], chainKey: 'shibarium' },\n { aliases: ['treasure'], chainKey: 'treasure' },\n { aliases: ['unichain'], chainKey: 'unichain' },\n { aliases: ['wemix'], chainKey: 'wemix' },\n { aliases: ['worldchain'], chainKey: 'worldchain' },\n { aliases: ['xlayer'], chainKey: 'xlayer' },\n { aliases: ['zircuit'], chainKey: 'zircuit' },\n { aliases: ['zksync'], chainKey: 'zksync' },\n] as const satisfies ReadonlyArray<{ aliases: readonly string[]; chainKey: FinalityChainKey }>;\n\n/**\n * Known CAIP-2 chain IDs and their approximate CCIP finality times in\n * milliseconds.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_ID: Partial<Record<Caip2ChainId, number>> = {\n ...Object.fromEntries(\n Object.entries(FINALITY_CHAIN_KEY_BY_CHAIN_ID).map(([chainId, chainKey]) => [\n chainId,\n FINALITY_MS_BY_CHAIN_KEY[chainKey],\n ]),\n ),\n};\n\n/**\n * Chain-name aliases and their approximate CCIP finality times in\n * milliseconds.\n *\n * These aliases are used as a fallback when a chain ID is not present in\n * `FINALITY_MS_BY_CHAIN_ID`.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_NAME_ALIAS: ReadonlyArray<{ aliases: readonly string[]; finalityMs: number }> = [\n ...FINALITY_CHAIN_NAME_ALIASES.map(({ aliases, chainKey }) => ({\n aliases,\n finalityMs: FINALITY_MS_BY_CHAIN_KEY[chainKey],\n })),\n];\n\n// Solana slot time is ~400ms. Polling every 2.5s (~6 slots) balances\n// responsiveness against RPC rate-limits — fast enough to detect finalization\n// promptly, without hammering the endpoint.\nexport const SOLANA_POLLING_INTERVAL_MS = 2_500;\n\n// A Solana blockhash is valid for 150 slots (~60s at 400ms/slot). Validators\n// may hold a transaction for up to ~90s before dropping it. We set a 120s\n// timeout to provide a comfortable buffer above worst-case blockhash expiry,\n// ensuring we don't falsely time out a transaction that is still eligible for\n// inclusion in a block.\nexport const SOLANA_TX_TIMEOUT_MS = 120_000;\n\n// Solana finalizes a block once ≥31 confirmed blocks are built on top of it.\n// `getSignatureStatuses` returns the running `confirmations` count (0 → N),\n// then `null` once the status flips to `finalized`. We use 32 as the\n// required-confirmation target so the progress bar fills smoothly from 0 → 31\n// during polling and snaps to 32 (= done) only when finalization is confirmed.\nexport const SOLANA_REQUIRED_CONFIRMATIONS = 32;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/transfer-service/markr/constants.ts"],"sourcesContent":["import type { Caip2ChainId } from '../../types/caip';\n\nexport const DEFAULT_MARKR_API_URL = 'https://proxy-api.avax.network/proxy/markr-helium' as const;\n\n/**\n * Cross-chain polling tiers used by Markr transfer tracking.\n *\n * Tier boundaries are selected from known destination/source finality windows\n * so we poll fast-finality chains more aggressively and avoid excessive RPC\n * traffic on slow-finality chains.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const CROSS_CHAIN_POLLING_INTERVAL_MS = {\n fast: 2_000, // 2 seconds\n medium: 5_000, // 5 seconds\n slow: 30_000, // 30 seconds\n verySlow: 180_000, // 3 minutes\n} as const;\n\n/**\n * Upper bounds (in ms) used to map known finality time to a polling tier.\n *\n * Values greater than `slow` are classified as `verySlow`.\n */\nexport const FINALITY_TIER_MAX_FINALITY_MS: Readonly<Record<'fast' | 'medium' | 'slow', number>> = {\n fast: 60_000,\n medium: 20 * 60_000,\n slow: 2 * 60 * 60_000,\n};\n\nconst FINALITY_MS_BY_CHAIN_KEY = {\n apechain: 50 * 60_000,\n arbitrum: 17 * 60_000,\n astar: 35_000,\n avalanche: 1_000,\n base: 18 * 60_000,\n berachain: 7_000,\n bitlayer: 60_000,\n blast: 20 * 60_000,\n bnbchain: 5_000,\n bob: 2 * 60 * 60_000,\n bsquared: 20 * 60_000,\n celo: 1_000,\n core: 60_000,\n corn: 12 * 60 * 60_000,\n cronos: 1_000,\n cronoszkevm: 31 * 60 * 60_000,\n ethereum: 15 * 60_000,\n fraxtal: 30 * 60_000,\n gnosis: 3 * 60_000,\n hashkey: 60 * 60_000,\n ink: 2 * 60 * 60_000,\n kroma: 25 * 60_000,\n linea: 20 * 60_000,\n mantle: 28 * 60_000,\n metis: 2 * 60 * 60_000,\n mindnetwork: 60 * 60_000,\n mode: 37 * 60_000,\n monad: 48_000,\n opmainnet: 20 * 60_000,\n polygon: 17 * 60_000,\n polygonzkevm: 2 * 60 * 60_000,\n ronin: 10_000,\n scroll: 60 * 60_000,\n sei: 1_000,\n shibarium: 60_000,\n solana: 1_000,\n sonic: 7_000,\n soneium: 27 * 60_000,\n treasure: 7 * 60 * 60_000,\n unichain: 24 * 60_000,\n wemix: 1_000,\n worldchain: 40 * 60_000,\n xlayer: 60 * 60_000,\n zircuit: 21 * 60_000,\n zksync: 20 * 60_000,\n} as const;\n\ntype FinalityChainKey = keyof typeof FINALITY_MS_BY_CHAIN_KEY;\n\nconst FINALITY_CHAIN_KEY_BY_CHAIN_ID = {\n 'eip155:1': 'ethereum',\n 'eip155:10': 'opmainnet',\n 'eip155:25': 'cronos',\n 'eip155:56': 'bnbchain',\n 'eip155:100': 'gnosis',\n 'eip155:137': 'polygon',\n 'eip155:324': 'zksync',\n 'eip155:1101': 'polygonzkevm',\n 'eip155:1116': 'core',\n 'eip155:1329': 'sei',\n 'eip155:196': 'xlayer',\n 'eip155:252': 'fraxtal',\n 'eip155:480': 'worldchain',\n 'eip155:59144': 'linea',\n 'eip155:8453': 'base',\n 'eip155:1088': 'metis',\n 'eip155:2020': 'ronin',\n 'eip155:42220': 'celo',\n 'eip155:43114': 'avalanche',\n 'eip155:48900': 'zircuit',\n 'eip155:5000': 'mantle',\n 'eip155:534352': 'scroll',\n 'eip155:42161': 'arbitrum',\n 'eip155:81457': 'blast',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana',\n} as const satisfies Partial<Record<Caip2ChainId, FinalityChainKey>>;\n\nconst FINALITY_CHAIN_NAME_ALIASES = [\n { aliases: ['apechain'], chainKey: 'apechain' },\n { aliases: ['arbitrum'], chainKey: 'arbitrum' },\n { aliases: ['astar'], chainKey: 'astar' },\n { aliases: ['avalanche'], chainKey: 'avalanche' },\n { aliases: ['base'], chainKey: 'base' },\n { aliases: ['berachain'], chainKey: 'berachain' },\n { aliases: ['bitlayer'], chainKey: 'bitlayer' },\n { aliases: ['blast'], chainKey: 'blast' },\n { aliases: ['bnbchain', 'bnbsmartchain', 'binancesmartchain', 'binancechain'], chainKey: 'bnbchain' },\n { aliases: ['bob'], chainKey: 'bob' },\n { aliases: ['b2', 'bsquared'], chainKey: 'bsquared' },\n { aliases: ['celo'], chainKey: 'celo' },\n { aliases: ['core'], chainKey: 'core' },\n { aliases: ['corn'], chainKey: 'corn' },\n { aliases: ['cronoszkevm'], chainKey: 'cronoszkevm' },\n { aliases: ['cronos'], chainKey: 'cronos' },\n { aliases: ['ethereum'], chainKey: 'ethereum' },\n { aliases: ['fraxtal'], chainKey: 'fraxtal' },\n { aliases: ['gnosis'], chainKey: 'gnosis' },\n { aliases: ['hashkey'], chainKey: 'hashkey' },\n { aliases: ['ink'], chainKey: 'ink' },\n { aliases: ['kroma'], chainKey: 'kroma' },\n { aliases: ['linea'], chainKey: 'linea' },\n { aliases: ['mantle'], chainKey: 'mantle' },\n { aliases: ['metis'], chainKey: 'metis' },\n { aliases: ['mindnetwork'], chainKey: 'mindnetwork' },\n { aliases: ['mode'], chainKey: 'mode' },\n { aliases: ['monad'], chainKey: 'monad' },\n { aliases: ['opmainnet', 'optimism'], chainKey: 'opmainnet' },\n { aliases: ['polygonzkevm'], chainKey: 'polygonzkevm' },\n { aliases: ['polygon'], chainKey: 'polygon' },\n { aliases: ['ronin'], chainKey: 'ronin' },\n { aliases: ['scroll'], chainKey: 'scroll' },\n { aliases: ['sei'], chainKey: 'sei' },\n { aliases: ['solana'], chainKey: 'solana' },\n { aliases: ['soneium'], chainKey: 'soneium' },\n { aliases: ['sonic'], chainKey: 'sonic' },\n { aliases: ['shibarium'], chainKey: 'shibarium' },\n { aliases: ['treasure'], chainKey: 'treasure' },\n { aliases: ['unichain'], chainKey: 'unichain' },\n { aliases: ['wemix'], chainKey: 'wemix' },\n { aliases: ['worldchain'], chainKey: 'worldchain' },\n { aliases: ['xlayer'], chainKey: 'xlayer' },\n { aliases: ['zircuit'], chainKey: 'zircuit' },\n { aliases: ['zksync'], chainKey: 'zksync' },\n] as const satisfies ReadonlyArray<{ aliases: readonly string[]; chainKey: FinalityChainKey }>;\n\n/**\n * Known CAIP-2 chain IDs and their approximate CCIP finality times in\n * milliseconds.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_ID: Partial<Record<Caip2ChainId, number>> = {\n ...Object.fromEntries(\n Object.entries(FINALITY_CHAIN_KEY_BY_CHAIN_ID).map(([chainId, chainKey]) => [\n chainId,\n FINALITY_MS_BY_CHAIN_KEY[chainKey],\n ]),\n ),\n};\n\n/**\n * Chain-name aliases and their approximate CCIP finality times in\n * milliseconds.\n *\n * These aliases are used as a fallback when a chain ID is not present in\n * `FINALITY_MS_BY_CHAIN_ID`.\n *\n * Finality reference:\n * https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain\n */\nexport const FINALITY_MS_BY_CHAIN_NAME_ALIAS: ReadonlyArray<{ aliases: readonly string[]; finalityMs: number }> = [\n ...FINALITY_CHAIN_NAME_ALIASES.map(({ aliases, chainKey }) => ({\n aliases,\n finalityMs: FINALITY_MS_BY_CHAIN_KEY[chainKey],\n })),\n];\n\n// Solana slot time is ~400ms. Polling every 2.5s (~6 slots) balances\n// responsiveness against RPC rate-limits — fast enough to detect finalization\n// promptly, without hammering the endpoint.\nexport const SOLANA_POLLING_INTERVAL_MS = 2_500;\n\n// A Solana blockhash is valid for 150 slots (~60s at 400ms/slot). Validators\n// may hold a transaction for up to ~90s before dropping it. We set a 120s\n// timeout to provide a comfortable buffer above worst-case blockhash expiry,\n// ensuring we don't falsely time out a transaction that is still eligible for\n// inclusion in a block.\nexport const SOLANA_TX_TIMEOUT_MS = 120_000;\n\n// Solana finalizes a block once ≥31 confirmed blocks are built on top of it.\n// `getSignatureStatuses` returns the running `confirmations` count (0 → N),\n// then `null` once the status flips to `finalized`. We use 32 as the\n// required-confirmation target so the progress bar fills smoothly from 0 → 31\n// during polling and snaps to 32 (= done) only when finalization is confirmed.\nexport const SOLANA_REQUIRED_CONFIRMATIONS = 32;\n"],"mappings":"AAEA,MAAa,EAAwB,oDAYxB,EAAkC,CAC7C,KAAM,IACN,OAAQ,IACR,KAAM,IACN,SAAU,KACX,CAOY,EAAsF,CACjG,KAAM,IACN,OAAQ,GAAK,IACb,KAAM,IAAS,IAChB,CAEK,EAA2B,CAC/B,SAAU,GAAK,IACf,SAAU,GAAK,IACf,MAAO,KACP,UAAW,IACX,KAAM,GAAK,IACX,UAAW,IACX,SAAU,IACV,MAAO,GAAK,IACZ,SAAU,IACV,IAAK,IAAS,IACd,SAAU,GAAK,IACf,KAAM,IACN,KAAM,IACN,KAAM,IAAU,IAChB,OAAQ,IACR,YAAa,KAAU,IACvB,SAAU,GAAK,IACf,QAAS,GAAK,IACd,OAAQ,EAAI,IACZ,QAAS,GAAK,IACd,IAAK,IAAS,IACd,MAAO,GAAK,IACZ,MAAO,GAAK,IACZ,OAAQ,GAAK,IACb,MAAO,IAAS,IAChB,YAAa,GAAK,IAClB,KAAM,GAAK,IACX,MAAO,KACP,UAAW,GAAK,IAChB,QAAS,GAAK,IACd,aAAc,IAAS,IACvB,MAAO,IACP,OAAQ,GAAK,IACb,IAAK,IACL,UAAW,IACX,OAAQ,IACR,MAAO,IACP,QAAS,GAAK,IACd,SAAU,IAAS,IACnB,SAAU,GAAK,IACf,MAAO,IACP,WAAY,GAAK,IACjB,OAAQ,GAAK,IACb,QAAS,GAAK,IACd,OAAQ,GAAK,IACd,CAIK,EAAiC,CACrC,WAAY,WACZ,YAAa,YACb,YAAa,SACb,YAAa,WACb,aAAc,SACd,aAAc,UACd,aAAc,SACd,cAAe,eACf,cAAe,OACf,cAAe,MACf,aAAc,SACd,aAAc,UACd,aAAc,aACd,eAAgB,QAChB,cAAe,OACf,cAAe,QACf,cAAe,QACf,eAAgB,OAChB,eAAgB,YAChB,eAAgB,UAChB,cAAe,SACf,gBAAiB,SACjB,eAAgB,WAChB,eAAgB,QAChB,0CAA2C,SAC5C,CAEK,EAA8B,CAClC,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,YAAY,CAAE,SAAU,YAAa,CACjD,CAAE,QAAS,CAAC,OAAO,CAAE,SAAU,OAAQ,CACvC,CAAE,QAAS,CAAC,YAAY,CAAE,SAAU,YAAa,CACjD,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,WAAY,gBAAiB,oBAAqB,eAAe,CAAE,SAAU,WAAY,CACrG,CAAE,QAAS,CAAC,MAAM,CAAE,SAAU,MAAO,CACrC,CAAE,QAAS,CAAC,KAAM,WAAW,CAAE,SAAU,WAAY,CACrD,CAAE,QAAS,CAAC,OAAO,CAAE,SAAU,OAAQ,CACvC,CAAE,QAAS,CAAC,OAAO,CAAE,SAAU,OAAQ,CACvC,CAAE,QAAS,CAAC,OAAO,CAAE,SAAU,OAAQ,CACvC,CAAE,QAAS,CAAC,cAAc,CAAE,SAAU,cAAe,CACrD,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,UAAU,CAAE,SAAU,UAAW,CAC7C,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,UAAU,CAAE,SAAU,UAAW,CAC7C,CAAE,QAAS,CAAC,MAAM,CAAE,SAAU,MAAO,CACrC,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,cAAc,CAAE,SAAU,cAAe,CACrD,CAAE,QAAS,CAAC,OAAO,CAAE,SAAU,OAAQ,CACvC,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,YAAa,WAAW,CAAE,SAAU,YAAa,CAC7D,CAAE,QAAS,CAAC,eAAe,CAAE,SAAU,eAAgB,CACvD,CAAE,QAAS,CAAC,UAAU,CAAE,SAAU,UAAW,CAC7C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,MAAM,CAAE,SAAU,MAAO,CACrC,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,UAAU,CAAE,SAAU,UAAW,CAC7C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,YAAY,CAAE,SAAU,YAAa,CACjD,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,WAAW,CAAE,SAAU,WAAY,CAC/C,CAAE,QAAS,CAAC,QAAQ,CAAE,SAAU,QAAS,CACzC,CAAE,QAAS,CAAC,aAAa,CAAE,SAAU,aAAc,CACnD,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC3C,CAAE,QAAS,CAAC,UAAU,CAAE,SAAU,UAAW,CAC7C,CAAE,QAAS,CAAC,SAAS,CAAE,SAAU,SAAU,CAC5C,CASY,EAAiE,CAC5E,GAAG,OAAO,YACR,OAAO,QAAQ,EAA+B,CAAC,KAAK,CAAC,EAAS,KAAc,CAC1E,EACA,EAAyB,GAC1B,CAAC,CACH,CACF,CAYY,EAAqG,CAChH,GAAG,EAA4B,KAAK,CAAE,UAAS,eAAgB,CAC7D,UACA,WAAY,EAAyB,GACtC,EAAE,CACJ,CAKY,EAA6B,KAO7B,EAAuB,KAOvB,EAAgC"}
|