@avalabs/fusion-sdk 0.27.0 → 0.28.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.
Files changed (57) hide show
  1. package/dist/constants.cjs +1 -1
  2. package/dist/constants.cjs.map +1 -1
  3. package/dist/constants.d.cts +32 -1
  4. package/dist/constants.d.ts +32 -1
  5. package/dist/constants.js +1 -1
  6. package/dist/constants.js.map +1 -1
  7. package/dist/errors.cjs +1 -1
  8. package/dist/errors.cjs.map +1 -1
  9. package/dist/errors.d.cts +2 -0
  10. package/dist/errors.d.ts +2 -0
  11. package/dist/errors.js +1 -1
  12. package/dist/errors.js.map +1 -1
  13. package/dist/mod.cjs +1 -1
  14. package/dist/mod.d.cts +3 -2
  15. package/dist/mod.d.ts +3 -2
  16. package/dist/mod.js +1 -1
  17. package/dist/transfer-service/_evm-errors.cjs.map +1 -1
  18. package/dist/transfer-service/_evm-errors.js.map +1 -1
  19. package/dist/transfer-service/avalanche-cct/_handlers/estimate-native-fee.cjs +1 -1
  20. package/dist/transfer-service/avalanche-cct/_handlers/estimate-native-fee.js +1 -1
  21. package/dist/transfer-service/avalanche-cct/_handlers/track-transfer.cjs +1 -1
  22. package/dist/transfer-service/avalanche-cct/_handlers/track-transfer.js +1 -1
  23. package/dist/transfer-service/avalanche-cct/_handlers/transfer-asset.cjs +1 -1
  24. package/dist/transfer-service/avalanche-cct/_handlers/transfer-asset.js +1 -1
  25. package/dist/transfer-service/avalanche-cct/_utils/fees.cjs +1 -1
  26. package/dist/transfer-service/avalanche-cct/_utils/fees.js +1 -1
  27. package/dist/transfer-service/avalanche-cct/_utils/polling.cjs +1 -1
  28. package/dist/transfer-service/avalanche-cct/_utils/polling.js +1 -1
  29. package/dist/transfer-service/markr/_api.cjs +1 -1
  30. package/dist/transfer-service/markr/_api.js +1 -1
  31. package/dist/transfer-service/markr/_handlers/estimate-native-fee.cjs +1 -1
  32. package/dist/transfer-service/markr/_handlers/estimate-native-fee.cjs.map +1 -1
  33. package/dist/transfer-service/markr/_handlers/estimate-native-fee.js +1 -1
  34. package/dist/transfer-service/markr/_handlers/estimate-native-fee.js.map +1 -1
  35. package/dist/transfer-service/markr/_handlers/transfer-asset-hyperliquid-withdraw.cjs +1 -1
  36. package/dist/transfer-service/markr/_handlers/transfer-asset-hyperliquid-withdraw.js +1 -1
  37. package/dist/transfer-service/markr/_handlers/transfer-asset.cjs +1 -1
  38. package/dist/transfer-service/markr/_handlers/transfer-asset.cjs.map +1 -1
  39. package/dist/transfer-service/markr/_handlers/transfer-asset.js +1 -1
  40. package/dist/transfer-service/markr/_handlers/transfer-asset.js.map +1 -1
  41. package/dist/transfer-service/markr/_hyperevm.cjs +2 -0
  42. package/dist/transfer-service/markr/_hyperevm.cjs.map +1 -0
  43. package/dist/transfer-service/markr/_hyperevm.js +2 -0
  44. package/dist/transfer-service/markr/_hyperevm.js.map +1 -0
  45. package/dist/transfer-service/markr/_hyperliquid-eip712.d.ts +1 -0
  46. package/dist/transfer-service/markr/_hyperliquid-l1-action.cjs +2 -0
  47. package/dist/transfer-service/markr/_hyperliquid-l1-action.cjs.map +1 -0
  48. package/dist/transfer-service/markr/_hyperliquid-l1-action.d.cts +60 -0
  49. package/dist/transfer-service/markr/_hyperliquid-l1-action.d.ts +60 -0
  50. package/dist/transfer-service/markr/_hyperliquid-l1-action.js +2 -0
  51. package/dist/transfer-service/markr/_hyperliquid-l1-action.js.map +1 -0
  52. package/dist/transfer-service/markr/_hyperliquid-schema.d.cts +8 -0
  53. package/dist/transfer-service/markr/_hyperliquid-schema.d.ts +10 -0
  54. package/dist/transfer-service/markr/_hyperliquid.d.ts +1 -0
  55. package/dist/transfer-service/markr/recurring/_api.cjs +1 -1
  56. package/dist/transfer-service/markr/recurring/_api.js +1 -1
  57. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"transfer-asset.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { HyperliquidChainIds, 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 { getEvmClientForChain, getSolanaRpcForChain, makeFailedTransferFromQuote, maybe1559 } from '../../_utils';\nimport { ApprovalRevertedError, buildErc20ApprovalRequest, signApprovalAndAssertConfirmed } from '../../_evm-approval';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport {\n assetToAddressString,\n calculateMarkrMinimumAmountOut,\n getAdditiveSourceAssetFeeAmount,\n isTokenAddressNative,\n} from '../_utils';\nimport { isEvmSwapResponse, isHyperliquidWithdrawSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport { _executeHyperliquidWithdraw } from './transfer-asset-hyperliquid-withdraw';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../../../utils/solana';\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 (sourceChainId === HyperliquidChainIds.MAINNET) {\n return _executeHyperliquidWithdrawTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n onStepChange,\n });\n }\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// Hyperliquid withdrawal path — wires `markrSwap` → HL handler\n// ---------------------------------------------------------------------------\n\ninterface HyperliquidWithdrawTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeHyperliquidWithdrawTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n onStepChange,\n}: HyperliquidWithdrawTransferParams): Promise<Transfer> {\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 uuid: quote.id,\n });\n\n if (!isHyperliquidWithdrawSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details:\n 'Expected `hyperliquid-withdraw` swap response from Markr for Hyperliquid source chain, but received a different variant.',\n });\n }\n\n return _executeHyperliquidWithdraw({\n apiOptions,\n environment,\n evmSigner,\n quote,\n swap,\n onStepChange,\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 const allowanceAmount = quote.amountIn + getAdditiveSourceAssetFeeAmount(quote);\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 const approvalRequest: EvmTransactionRequest | undefined =\n !isTokenInNative && spenderAddress\n ? await buildErc20ApprovalRequest({\n chainIdHex: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n client: sourceClient,\n gasSettings,\n owner: fromAddress,\n requiredAllowance: allowanceAmount,\n spender: spenderAddress,\n token: tokenInAddress,\n })\n : undefined;\n const requiresApprovalSignature = approvalRequest !== undefined;\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 ...maybe1559(gasSettings),\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 try {\n await signApprovalAndAssertConfirmed({\n client: sourceClient,\n evmSigner,\n onStepChange,\n request: approvalRequest,\n step: {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n },\n });\n } catch (error) {\n // Match the original behavior of \"branch only on the confirmed-then-\n // reverted receipt status\" by discriminating on the dedicated error\n // class — signer rejection / RPC errors fall through to the rethrow.\n if (error instanceof ApprovalRevertedError) {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n throw error;\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 ...maybe1559(gasSettings),\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
+ {"version":3,"file":"transfer-asset.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/transfer-asset.ts"],"sourcesContent":["import { isAddress } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { HyperEvmChainIds, HyperliquidChainIds, 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 { getEvmClientForChain, getSolanaRpcForChain, makeFailedTransferFromQuote, maybe1559 } from '../../_utils';\nimport { ApprovalRevertedError, buildErc20ApprovalRequest, signApprovalAndAssertConfirmed } from '../../_evm-approval';\nimport { markrGetSpenderAddress, markrSwap, type ApiOptions } from '../_api';\nimport { _getGasLimit, maybeEnableHyperEvmBigBlocks } from '../_hyperevm';\nimport {\n assetToAddressString,\n calculateMarkrMinimumAmountOut,\n getAdditiveSourceAssetFeeAmount,\n isTokenAddressNative,\n} from '../_utils';\nimport { isEvmSwapResponse, isHyperliquidWithdrawSwapResponse, isSolanaSwapResponse } from '../_type-guards';\nimport { SOLANA_REQUIRED_CONFIRMATIONS } from '../constants';\nimport { _estimateGasFromSwapResponse } from './estimate-native-fee';\nimport { _executeHyperliquidWithdraw } from './transfer-asset-hyperliquid-withdraw';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport { refreshSolanaSwapTransactionBlockhash } from '../../../utils/solana';\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 (sourceChainId === HyperliquidChainIds.MAINNET) {\n return _executeHyperliquidWithdrawTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n onStepChange,\n });\n }\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// Hyperliquid withdrawal path — wires `markrSwap` → HL handler\n// ---------------------------------------------------------------------------\n\ninterface HyperliquidWithdrawTransferParams {\n apiOptions: ApiOptions;\n appId: string;\n environment: Environment;\n evmSigner: EvmSigner;\n quote: Parameters<TransferService['transferAsset']>[0]['quote'];\n onStepChange?: Parameters<TransferService['transferAsset']>[0]['onStepChange'];\n}\n\nasync function _executeHyperliquidWithdrawTransfer({\n apiOptions,\n appId,\n environment,\n evmSigner,\n quote,\n onStepChange,\n}: HyperliquidWithdrawTransferParams): Promise<Transfer> {\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 uuid: quote.id,\n });\n\n if (!isHyperliquidWithdrawSwapResponse(swap)) {\n throw new SdkError(ErrorReason.CHAIN_NOT_SUPPORTED, ErrorCode.INVALID_PARAMS, {\n details:\n 'Expected `hyperliquid-withdraw` swap response from Markr for Hyperliquid source chain, but received a different variant.',\n });\n }\n\n return _executeHyperliquidWithdraw({\n apiOptions,\n environment,\n evmSigner,\n quote,\n swap,\n onStepChange,\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 const allowanceAmount = quote.amountIn + getAdditiveSourceAssetFeeAmount(quote);\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 const approvalRequest: EvmTransactionRequest | undefined =\n !isTokenInNative && spenderAddress\n ? await buildErc20ApprovalRequest({\n chainIdHex: caip2ToEip155HexChainId(quote.sourceChain.chainId),\n client: sourceClient,\n gasSettings,\n owner: fromAddress,\n requiredAllowance: allowanceAmount,\n spender: spenderAddress,\n token: tokenInAddress,\n })\n : undefined;\n const requiresApprovalSignature = approvalRequest !== undefined;\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 ...maybe1559(gasSettings),\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 try {\n await signApprovalAndAssertConfirmed({\n client: sourceClient,\n evmSigner,\n onStepChange,\n request: approvalRequest,\n step: {\n currentSignature: 1,\n currentSignatureReason: TransferSignatureReason.AllowanceApproval,\n quote,\n requiredSignatures: 2,\n },\n });\n } catch (error) {\n // Match the original behavior of \"branch only on the confirmed-then-\n // reverted receipt status\" by discriminating on the dedicated error\n // class — signer rejection / RPC errors fall through to the rethrow.\n if (error instanceof ApprovalRevertedError) {\n return makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'ERC20 approval transaction was reverted',\n });\n }\n throw error;\n }\n }\n\n const swapGasWithMargin = await _estimateGasFromSwapResponse({\n crossChain: isCrossChainSwap,\n fromAddress,\n feeUnitsMarginBps: gasSettings?.estimateGasMarginBps,\n gasLimit: _getGasLimit(quote),\n sourceClient,\n swap,\n });\n\n const bigBlocksResult = await maybeEnableHyperEvmBigBlocks({\n environment,\n evmSigner,\n fromAddress,\n onStepChange,\n quote,\n requiresApprovalSignature,\n swapGasWithMargin,\n });\n\n if (!bigBlocksResult.ok) {\n return bigBlocksResult.transfer;\n }\n\n const { requiredSignatures } = bigBlocksResult;\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 ...maybe1559(gasSettings),\n };\n\n const step: TransferStepDetails = {\n currentSignature: requiredSignatures,\n currentSignatureReason: TransferSignatureReason.TokensTransfer,\n quote,\n requiredSignatures,\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. HyperEVM is excluded:\n * heavy routes may need a prior `evmUserModify` big-blocks signature that\n * cannot be folded into `signBatch`, and the batch path returns before gas\n * estimation / big-block enablement.\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 sourceChainId !== HyperEvmChainIds.MAINNET &&\n requiresApprovalSignature &&\n approvalRequest !== undefined &&\n typeof signBatch === 'function'\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../constants.cjs`),t=require(`../../errors.cjs`),n=require(`../../utils/caip.cjs`),r=require(`../_utils.cjs`),i=require(`./_hyperliquid-l1-action.cjs`);function a(t){if(n.caip2ToEip155ChainId(t.sourceChain.chainId)===999)return e.HYPEREVM_BIG_BLOCK_GAS_LIMIT}async function o({quote:a,swapGasWithMargin:o,requiresApprovalSignature:s,fromAddress:c,environment:l,evmSigner:u,onStepChange:d}){let f=n.caip2ToEip155ChainId(a.sourceChain.chainId),p=f===999&&o>2000000n,m=(s?1:0)+(p?1:0)+1;if(!p)return{ok:!0,requiredSignatures:m};if(!u.signTypedData)throw new t.SdkError(`HyperEVM swaps above the small-block gas limit require an EIP-712 typed-data signer to enable big blocks.`,t.ErrorCode.SIGNING_FAILED,{details:`EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.`});let h={currentSignature:(s?1:0)+1,currentSignatureReason:e.TransferSignatureReason.HyperEvmEnableBigBlocks,quote:a,requiredSignatures:m};d?.(h);let g;try{g=await i.enableHyperEvmBigBlocks({address:c,chainId:f,environment:l,evmSigner:u,step:h})}catch(e){if(e instanceof t.HttpError)return{ok:!1,transfer:r.makeFailedTransferFromQuote(a,{environment:l,errorCode:t.ErrorCode.HL_BIG_BLOCKS_FAILED,errorReason:`Failed to enable HyperEVM big blocks (HTTP ${e.status}). Please retry.`})};throw e}return g.status===`ok`?{ok:!0,requiredSignatures:m}:{ok:!1,transfer:r.makeFailedTransferFromQuote(a,{environment:l,errorCode:t.ErrorCode.HL_BIG_BLOCKS_FAILED,errorReason:`Hyperliquid rejected the big-blocks enablement. Please retry.`})}}exports._getGasLimit=a,exports.maybeEnableHyperEvmBigBlocks=o;
2
+ //# sourceMappingURL=_hyperevm.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_hyperevm.cjs","names":["caip2ToEip155ChainId","HYPEREVM_BIG_BLOCK_GAS_LIMIT","SdkError","ErrorCode","TransferSignatureReason","enableHyperEvmBigBlocks","HttpError","makeFailedTransferFromQuote"],"sources":["../../../src/transfer-service/markr/_hyperevm.ts"],"sourcesContent":["/**\n * HyperEVM-specific transfer helpers — gas-limit selection for estimation and\n * just-in-time big-block enablement. Kept out of the generic Markr transfer /\n * fee paths so chain-specific dual-block logic stays encapsulated.\n */\nimport type { Address as EvmAddress } from 'viem';\nimport {\n Environment,\n HYPEREVM_BIG_BLOCK_GAS_LIMIT,\n HYPEREVM_CHAIN_ID,\n HYPEREVM_SMALL_BLOCK_GAS_LIMIT,\n TransferSignatureReason,\n} from '../../constants';\nimport { ErrorCode, HttpError, SdkError } from '../../errors';\nimport type { Quote } from '../../types/quote';\nimport type { EvmSigner } from '../../types/signer';\nimport type { FailedTransfer, TransferStepDetails } from '../../types/transfer';\nimport { caip2ToEip155ChainId } from '../../utils/caip';\nimport { makeFailedTransferFromQuote } from '../_utils';\nimport { enableHyperEvmBigBlocks } from './_hyperliquid-l1-action';\n\n/**\n * Explicit `gas` (gas limit) upper bound for `eth_estimateGas`, when a chain\n * needs one. HyperEVM: big-block ceiling so heavy routes don't revert against\n * the small-block search cap. Other chains: `undefined` (node default).\n *\n * @internal\n */\nexport function _getGasLimit(quote: Quote): bigint | undefined {\n if (caip2ToEip155ChainId(quote.sourceChain.chainId) === HYPEREVM_CHAIN_ID) {\n return HYPEREVM_BIG_BLOCK_GAS_LIMIT;\n }\n return undefined;\n}\n\nexport type MaybeEnableHyperEvmBigBlocksResult =\n | { readonly ok: true; readonly requiredSignatures: number }\n | { readonly ok: false; readonly transfer: FailedTransfer };\n\nexport interface MaybeEnableHyperEvmBigBlocksParams {\n readonly quote: Quote;\n readonly swapGasWithMargin: bigint;\n readonly requiresApprovalSignature: boolean;\n readonly fromAddress: EvmAddress;\n readonly environment: Environment;\n readonly evmSigner: EvmSigner;\n readonly onStepChange?: (step: TransferStepDetails) => void;\n}\n\n/**\n * On HyperEVM, when the estimated swap gas exceeds the small-block ceiling,\n * sign and submit `evmUserModify { usingBigBlocks: true }` before the swap.\n * Cheap HyperEVM routes and all other chains are a no-op.\n *\n * @internal\n */\nexport async function maybeEnableHyperEvmBigBlocks({\n quote,\n swapGasWithMargin,\n requiresApprovalSignature,\n fromAddress,\n environment,\n evmSigner,\n onStepChange,\n}: MaybeEnableHyperEvmBigBlocksParams): Promise<MaybeEnableHyperEvmBigBlocksResult> {\n const sourceEvmChainId = caip2ToEip155ChainId(quote.sourceChain.chainId);\n const needsBigBlocks = sourceEvmChainId === HYPEREVM_CHAIN_ID && swapGasWithMargin > HYPEREVM_SMALL_BLOCK_GAS_LIMIT;\n\n const requiredSignatures = (requiresApprovalSignature ? 1 : 0) + (needsBigBlocks ? 1 : 0) + 1;\n\n if (!needsBigBlocks) {\n return { ok: true, requiredSignatures };\n }\n\n if (!evmSigner.signTypedData) {\n throw new SdkError(\n 'HyperEVM swaps above the small-block gas limit require an EIP-712 typed-data signer to enable big blocks.',\n ErrorCode.SIGNING_FAILED,\n {\n details: 'EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.',\n },\n );\n }\n\n const bigBlocksStep: TransferStepDetails = {\n currentSignature: (requiresApprovalSignature ? 1 : 0) + 1,\n currentSignatureReason: TransferSignatureReason.HyperEvmEnableBigBlocks,\n quote,\n requiredSignatures,\n };\n\n onStepChange?.(bigBlocksStep);\n\n let bigBlocksResponse;\n try {\n bigBlocksResponse = await enableHyperEvmBigBlocks({\n address: fromAddress,\n chainId: sourceEvmChainId,\n environment,\n evmSigner,\n step: bigBlocksStep,\n });\n } catch (error) {\n // Surface as a failed transfer (no on-chain cost paid yet) so the UI can\n // prompt a retry rather than crashing the panel.\n if (error instanceof HttpError) {\n return {\n ok: false,\n transfer: makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.HL_BIG_BLOCKS_FAILED,\n errorReason: `Failed to enable HyperEVM big blocks (HTTP ${error.status}). Please retry.`,\n }),\n };\n }\n throw error;\n }\n\n if (bigBlocksResponse.status !== 'ok') {\n return {\n ok: false,\n transfer: makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.HL_BIG_BLOCKS_FAILED,\n errorReason: 'Hyperliquid rejected the big-blocks enablement. Please retry.',\n }),\n };\n }\n\n return { ok: true, requiredSignatures };\n}\n"],"mappings":"4KA4BA,SAAgB,EAAa,EAAkC,CAC7D,GAAIA,EAAAA,qBAAqB,EAAM,YAAY,QAAQ,GAAA,IACjD,OAAOC,EAAAA,6BA0BX,eAAsB,EAA6B,CACjD,QACA,oBACA,4BACA,cACA,cACA,YACA,gBACkF,CAClF,IAAM,EAAmBD,EAAAA,qBAAqB,EAAM,YAAY,QAAQ,CAClE,EAAiB,IAAA,KAA0C,EAAA,SAE3D,GAAsB,EAA4B,EAAI,IAAM,EAAiB,EAAI,GAAK,EAE5F,GAAI,CAAC,EACH,MAAO,CAAE,GAAI,GAAM,qBAAoB,CAGzC,GAAI,CAAC,EAAU,cACb,MAAM,IAAIE,EAAAA,SACR,4GACAC,EAAAA,UAAU,eACV,CACE,QAAS,qGACV,CACF,CAGH,IAAM,EAAqC,CACzC,kBAAmB,EAA4B,EAAI,GAAK,EACxD,uBAAwBC,EAAAA,wBAAwB,wBAChD,QACA,qBACD,CAED,IAAe,EAAc,CAE7B,IAAI,EACJ,GAAI,CACF,EAAoB,MAAMC,EAAAA,wBAAwB,CAChD,QAAS,EACT,QAAS,EACT,cACA,YACA,KAAM,EACP,CAAC,OACK,EAAO,CAGd,GAAI,aAAiBC,EAAAA,UACnB,MAAO,CACL,GAAI,GACJ,SAAUC,EAAAA,4BAA4B,EAAO,CAC3C,cACA,UAAWJ,EAAAA,UAAU,qBACrB,YAAa,8CAA8C,EAAM,OAAO,kBACzE,CAAC,CACH,CAEH,MAAM,EAcR,OAXI,EAAkB,SAAW,KAW1B,CAAE,GAAI,GAAM,qBAAoB,CAV9B,CACL,GAAI,GACJ,SAAUI,EAAAA,4BAA4B,EAAO,CAC3C,cACA,UAAWJ,EAAAA,UAAU,qBACrB,YAAa,gEACd,CAAC,CACH"}
@@ -0,0 +1,2 @@
1
+ import{HYPEREVM_BIG_BLOCK_GAS_LIMIT as e,TransferSignatureReason as t}from"../../constants.js";import{ErrorCode as n,HttpError as r,SdkError as i}from"../../errors.js";import{caip2ToEip155ChainId as a}from"../../utils/caip.js";import{makeFailedTransferFromQuote as o}from"../_utils.js";import{enableHyperEvmBigBlocks as s}from"./_hyperliquid-l1-action.js";function c(t){if(a(t.sourceChain.chainId)===999)return e}async function l({quote:e,swapGasWithMargin:c,requiresApprovalSignature:l,fromAddress:u,environment:d,evmSigner:f,onStepChange:p}){let m=a(e.sourceChain.chainId),h=m===999&&c>2000000n,g=(l?1:0)+(h?1:0)+1;if(!h)return{ok:!0,requiredSignatures:g};if(!f.signTypedData)throw new i(`HyperEVM swaps above the small-block gas limit require an EIP-712 typed-data signer to enable big blocks.`,n.SIGNING_FAILED,{details:`EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.`});let _={currentSignature:(l?1:0)+1,currentSignatureReason:t.HyperEvmEnableBigBlocks,quote:e,requiredSignatures:g};p?.(_);let v;try{v=await s({address:u,chainId:m,environment:d,evmSigner:f,step:_})}catch(t){if(t instanceof r)return{ok:!1,transfer:o(e,{environment:d,errorCode:n.HL_BIG_BLOCKS_FAILED,errorReason:`Failed to enable HyperEVM big blocks (HTTP ${t.status}). Please retry.`})};throw t}return v.status===`ok`?{ok:!0,requiredSignatures:g}:{ok:!1,transfer:o(e,{environment:d,errorCode:n.HL_BIG_BLOCKS_FAILED,errorReason:`Hyperliquid rejected the big-blocks enablement. Please retry.`})}}export{c as _getGasLimit,l as maybeEnableHyperEvmBigBlocks};
2
+ //# sourceMappingURL=_hyperevm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_hyperevm.js","names":[],"sources":["../../../src/transfer-service/markr/_hyperevm.ts"],"sourcesContent":["/**\n * HyperEVM-specific transfer helpers — gas-limit selection for estimation and\n * just-in-time big-block enablement. Kept out of the generic Markr transfer /\n * fee paths so chain-specific dual-block logic stays encapsulated.\n */\nimport type { Address as EvmAddress } from 'viem';\nimport {\n Environment,\n HYPEREVM_BIG_BLOCK_GAS_LIMIT,\n HYPEREVM_CHAIN_ID,\n HYPEREVM_SMALL_BLOCK_GAS_LIMIT,\n TransferSignatureReason,\n} from '../../constants';\nimport { ErrorCode, HttpError, SdkError } from '../../errors';\nimport type { Quote } from '../../types/quote';\nimport type { EvmSigner } from '../../types/signer';\nimport type { FailedTransfer, TransferStepDetails } from '../../types/transfer';\nimport { caip2ToEip155ChainId } from '../../utils/caip';\nimport { makeFailedTransferFromQuote } from '../_utils';\nimport { enableHyperEvmBigBlocks } from './_hyperliquid-l1-action';\n\n/**\n * Explicit `gas` (gas limit) upper bound for `eth_estimateGas`, when a chain\n * needs one. HyperEVM: big-block ceiling so heavy routes don't revert against\n * the small-block search cap. Other chains: `undefined` (node default).\n *\n * @internal\n */\nexport function _getGasLimit(quote: Quote): bigint | undefined {\n if (caip2ToEip155ChainId(quote.sourceChain.chainId) === HYPEREVM_CHAIN_ID) {\n return HYPEREVM_BIG_BLOCK_GAS_LIMIT;\n }\n return undefined;\n}\n\nexport type MaybeEnableHyperEvmBigBlocksResult =\n | { readonly ok: true; readonly requiredSignatures: number }\n | { readonly ok: false; readonly transfer: FailedTransfer };\n\nexport interface MaybeEnableHyperEvmBigBlocksParams {\n readonly quote: Quote;\n readonly swapGasWithMargin: bigint;\n readonly requiresApprovalSignature: boolean;\n readonly fromAddress: EvmAddress;\n readonly environment: Environment;\n readonly evmSigner: EvmSigner;\n readonly onStepChange?: (step: TransferStepDetails) => void;\n}\n\n/**\n * On HyperEVM, when the estimated swap gas exceeds the small-block ceiling,\n * sign and submit `evmUserModify { usingBigBlocks: true }` before the swap.\n * Cheap HyperEVM routes and all other chains are a no-op.\n *\n * @internal\n */\nexport async function maybeEnableHyperEvmBigBlocks({\n quote,\n swapGasWithMargin,\n requiresApprovalSignature,\n fromAddress,\n environment,\n evmSigner,\n onStepChange,\n}: MaybeEnableHyperEvmBigBlocksParams): Promise<MaybeEnableHyperEvmBigBlocksResult> {\n const sourceEvmChainId = caip2ToEip155ChainId(quote.sourceChain.chainId);\n const needsBigBlocks = sourceEvmChainId === HYPEREVM_CHAIN_ID && swapGasWithMargin > HYPEREVM_SMALL_BLOCK_GAS_LIMIT;\n\n const requiredSignatures = (requiresApprovalSignature ? 1 : 0) + (needsBigBlocks ? 1 : 0) + 1;\n\n if (!needsBigBlocks) {\n return { ok: true, requiredSignatures };\n }\n\n if (!evmSigner.signTypedData) {\n throw new SdkError(\n 'HyperEVM swaps above the small-block gas limit require an EIP-712 typed-data signer to enable big blocks.',\n ErrorCode.SIGNING_FAILED,\n {\n details: 'EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.',\n },\n );\n }\n\n const bigBlocksStep: TransferStepDetails = {\n currentSignature: (requiresApprovalSignature ? 1 : 0) + 1,\n currentSignatureReason: TransferSignatureReason.HyperEvmEnableBigBlocks,\n quote,\n requiredSignatures,\n };\n\n onStepChange?.(bigBlocksStep);\n\n let bigBlocksResponse;\n try {\n bigBlocksResponse = await enableHyperEvmBigBlocks({\n address: fromAddress,\n chainId: sourceEvmChainId,\n environment,\n evmSigner,\n step: bigBlocksStep,\n });\n } catch (error) {\n // Surface as a failed transfer (no on-chain cost paid yet) so the UI can\n // prompt a retry rather than crashing the panel.\n if (error instanceof HttpError) {\n return {\n ok: false,\n transfer: makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.HL_BIG_BLOCKS_FAILED,\n errorReason: `Failed to enable HyperEVM big blocks (HTTP ${error.status}). Please retry.`,\n }),\n };\n }\n throw error;\n }\n\n if (bigBlocksResponse.status !== 'ok') {\n return {\n ok: false,\n transfer: makeFailedTransferFromQuote(quote, {\n environment,\n errorCode: ErrorCode.HL_BIG_BLOCKS_FAILED,\n errorReason: 'Hyperliquid rejected the big-blocks enablement. Please retry.',\n }),\n };\n }\n\n return { ok: true, requiredSignatures };\n}\n"],"mappings":"oWA4BA,SAAgB,EAAa,EAAkC,CAC7D,GAAI,EAAqB,EAAM,YAAY,QAAQ,GAAA,IACjD,OAAO,EA0BX,eAAsB,EAA6B,CACjD,QACA,oBACA,4BACA,cACA,cACA,YACA,gBACkF,CAClF,IAAM,EAAmB,EAAqB,EAAM,YAAY,QAAQ,CAClE,EAAiB,IAAA,KAA0C,EAAA,SAE3D,GAAsB,EAA4B,EAAI,IAAM,EAAiB,EAAI,GAAK,EAE5F,GAAI,CAAC,EACH,MAAO,CAAE,GAAI,GAAM,qBAAoB,CAGzC,GAAI,CAAC,EAAU,cACb,MAAM,IAAI,EACR,4GACA,EAAU,eACV,CACE,QAAS,qGACV,CACF,CAGH,IAAM,EAAqC,CACzC,kBAAmB,EAA4B,EAAI,GAAK,EACxD,uBAAwB,EAAwB,wBAChD,QACA,qBACD,CAED,IAAe,EAAc,CAE7B,IAAI,EACJ,GAAI,CACF,EAAoB,MAAM,EAAwB,CAChD,QAAS,EACT,QAAS,EACT,cACA,YACA,KAAM,EACP,CAAC,OACK,EAAO,CAGd,GAAI,aAAiB,EACnB,MAAO,CACL,GAAI,GACJ,SAAU,EAA4B,EAAO,CAC3C,cACA,UAAW,EAAU,qBACrB,YAAa,8CAA8C,EAAM,OAAO,kBACzE,CAAC,CACH,CAEH,MAAM,EAcR,OAXI,EAAkB,SAAW,KAW1B,CAAE,GAAI,GAAM,qBAAoB,CAV9B,CACL,GAAI,GACJ,SAAU,EAA4B,EAAO,CAC3C,cACA,UAAW,EAAU,qBACrB,YAAa,gEACd,CAAC,CACH"}
@@ -0,0 +1 @@
1
+ import { Address } from "viem";
@@ -0,0 +1,2 @@
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../constants.cjs`),t=require(`../../errors.cjs`),n=require(`./_hyperliquid.cjs`);let r=require(`viem`),i=require(`@msgpack/msgpack`);const a=BigInt(2**53-1),o={name:`Exchange`,version:`1`,chainId:1337,verifyingContract:`0x0000000000000000000000000000000000000000`},s={Agent:[{name:`source`,type:`string`},{name:`connectionId`,type:`bytes32`}]};function c(e){return{type:`evmUserModify`,usingBigBlocks:e}}function l(e,t){return(0,r.keccak256)((0,r.concat)([(0,i.encode)(e),(0,r.numberToBytes)(t,{size:8}),Uint8Array.from([0])]))}function u(e,t){return{domain:o,types:s,primaryType:`Agent`,message:{source:t?`a`:`b`,connectionId:e}}}async function d({evmSigner:r,environment:i,address:o,chainId:s,usingBigBlocks:d=!0,nonce:f,fetch:p,signal:m,step:h}){if(!r.signTypedData)throw new t.SdkError(`Enabling HyperEVM big blocks requires an EIP-712 typed-data signer.`,t.ErrorCode.SIGNING_FAILED,{details:`EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.`});let g=i===e.Environment.PROD,_=f??BigInt(Date.now());if(_<0n||_>a)throw new t.InvalidParamsError(`Hyperliquid L1 action nonce must be a non-negative integer within Number.MAX_SAFE_INTEGER.`,`Received nonce ${_.toString()}.`);let v=c(d),y=u(l(v,_),g),b=await r.signTypedData({typedData:y,address:o,chainId:s},h);return n.hyperliquidExchangePost({apiBaseUrl:n.hyperliquidApiBaseUrlForEnvironment(i),signature:b,nonce:_,action:v,fetch:p,signal:m})}exports.buildEvmUserModifyAction=c,exports.enableHyperEvmBigBlocks=d;
2
+ //# sourceMappingURL=_hyperliquid-l1-action.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_hyperliquid-l1-action.cjs","names":["SdkError","ErrorCode","Environment","InvalidParamsError","hyperliquidExchangePost","hyperliquidApiBaseUrlForEnvironment"],"sources":["../../../src/transfer-service/markr/_hyperliquid-l1-action.ts"],"sourcesContent":["/**\n * Hyperliquid **L1-action** signing for `evmUserModify` — the HyperEVM\n * \"big blocks\" toggle.\n *\n * This is a different signing scheme from the user-signed `sendAsset` action in\n * `_hyperliquid-eip712.ts`. L1 actions use Hyperliquid's \"phantom agent\" flow:\n *\n * 1. msgpack-encode the `action` object.\n * 2. keccak256 over `msgpack(action) ++ nonce(8B big-endian) ++ vault/expiry\n * flags` → a 32-byte `connectionId`.\n * 3. EIP-712 sign an `Agent { source, connectionId }` struct under a FIXED\n * domain (`name: \"Exchange\"`, `version: \"1\"`, `chainId: 1337`,\n * `verifyingContract: 0x0`). Mainnet vs testnet is carried in `source`\n * (`\"a\"` | `\"b\"`), NOT the domain chainId — the domain chainId is always\n * 1337 for L1 actions.\n * 4. POST `{ action, nonce, signature }` to `/exchange`.\n *\n * Why this exists: HyperEVM (chain 999) produces two block types — small\n * (\"fast\") blocks capped at ~2M gas, and big blocks at 30M gas. Small blocks\n * are the default, so a multi-hop swap (~4M gas) is rejected with\n * \"exceeds block gas limit\". `evmUserModify { usingBigBlocks: true }` opts the\n * address into big blocks (persistent, per-address) so those swaps land.\n *\n * Refs:\n * - https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/signing\n * - https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture\n */\nimport { concat, keccak256, numberToBytes, type Address as EvmAddress, type Hex } from 'viem';\nimport { encode as msgpackEncode } from '@msgpack/msgpack';\nimport { Environment } from '../../constants';\nimport { ErrorCode, InvalidParamsError, SdkError } from '../../errors';\nimport type { EvmSigner, EvmTypedData } from '../../types/signer';\nimport type { TransferStepDetails } from '../../types/transfer';\nimport type { Fetch } from '../../types/utility-types';\nimport {\n hyperliquidApiBaseUrlForEnvironment,\n hyperliquidExchangePost,\n type HyperliquidExchangeResponse,\n} from './_hyperliquid';\n\n/** L1 nonce must fit a JSON Number without precision loss (`Number(nonce)` on the wire). */\nconst MAX_L1_ACTION_NONCE = BigInt(Number.MAX_SAFE_INTEGER);\n\n/** L1-action EIP-712 domain — fixed for ALL Hyperliquid L1 actions. */\nconst HL_L1_ACTION_DOMAIN = {\n name: 'Exchange',\n version: '1',\n chainId: 1337,\n verifyingContract: '0x0000000000000000000000000000000000000000',\n} as const satisfies EvmTypedData['domain'];\n\nconst HL_AGENT_TYPES = {\n Agent: [\n { name: 'source', type: 'string' },\n { name: 'connectionId', type: 'bytes32' },\n ],\n} as const;\n\nconst HL_AGENT_PRIMARY_TYPE = 'Agent' as const;\n\nexport interface EvmUserModifyAction extends Record<string, unknown> {\n readonly type: 'evmUserModify';\n readonly usingBigBlocks: boolean;\n}\n\n/**\n * Build the `evmUserModify` L1 action.\n *\n * Field order is significant — the signature is over the msgpack encoding, so\n * `type` MUST precede `usingBigBlocks` (matches Hyperliquid's reference SDKs).\n */\nexport function buildEvmUserModifyAction(usingBigBlocks: boolean): EvmUserModifyAction {\n return { type: 'evmUserModify', usingBigBlocks };\n}\n\n/**\n * Compute the Hyperliquid L1-action hash (a.k.a. `connectionId`).\n *\n * `keccak256( msgpack(action) ++ nonce[8B big-endian] ++ 0x00 )`.\n *\n * The trailing `0x00` is the \"no vault address\" flag. We never use a vault or\n * an `expiresAfter` for `evmUserModify`, so nothing else is appended — this\n * MUST stay in lock-step with the body sent to `/exchange` (which likewise\n * omits `vaultAddress`/`expiresAfter`), or Hyperliquid recomputes a different\n * hash and rejects the signature.\n */\nexport function computeL1ActionHash(action: Record<string, unknown>, nonce: bigint): Hex {\n const actionBytes = msgpackEncode(action);\n const nonceBytes = numberToBytes(nonce, { size: 8 });\n const noVaultFlag = Uint8Array.from([0x00]);\n\n return keccak256(concat([actionBytes, nonceBytes, noVaultFlag]));\n}\n\n/** Build the phantom-agent EIP-712 typed data for an L1 action hash. */\nexport function buildL1ActionAgentTypedData(connectionId: Hex, isMainnet: boolean): EvmTypedData {\n return {\n domain: HL_L1_ACTION_DOMAIN,\n types: HL_AGENT_TYPES,\n primaryType: HL_AGENT_PRIMARY_TYPE,\n message: {\n // \"a\" = mainnet, \"b\" = testnet. This is how L1 actions encode the\n // network — the domain chainId stays 1337 in both cases.\n source: isMainnet ? 'a' : 'b',\n connectionId,\n },\n };\n}\n\nexport interface EnableHyperEvmBigBlocksParams {\n readonly evmSigner: EvmSigner;\n readonly environment: Environment;\n /** Address opting into big blocks (the swap's `fromAddress`). */\n readonly address: EvmAddress;\n /**\n * EVM chainId forwarded to the wallet's `signTypedData` for routing/context\n * (the HyperEVM chain the user is on, e.g. 999). NOT the EIP-712 domain\n * chainId — that is fixed at 1337 inside the typed data.\n */\n readonly chainId: number;\n /** Defaults to `true`. Pass `false` to opt back out of big blocks. */\n readonly usingBigBlocks?: boolean;\n /** Millisecond nonce. Defaults to `Date.now()`. */\n readonly nonce?: bigint;\n readonly fetch?: Fetch;\n readonly signal?: AbortSignal;\n readonly step: TransferStepDetails;\n}\n\n/**\n * Sign and submit `evmUserModify { usingBigBlocks }` to Hyperliquid's\n * `/exchange` endpoint, opting the address into (or out of) HyperEVM big blocks.\n *\n * Requires `evmSigner.signTypedData` — throws {@link SdkError} with\n * `SIGNING_FAILED` if it isn't wired. The returned response's `status` is\n * `\"ok\"` on success; callers should treat `\"err\"` as a failure.\n */\nexport async function enableHyperEvmBigBlocks({\n evmSigner,\n environment,\n address,\n chainId,\n usingBigBlocks = true,\n nonce,\n fetch: customFetch,\n signal,\n step,\n}: EnableHyperEvmBigBlocksParams): Promise<HyperliquidExchangeResponse> {\n if (!evmSigner.signTypedData) {\n throw new SdkError(\n 'Enabling HyperEVM big blocks requires an EIP-712 typed-data signer.',\n ErrorCode.SIGNING_FAILED,\n {\n details: 'EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.',\n },\n );\n }\n\n const isMainnet = environment === Environment.PROD;\n const actionNonce = nonce ?? BigInt(Date.now());\n\n if (actionNonce < 0n || actionNonce > MAX_L1_ACTION_NONCE) {\n throw new InvalidParamsError(\n 'Hyperliquid L1 action nonce must be a non-negative integer within Number.MAX_SAFE_INTEGER.',\n `Received nonce ${actionNonce.toString()}.`,\n );\n }\n\n const action = buildEvmUserModifyAction(usingBigBlocks);\n const connectionId = computeL1ActionHash(action, actionNonce);\n const typedData = buildL1ActionAgentTypedData(connectionId, isMainnet);\n\n const signature = await evmSigner.signTypedData({ typedData, address, chainId }, step);\n\n return hyperliquidExchangePost({\n apiBaseUrl: hyperliquidApiBaseUrlForEnvironment(environment),\n signature,\n nonce: actionNonce,\n action,\n fetch: customFetch,\n signal,\n });\n}\n"],"mappings":"yMAyCA,MAAM,EAAsB,eAA+B,CAGrD,EAAsB,CAC1B,KAAM,WACN,QAAS,IACT,QAAS,KACT,kBAAmB,6CACpB,CAEK,EAAiB,CACrB,MAAO,CACL,CAAE,KAAM,SAAU,KAAM,SAAU,CAClC,CAAE,KAAM,eAAgB,KAAM,UAAW,CAC1C,CACF,CAeD,SAAgB,EAAyB,EAA8C,CACrF,MAAO,CAAE,KAAM,gBAAiB,iBAAgB,CAclD,SAAgB,EAAoB,EAAiC,EAAoB,CAKvF,OAAA,EAAA,EAAA,YAAA,EAAA,EAAA,QAAwB,cAJU,EAAO,qBACR,EAAO,CAAE,KAAM,EAAG,CAAC,CAChC,WAAW,KAAK,CAAC,EAAK,CAAC,CAEmB,CAAC,CAAC,CAIlE,SAAgB,EAA4B,EAAmB,EAAkC,CAC/F,MAAO,CACL,OAAQ,EACR,MAAO,EACP,YAAa,QACb,QAAS,CAGP,OAAQ,EAAY,IAAM,IAC1B,eACD,CACF,CA+BH,eAAsB,EAAwB,CAC5C,YACA,cACA,UACA,UACA,iBAAiB,GACjB,QACA,MAAO,EACP,SACA,QACsE,CACtE,GAAI,CAAC,EAAU,cACb,MAAM,IAAIA,EAAAA,SACR,sEACAC,EAAAA,UAAU,eACV,CACE,QAAS,qGACV,CACF,CAGH,IAAM,EAAY,IAAgBC,EAAAA,YAAY,KACxC,EAAc,GAAS,OAAO,KAAK,KAAK,CAAC,CAE/C,GAAI,EAAc,IAAM,EAAc,EACpC,MAAM,IAAIC,EAAAA,mBACR,6FACA,kBAAkB,EAAY,UAAU,CAAC,GAC1C,CAGH,IAAM,EAAS,EAAyB,EAAe,CAEjD,EAAY,EADG,EAAoB,EAAQ,EAAY,CACD,EAAU,CAEhE,EAAY,MAAM,EAAU,cAAc,CAAE,YAAW,UAAS,UAAS,CAAE,EAAK,CAEtF,OAAOC,EAAAA,wBAAwB,CAC7B,WAAYC,EAAAA,oCAAoC,EAAY,CAC5D,YACA,MAAO,EACP,SACA,MAAO,EACP,SACD,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Environment } from "../../constants.cjs";
2
+ import { Fetch } from "../../types/utility-types.cjs";
3
+ import { TransferStepDetails } from "../../types/transfer.cjs";
4
+ import { EvmSigner } from "../../types/signer.cjs";
5
+ import { HyperliquidExchangeResponse } from "./_hyperliquid-schema.cjs";
6
+ import { Address } from "viem";
7
+
8
+ //#region src/transfer-service/markr/_hyperliquid-l1-action.d.ts
9
+ interface EvmUserModifyAction extends Record<string, unknown> {
10
+ readonly type: "evmUserModify";
11
+ readonly usingBigBlocks: boolean;
12
+ }
13
+ /**
14
+ * Build the `evmUserModify` L1 action.
15
+ *
16
+ * Field order is significant — the signature is over the msgpack encoding, so
17
+ * `type` MUST precede `usingBigBlocks` (matches Hyperliquid's reference SDKs).
18
+ */
19
+ declare function buildEvmUserModifyAction(usingBigBlocks: boolean): EvmUserModifyAction;
20
+ interface EnableHyperEvmBigBlocksParams {
21
+ readonly evmSigner: EvmSigner;
22
+ readonly environment: Environment;
23
+ /** Address opting into big blocks (the swap's `fromAddress`). */
24
+ readonly address: Address;
25
+ /**
26
+ * EVM chainId forwarded to the wallet's `signTypedData` for routing/context
27
+ * (the HyperEVM chain the user is on, e.g. 999). NOT the EIP-712 domain
28
+ * chainId — that is fixed at 1337 inside the typed data.
29
+ */
30
+ readonly chainId: number;
31
+ /** Defaults to `true`. Pass `false` to opt back out of big blocks. */
32
+ readonly usingBigBlocks?: boolean;
33
+ /** Millisecond nonce. Defaults to `Date.now()`. */
34
+ readonly nonce?: bigint;
35
+ readonly fetch?: Fetch;
36
+ readonly signal?: AbortSignal;
37
+ readonly step: TransferStepDetails;
38
+ }
39
+ /**
40
+ * Sign and submit `evmUserModify { usingBigBlocks }` to Hyperliquid's
41
+ * `/exchange` endpoint, opting the address into (or out of) HyperEVM big blocks.
42
+ *
43
+ * Requires `evmSigner.signTypedData` — throws {@link SdkError} with
44
+ * `SIGNING_FAILED` if it isn't wired. The returned response's `status` is
45
+ * `"ok"` on success; callers should treat `"err"` as a failure.
46
+ */
47
+ declare function enableHyperEvmBigBlocks({
48
+ evmSigner,
49
+ environment,
50
+ address,
51
+ chainId,
52
+ usingBigBlocks,
53
+ nonce,
54
+ fetch: customFetch,
55
+ signal,
56
+ step
57
+ }: EnableHyperEvmBigBlocksParams): Promise<HyperliquidExchangeResponse>;
58
+ //#endregion
59
+ export { EnableHyperEvmBigBlocksParams, EvmUserModifyAction, buildEvmUserModifyAction, enableHyperEvmBigBlocks };
60
+ //# sourceMappingURL=_hyperliquid-l1-action.d.cts.map
@@ -0,0 +1,60 @@
1
+ import { Environment } from "../../constants.js";
2
+ import { Fetch } from "../../types/utility-types.js";
3
+ import { TransferStepDetails } from "../../types/transfer.js";
4
+ import { EvmSigner } from "../../types/signer.js";
5
+ import { HyperliquidExchangeResponse } from "./_hyperliquid-schema.js";
6
+ import { Address } from "viem";
7
+
8
+ //#region src/transfer-service/markr/_hyperliquid-l1-action.d.ts
9
+ interface EvmUserModifyAction extends Record<string, unknown> {
10
+ readonly type: "evmUserModify";
11
+ readonly usingBigBlocks: boolean;
12
+ }
13
+ /**
14
+ * Build the `evmUserModify` L1 action.
15
+ *
16
+ * Field order is significant — the signature is over the msgpack encoding, so
17
+ * `type` MUST precede `usingBigBlocks` (matches Hyperliquid's reference SDKs).
18
+ */
19
+ declare function buildEvmUserModifyAction(usingBigBlocks: boolean): EvmUserModifyAction;
20
+ interface EnableHyperEvmBigBlocksParams {
21
+ readonly evmSigner: EvmSigner;
22
+ readonly environment: Environment;
23
+ /** Address opting into big blocks (the swap's `fromAddress`). */
24
+ readonly address: Address;
25
+ /**
26
+ * EVM chainId forwarded to the wallet's `signTypedData` for routing/context
27
+ * (the HyperEVM chain the user is on, e.g. 999). NOT the EIP-712 domain
28
+ * chainId — that is fixed at 1337 inside the typed data.
29
+ */
30
+ readonly chainId: number;
31
+ /** Defaults to `true`. Pass `false` to opt back out of big blocks. */
32
+ readonly usingBigBlocks?: boolean;
33
+ /** Millisecond nonce. Defaults to `Date.now()`. */
34
+ readonly nonce?: bigint;
35
+ readonly fetch?: Fetch;
36
+ readonly signal?: AbortSignal;
37
+ readonly step: TransferStepDetails;
38
+ }
39
+ /**
40
+ * Sign and submit `evmUserModify { usingBigBlocks }` to Hyperliquid's
41
+ * `/exchange` endpoint, opting the address into (or out of) HyperEVM big blocks.
42
+ *
43
+ * Requires `evmSigner.signTypedData` — throws {@link SdkError} with
44
+ * `SIGNING_FAILED` if it isn't wired. The returned response's `status` is
45
+ * `"ok"` on success; callers should treat `"err"` as a failure.
46
+ */
47
+ declare function enableHyperEvmBigBlocks({
48
+ evmSigner,
49
+ environment,
50
+ address,
51
+ chainId,
52
+ usingBigBlocks,
53
+ nonce,
54
+ fetch: customFetch,
55
+ signal,
56
+ step
57
+ }: EnableHyperEvmBigBlocksParams): Promise<HyperliquidExchangeResponse>;
58
+ //#endregion
59
+ export { EnableHyperEvmBigBlocksParams, EvmUserModifyAction, buildEvmUserModifyAction, enableHyperEvmBigBlocks };
60
+ //# sourceMappingURL=_hyperliquid-l1-action.d.ts.map
@@ -0,0 +1,2 @@
1
+ import{Environment as e}from"../../constants.js";import{ErrorCode as t,InvalidParamsError as n,SdkError as r}from"../../errors.js";import{hyperliquidApiBaseUrlForEnvironment as i,hyperliquidExchangePost as a}from"./_hyperliquid.js";import{concat as o,keccak256 as s,numberToBytes as c}from"viem";import{encode as l}from"@msgpack/msgpack";const u=BigInt(2**53-1),d={name:`Exchange`,version:`1`,chainId:1337,verifyingContract:`0x0000000000000000000000000000000000000000`},f={Agent:[{name:`source`,type:`string`},{name:`connectionId`,type:`bytes32`}]};function p(e){return{type:`evmUserModify`,usingBigBlocks:e}}function m(e,t){return s(o([l(e),c(t,{size:8}),Uint8Array.from([0])]))}function h(e,t){return{domain:d,types:f,primaryType:`Agent`,message:{source:t?`a`:`b`,connectionId:e}}}async function g({evmSigner:o,environment:s,address:c,chainId:l,usingBigBlocks:d=!0,nonce:f,fetch:g,signal:_,step:v}){if(!o.signTypedData)throw new r(`Enabling HyperEVM big blocks requires an EIP-712 typed-data signer.`,t.SIGNING_FAILED,{details:`EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.`});let y=s===e.PROD,b=f??BigInt(Date.now());if(b<0n||b>u)throw new n(`Hyperliquid L1 action nonce must be a non-negative integer within Number.MAX_SAFE_INTEGER.`,`Received nonce ${b.toString()}.`);let x=p(d),S=h(m(x,b),y),C=await o.signTypedData({typedData:S,address:c,chainId:l},v);return a({apiBaseUrl:i(s),signature:C,nonce:b,action:x,fetch:g,signal:_})}export{p as buildEvmUserModifyAction,g as enableHyperEvmBigBlocks};
2
+ //# sourceMappingURL=_hyperliquid-l1-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_hyperliquid-l1-action.js","names":["msgpackEncode"],"sources":["../../../src/transfer-service/markr/_hyperliquid-l1-action.ts"],"sourcesContent":["/**\n * Hyperliquid **L1-action** signing for `evmUserModify` — the HyperEVM\n * \"big blocks\" toggle.\n *\n * This is a different signing scheme from the user-signed `sendAsset` action in\n * `_hyperliquid-eip712.ts`. L1 actions use Hyperliquid's \"phantom agent\" flow:\n *\n * 1. msgpack-encode the `action` object.\n * 2. keccak256 over `msgpack(action) ++ nonce(8B big-endian) ++ vault/expiry\n * flags` → a 32-byte `connectionId`.\n * 3. EIP-712 sign an `Agent { source, connectionId }` struct under a FIXED\n * domain (`name: \"Exchange\"`, `version: \"1\"`, `chainId: 1337`,\n * `verifyingContract: 0x0`). Mainnet vs testnet is carried in `source`\n * (`\"a\"` | `\"b\"`), NOT the domain chainId — the domain chainId is always\n * 1337 for L1 actions.\n * 4. POST `{ action, nonce, signature }` to `/exchange`.\n *\n * Why this exists: HyperEVM (chain 999) produces two block types — small\n * (\"fast\") blocks capped at ~2M gas, and big blocks at 30M gas. Small blocks\n * are the default, so a multi-hop swap (~4M gas) is rejected with\n * \"exceeds block gas limit\". `evmUserModify { usingBigBlocks: true }` opts the\n * address into big blocks (persistent, per-address) so those swaps land.\n *\n * Refs:\n * - https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/signing\n * - https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture\n */\nimport { concat, keccak256, numberToBytes, type Address as EvmAddress, type Hex } from 'viem';\nimport { encode as msgpackEncode } from '@msgpack/msgpack';\nimport { Environment } from '../../constants';\nimport { ErrorCode, InvalidParamsError, SdkError } from '../../errors';\nimport type { EvmSigner, EvmTypedData } from '../../types/signer';\nimport type { TransferStepDetails } from '../../types/transfer';\nimport type { Fetch } from '../../types/utility-types';\nimport {\n hyperliquidApiBaseUrlForEnvironment,\n hyperliquidExchangePost,\n type HyperliquidExchangeResponse,\n} from './_hyperliquid';\n\n/** L1 nonce must fit a JSON Number without precision loss (`Number(nonce)` on the wire). */\nconst MAX_L1_ACTION_NONCE = BigInt(Number.MAX_SAFE_INTEGER);\n\n/** L1-action EIP-712 domain — fixed for ALL Hyperliquid L1 actions. */\nconst HL_L1_ACTION_DOMAIN = {\n name: 'Exchange',\n version: '1',\n chainId: 1337,\n verifyingContract: '0x0000000000000000000000000000000000000000',\n} as const satisfies EvmTypedData['domain'];\n\nconst HL_AGENT_TYPES = {\n Agent: [\n { name: 'source', type: 'string' },\n { name: 'connectionId', type: 'bytes32' },\n ],\n} as const;\n\nconst HL_AGENT_PRIMARY_TYPE = 'Agent' as const;\n\nexport interface EvmUserModifyAction extends Record<string, unknown> {\n readonly type: 'evmUserModify';\n readonly usingBigBlocks: boolean;\n}\n\n/**\n * Build the `evmUserModify` L1 action.\n *\n * Field order is significant — the signature is over the msgpack encoding, so\n * `type` MUST precede `usingBigBlocks` (matches Hyperliquid's reference SDKs).\n */\nexport function buildEvmUserModifyAction(usingBigBlocks: boolean): EvmUserModifyAction {\n return { type: 'evmUserModify', usingBigBlocks };\n}\n\n/**\n * Compute the Hyperliquid L1-action hash (a.k.a. `connectionId`).\n *\n * `keccak256( msgpack(action) ++ nonce[8B big-endian] ++ 0x00 )`.\n *\n * The trailing `0x00` is the \"no vault address\" flag. We never use a vault or\n * an `expiresAfter` for `evmUserModify`, so nothing else is appended — this\n * MUST stay in lock-step with the body sent to `/exchange` (which likewise\n * omits `vaultAddress`/`expiresAfter`), or Hyperliquid recomputes a different\n * hash and rejects the signature.\n */\nexport function computeL1ActionHash(action: Record<string, unknown>, nonce: bigint): Hex {\n const actionBytes = msgpackEncode(action);\n const nonceBytes = numberToBytes(nonce, { size: 8 });\n const noVaultFlag = Uint8Array.from([0x00]);\n\n return keccak256(concat([actionBytes, nonceBytes, noVaultFlag]));\n}\n\n/** Build the phantom-agent EIP-712 typed data for an L1 action hash. */\nexport function buildL1ActionAgentTypedData(connectionId: Hex, isMainnet: boolean): EvmTypedData {\n return {\n domain: HL_L1_ACTION_DOMAIN,\n types: HL_AGENT_TYPES,\n primaryType: HL_AGENT_PRIMARY_TYPE,\n message: {\n // \"a\" = mainnet, \"b\" = testnet. This is how L1 actions encode the\n // network — the domain chainId stays 1337 in both cases.\n source: isMainnet ? 'a' : 'b',\n connectionId,\n },\n };\n}\n\nexport interface EnableHyperEvmBigBlocksParams {\n readonly evmSigner: EvmSigner;\n readonly environment: Environment;\n /** Address opting into big blocks (the swap's `fromAddress`). */\n readonly address: EvmAddress;\n /**\n * EVM chainId forwarded to the wallet's `signTypedData` for routing/context\n * (the HyperEVM chain the user is on, e.g. 999). NOT the EIP-712 domain\n * chainId — that is fixed at 1337 inside the typed data.\n */\n readonly chainId: number;\n /** Defaults to `true`. Pass `false` to opt back out of big blocks. */\n readonly usingBigBlocks?: boolean;\n /** Millisecond nonce. Defaults to `Date.now()`. */\n readonly nonce?: bigint;\n readonly fetch?: Fetch;\n readonly signal?: AbortSignal;\n readonly step: TransferStepDetails;\n}\n\n/**\n * Sign and submit `evmUserModify { usingBigBlocks }` to Hyperliquid's\n * `/exchange` endpoint, opting the address into (or out of) HyperEVM big blocks.\n *\n * Requires `evmSigner.signTypedData` — throws {@link SdkError} with\n * `SIGNING_FAILED` if it isn't wired. The returned response's `status` is\n * `\"ok\"` on success; callers should treat `\"err\"` as a failure.\n */\nexport async function enableHyperEvmBigBlocks({\n evmSigner,\n environment,\n address,\n chainId,\n usingBigBlocks = true,\n nonce,\n fetch: customFetch,\n signal,\n step,\n}: EnableHyperEvmBigBlocksParams): Promise<HyperliquidExchangeResponse> {\n if (!evmSigner.signTypedData) {\n throw new SdkError(\n 'Enabling HyperEVM big blocks requires an EIP-712 typed-data signer.',\n ErrorCode.SIGNING_FAILED,\n {\n details: 'EvmSigner.signTypedData is undefined. Wire it via wagmi useSignTypedData or the wallet equivalent.',\n },\n );\n }\n\n const isMainnet = environment === Environment.PROD;\n const actionNonce = nonce ?? BigInt(Date.now());\n\n if (actionNonce < 0n || actionNonce > MAX_L1_ACTION_NONCE) {\n throw new InvalidParamsError(\n 'Hyperliquid L1 action nonce must be a non-negative integer within Number.MAX_SAFE_INTEGER.',\n `Received nonce ${actionNonce.toString()}.`,\n );\n }\n\n const action = buildEvmUserModifyAction(usingBigBlocks);\n const connectionId = computeL1ActionHash(action, actionNonce);\n const typedData = buildL1ActionAgentTypedData(connectionId, isMainnet);\n\n const signature = await evmSigner.signTypedData({ typedData, address, chainId }, step);\n\n return hyperliquidExchangePost({\n apiBaseUrl: hyperliquidApiBaseUrlForEnvironment(environment),\n signature,\n nonce: actionNonce,\n action,\n fetch: customFetch,\n signal,\n });\n}\n"],"mappings":"kVAyCA,MAAM,EAAsB,eAA+B,CAGrD,EAAsB,CAC1B,KAAM,WACN,QAAS,IACT,QAAS,KACT,kBAAmB,6CACpB,CAEK,EAAiB,CACrB,MAAO,CACL,CAAE,KAAM,SAAU,KAAM,SAAU,CAClC,CAAE,KAAM,eAAgB,KAAM,UAAW,CAC1C,CACF,CAeD,SAAgB,EAAyB,EAA8C,CACrF,MAAO,CAAE,KAAM,gBAAiB,iBAAgB,CAclD,SAAgB,EAAoB,EAAiC,EAAoB,CAKvF,OAAO,EAAU,EAAO,CAJJA,EAAc,EAAO,CACtB,EAAc,EAAO,CAAE,KAAM,EAAG,CAAC,CAChC,WAAW,KAAK,CAAC,EAAK,CAAC,CAEmB,CAAC,CAAC,CAIlE,SAAgB,EAA4B,EAAmB,EAAkC,CAC/F,MAAO,CACL,OAAQ,EACR,MAAO,EACP,YAAa,QACb,QAAS,CAGP,OAAQ,EAAY,IAAM,IAC1B,eACD,CACF,CA+BH,eAAsB,EAAwB,CAC5C,YACA,cACA,UACA,UACA,iBAAiB,GACjB,QACA,MAAO,EACP,SACA,QACsE,CACtE,GAAI,CAAC,EAAU,cACb,MAAM,IAAI,EACR,sEACA,EAAU,eACV,CACE,QAAS,qGACV,CACF,CAGH,IAAM,EAAY,IAAgB,EAAY,KACxC,EAAc,GAAS,OAAO,KAAK,KAAK,CAAC,CAE/C,GAAI,EAAc,IAAM,EAAc,EACpC,MAAM,IAAI,EACR,6FACA,kBAAkB,EAAY,UAAU,CAAC,GAC1C,CAGH,IAAM,EAAS,EAAyB,EAAe,CAEjD,EAAY,EADG,EAAoB,EAAQ,EAAY,CACD,EAAU,CAEhE,EAAY,MAAM,EAAU,cAAc,CAAE,YAAW,UAAS,UAAS,CAAE,EAAK,CAEtF,OAAO,EAAwB,CAC7B,WAAY,EAAoC,EAAY,CAC5D,YACA,MAAO,EACP,SACA,MAAO,EACP,SACD,CAAC"}
@@ -0,0 +1,8 @@
1
+ //#region src/transfer-service/markr/_hyperliquid-schema.d.ts
2
+ interface HyperliquidExchangeResponse {
3
+ readonly status: "ok" | "err";
4
+ readonly response?: unknown;
5
+ }
6
+ //#endregion
7
+ export { HyperliquidExchangeResponse };
8
+ //# sourceMappingURL=_hyperliquid-schema.d.cts.map
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/transfer-service/markr/_hyperliquid-schema.d.ts
4
+ interface HyperliquidExchangeResponse {
5
+ readonly status: "ok" | "err";
6
+ readonly response?: unknown;
7
+ }
8
+ //#endregion
9
+ export { HyperliquidExchangeResponse };
10
+ //# sourceMappingURL=_hyperliquid-schema.d.ts.map
@@ -0,0 +1 @@
1
+ import { HyperliquidExchangeResponse } from "./_hyperliquid-schema.js";
@@ -1,2 +1,2 @@
1
- const e=require(`../../../errors.cjs`);require(`./types.cjs`);const t=require(`../_schema.cjs`),n=require(`../../fetch-utilities.cjs`),r=require(`../_api.cjs`),i=require(`./_schema.cjs`),a=/^0x[0-9a-fA-F]{64}$/;function o(t){if(t.error)return!(t.error instanceof e.AbortedError);let n=t.response?.status??0;return n===408||n===425||n===429||n>=500&&n<=599}function s(t){if(t===1/0||t===-1)return-1;if(!Number.isInteger(t)||t<2||t>365)throw new e.InvalidParamsError(`Invalid numberOfOrders`,`Expected an integer in [2, 365], Infinity, or -1 (unlimited). Got: ${String(t)}`);return t}async function c({apiBaseUrl:t,apiToken:a,fetch:o},c){let l=`/recurring/quote`,u=n.combineUrlPathnames(t,l),d={appId:c.appId,chainId:c.chainId,tokenIn:c.tokenIn,tokenInDecimals:c.tokenInDecimals,tokenOut:c.tokenOut,tokenOutDecimals:c.tokenOutDecimals,amount:c.amount.toString(),numberOfOrders:s(c.numberOfOrders),frequency:c.frequency,slippage:c.slippage},f=await n.fetchJson(u,{body:JSON.stringify(d),fetch:o,headers:r.getAuthHeaders(a),method:`POST`}),p=i.RecurringQuoteResponseSchema.safeParse(f);if(!p.success)throw new e.ResponseValidationError(`Invalid response from Markr "${l}" endpoint.`,p.error.issues,f);return p.data}async function l({apiBaseUrl:t,apiToken:a,fetch:s},c){let l=`/recurring/swap`,u=await n.fetchJson(n.combineUrlPathnames(t,l),{body:JSON.stringify(c),fetch:s,headers:r.getAuthHeaders(a),method:`POST`,retries:3,retryOn:o}),d=i.RecurringSwapResponseSchema.safeParse(u);if(!d.success)throw new e.ResponseValidationError(`Invalid response from Markr "${l}" endpoint.`,d.error.issues,u);return d.data}async function u({apiBaseUrl:t,apiToken:a,fetch:o},s){let c=new URLSearchParams({address:s.address});s.chainId!==void 0&&c.set(`chainId`,String(s.chainId)),s.status!==void 0&&c.set(`status`,s.status);let l=await n.fetchJson(n.combineUrlPathnames(t,`/recurring/orders?${c.toString()}`),{headers:r.getAuthHeaders(a),fetch:o}),u=i.ListRecurringOrdersResponseSchema.safeParse(l);if(!u.success)throw new e.ResponseValidationError(`Invalid response from Markr "/recurring/orders" endpoint.`,u.error.issues,l);return u.data}async function d({apiBaseUrl:i,apiToken:s,fetch:c},l,u){if(!a.test(u.orderId))throw new e.InvalidParamsError(`Invalid recurring orderId`,`Expected 0x-prefixed bytes32 hex (66 chars). Got: ${JSON.stringify(u.orderId)}`);let d=`/recurring/orders/${encodeURIComponent(u.orderId)}/${l}`,f=await n.fetchJson(n.combineUrlPathnames(i,d),{body:JSON.stringify({address:u.address,chainId:u.chainId}),fetch:c,headers:r.getAuthHeaders(s),method:`POST`,retries:3,retryOn:o}),p=t.WrappedSwapTransactionResponseSchema.safeParse(f);if(!p.success)throw new e.ResponseValidationError(`Invalid response from Markr "${d}" endpoint.`,p.error.issues,f);return p.data}function f(e,t){return d(e,`cancel`,t)}function p(e,t){return d(e,`pause`,t)}function m(e,t){return d(e,`unpause`,t)}exports.markrListRecurringOrders=u,exports.markrPrepareCancellation=f,exports.markrPreparePause=p,exports.markrPrepareUnpause=m,exports.markrRecurringQuote=c,exports.markrRecurringSwap=l;
1
+ const e=require(`../../../errors.cjs`),t=require(`../../fetch-utilities.cjs`);require(`./types.cjs`);const n=require(`../_schema.cjs`),r=require(`../_api.cjs`),i=require(`./_schema.cjs`),a=/^0x[0-9a-fA-F]{64}$/;function o(t){if(t.error)return!(t.error instanceof e.AbortedError);let n=t.response?.status??0;return n===408||n===425||n===429||n>=500&&n<=599}function s(t){if(t===1/0||t===-1)return-1;if(!Number.isInteger(t)||t<2||t>365)throw new e.InvalidParamsError(`Invalid numberOfOrders`,`Expected an integer in [2, 365], Infinity, or -1 (unlimited). Got: ${String(t)}`);return t}async function c({apiBaseUrl:n,apiToken:a,fetch:o},c){let l=`/recurring/quote`,u=t.combineUrlPathnames(n,l),d={appId:c.appId,chainId:c.chainId,tokenIn:c.tokenIn,tokenInDecimals:c.tokenInDecimals,tokenOut:c.tokenOut,tokenOutDecimals:c.tokenOutDecimals,amount:c.amount.toString(),numberOfOrders:s(c.numberOfOrders),frequency:c.frequency,slippage:c.slippage},f=await t.fetchJson(u,{body:JSON.stringify(d),fetch:o,headers:r.getAuthHeaders(a),method:`POST`}),p=i.RecurringQuoteResponseSchema.safeParse(f);if(!p.success)throw new e.ResponseValidationError(`Invalid response from Markr "${l}" endpoint.`,p.error.issues,f);return p.data}async function l({apiBaseUrl:n,apiToken:a,fetch:s},c){let l=`/recurring/swap`,u=await t.fetchJson(t.combineUrlPathnames(n,l),{body:JSON.stringify(c),fetch:s,headers:r.getAuthHeaders(a),method:`POST`,retries:3,retryOn:o}),d=i.RecurringSwapResponseSchema.safeParse(u);if(!d.success)throw new e.ResponseValidationError(`Invalid response from Markr "${l}" endpoint.`,d.error.issues,u);return d.data}async function u({apiBaseUrl:n,apiToken:a,fetch:o},s){let c=new URLSearchParams({address:s.address});s.chainId!==void 0&&c.set(`chainId`,String(s.chainId)),s.status!==void 0&&c.set(`status`,s.status);let l=await t.fetchJson(t.combineUrlPathnames(n,`/recurring/orders?${c.toString()}`),{headers:r.getAuthHeaders(a),fetch:o}),u=i.ListRecurringOrdersResponseSchema.safeParse(l);if(!u.success)throw new e.ResponseValidationError(`Invalid response from Markr "/recurring/orders" endpoint.`,u.error.issues,l);return u.data}async function d({apiBaseUrl:i,apiToken:s,fetch:c},l,u){if(!a.test(u.orderId))throw new e.InvalidParamsError(`Invalid recurring orderId`,`Expected 0x-prefixed bytes32 hex (66 chars). Got: ${JSON.stringify(u.orderId)}`);let d=`/recurring/orders/${encodeURIComponent(u.orderId)}/${l}`,f=await t.fetchJson(t.combineUrlPathnames(i,d),{body:JSON.stringify({address:u.address,chainId:u.chainId}),fetch:c,headers:r.getAuthHeaders(s),method:`POST`,retries:3,retryOn:o}),p=n.WrappedSwapTransactionResponseSchema.safeParse(f);if(!p.success)throw new e.ResponseValidationError(`Invalid response from Markr "${d}" endpoint.`,p.error.issues,f);return p.data}function f(e,t){return d(e,`cancel`,t)}function p(e,t){return d(e,`pause`,t)}function m(e,t){return d(e,`unpause`,t)}exports.markrListRecurringOrders=u,exports.markrPrepareCancellation=f,exports.markrPreparePause=p,exports.markrPrepareUnpause=m,exports.markrRecurringQuote=c,exports.markrRecurringSwap=l;
2
2
  //# sourceMappingURL=_api.cjs.map
@@ -1,2 +1,2 @@
1
- import{AbortedError as e,InvalidParamsError as t,ResponseValidationError as n}from"../../../errors.js";import"./types.js";import{WrappedSwapTransactionResponseSchema as r}from"../_schema.js";import{combineUrlPathnames as i,fetchJson as a}from"../../fetch-utilities.js";import{getAuthHeaders as o}from"../_api.js";import{ListRecurringOrdersResponseSchema as s,RecurringQuoteResponseSchema as c,RecurringSwapResponseSchema as l}from"./_schema.js";const u=/^0x[0-9a-fA-F]{64}$/;function d(t){if(t.error)return!(t.error instanceof e);let n=t.response?.status??0;return n===408||n===425||n===429||n>=500&&n<=599}function f(e){if(e===1/0||e===-1)return-1;if(!Number.isInteger(e)||e<2||e>365)throw new t(`Invalid numberOfOrders`,`Expected an integer in [2, 365], Infinity, or -1 (unlimited). Got: ${String(e)}`);return e}async function p({apiBaseUrl:e,apiToken:t,fetch:r},s){let l=`/recurring/quote`,u=i(e,l),d={appId:s.appId,chainId:s.chainId,tokenIn:s.tokenIn,tokenInDecimals:s.tokenInDecimals,tokenOut:s.tokenOut,tokenOutDecimals:s.tokenOutDecimals,amount:s.amount.toString(),numberOfOrders:f(s.numberOfOrders),frequency:s.frequency,slippage:s.slippage},p=await a(u,{body:JSON.stringify(d),fetch:r,headers:o(t),method:`POST`}),m=c.safeParse(p);if(!m.success)throw new n(`Invalid response from Markr "${l}" endpoint.`,m.error.issues,p);return m.data}async function m({apiBaseUrl:e,apiToken:t,fetch:r},s){let c=`/recurring/swap`,u=await a(i(e,c),{body:JSON.stringify(s),fetch:r,headers:o(t),method:`POST`,retries:3,retryOn:d}),f=l.safeParse(u);if(!f.success)throw new n(`Invalid response from Markr "${c}" endpoint.`,f.error.issues,u);return f.data}async function h({apiBaseUrl:e,apiToken:t,fetch:r},c){let l=new URLSearchParams({address:c.address});c.chainId!==void 0&&l.set(`chainId`,String(c.chainId)),c.status!==void 0&&l.set(`status`,c.status);let u=await a(i(e,`/recurring/orders?${l.toString()}`),{headers:o(t),fetch:r}),d=s.safeParse(u);if(!d.success)throw new n(`Invalid response from Markr "/recurring/orders" endpoint.`,d.error.issues,u);return d.data}async function g({apiBaseUrl:e,apiToken:s,fetch:c},l,f){if(!u.test(f.orderId))throw new t(`Invalid recurring orderId`,`Expected 0x-prefixed bytes32 hex (66 chars). Got: ${JSON.stringify(f.orderId)}`);let p=`/recurring/orders/${encodeURIComponent(f.orderId)}/${l}`,m=await a(i(e,p),{body:JSON.stringify({address:f.address,chainId:f.chainId}),fetch:c,headers:o(s),method:`POST`,retries:3,retryOn:d}),h=r.safeParse(m);if(!h.success)throw new n(`Invalid response from Markr "${p}" endpoint.`,h.error.issues,m);return h.data}function _(e,t){return g(e,`cancel`,t)}function v(e,t){return g(e,`pause`,t)}function y(e,t){return g(e,`unpause`,t)}export{h as markrListRecurringOrders,_ as markrPrepareCancellation,v as markrPreparePause,y as markrPrepareUnpause,p as markrRecurringQuote,m as markrRecurringSwap};
1
+ import{AbortedError as e,InvalidParamsError as t,ResponseValidationError as n}from"../../../errors.js";import{combineUrlPathnames as r,fetchJson as i}from"../../fetch-utilities.js";import"./types.js";import{WrappedSwapTransactionResponseSchema as a}from"../_schema.js";import{getAuthHeaders as o}from"../_api.js";import{ListRecurringOrdersResponseSchema as s,RecurringQuoteResponseSchema as c,RecurringSwapResponseSchema as l}from"./_schema.js";const u=/^0x[0-9a-fA-F]{64}$/;function d(t){if(t.error)return!(t.error instanceof e);let n=t.response?.status??0;return n===408||n===425||n===429||n>=500&&n<=599}function f(e){if(e===1/0||e===-1)return-1;if(!Number.isInteger(e)||e<2||e>365)throw new t(`Invalid numberOfOrders`,`Expected an integer in [2, 365], Infinity, or -1 (unlimited). Got: ${String(e)}`);return e}async function p({apiBaseUrl:e,apiToken:t,fetch:a},s){let l=`/recurring/quote`,u=r(e,l),d={appId:s.appId,chainId:s.chainId,tokenIn:s.tokenIn,tokenInDecimals:s.tokenInDecimals,tokenOut:s.tokenOut,tokenOutDecimals:s.tokenOutDecimals,amount:s.amount.toString(),numberOfOrders:f(s.numberOfOrders),frequency:s.frequency,slippage:s.slippage},p=await i(u,{body:JSON.stringify(d),fetch:a,headers:o(t),method:`POST`}),m=c.safeParse(p);if(!m.success)throw new n(`Invalid response from Markr "${l}" endpoint.`,m.error.issues,p);return m.data}async function m({apiBaseUrl:e,apiToken:t,fetch:a},s){let c=`/recurring/swap`,u=await i(r(e,c),{body:JSON.stringify(s),fetch:a,headers:o(t),method:`POST`,retries:3,retryOn:d}),f=l.safeParse(u);if(!f.success)throw new n(`Invalid response from Markr "${c}" endpoint.`,f.error.issues,u);return f.data}async function h({apiBaseUrl:e,apiToken:t,fetch:a},c){let l=new URLSearchParams({address:c.address});c.chainId!==void 0&&l.set(`chainId`,String(c.chainId)),c.status!==void 0&&l.set(`status`,c.status);let u=await i(r(e,`/recurring/orders?${l.toString()}`),{headers:o(t),fetch:a}),d=s.safeParse(u);if(!d.success)throw new n(`Invalid response from Markr "/recurring/orders" endpoint.`,d.error.issues,u);return d.data}async function g({apiBaseUrl:e,apiToken:s,fetch:c},l,f){if(!u.test(f.orderId))throw new t(`Invalid recurring orderId`,`Expected 0x-prefixed bytes32 hex (66 chars). Got: ${JSON.stringify(f.orderId)}`);let p=`/recurring/orders/${encodeURIComponent(f.orderId)}/${l}`,m=await i(r(e,p),{body:JSON.stringify({address:f.address,chainId:f.chainId}),fetch:c,headers:o(s),method:`POST`,retries:3,retryOn:d}),h=a.safeParse(m);if(!h.success)throw new n(`Invalid response from Markr "${p}" endpoint.`,h.error.issues,m);return h.data}function _(e,t){return g(e,`cancel`,t)}function v(e,t){return g(e,`pause`,t)}function y(e,t){return g(e,`unpause`,t)}export{h as markrListRecurringOrders,_ as markrPrepareCancellation,v as markrPreparePause,y as markrPrepareUnpause,p as markrRecurringQuote,m as markrRecurringSwap};
2
2
  //# sourceMappingURL=_api.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@avalabs/fusion-sdk",
3
3
  "license": "Limited Ecosystem License",
4
- "version": "0.27.0",
4
+ "version": "0.28.0",
5
5
  "type": "module",
6
6
  "main": "./dist/mod.cjs",
7
7
  "module": "./dist/mod.js",
@@ -25,6 +25,7 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@bitcoinerlab/secp256k1": "^1.2.0",
28
+ "@msgpack/msgpack": "^3.1.3",
28
29
  "@layerzerolabs/lz-v2-utilities": "^3.0.17",
29
30
  "@lombard.finance/sdk": "^4.3.0",
30
31
  "@scure/base": "^1.0.1",