@avalabs/fusion-sdk 0.20.0 → 0.22.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 (101) hide show
  1. package/dist/mod.cjs +1 -1
  2. package/dist/mod.d.cts +5 -1
  3. package/dist/mod.d.ts +5 -1
  4. package/dist/mod.js +1 -1
  5. package/dist/transfer-manager.cjs +1 -1
  6. package/dist/transfer-manager.cjs.map +1 -1
  7. package/dist/transfer-manager.js +1 -1
  8. package/dist/transfer-manager.js.map +1 -1
  9. package/dist/transfer-service/_evm-approval.cjs +2 -0
  10. package/dist/transfer-service/_evm-approval.cjs.map +1 -0
  11. package/dist/transfer-service/_evm-approval.d.cts +23 -0
  12. package/dist/transfer-service/_evm-approval.d.ts +23 -0
  13. package/dist/transfer-service/_evm-approval.js +2 -0
  14. package/dist/transfer-service/_evm-approval.js.map +1 -0
  15. package/dist/transfer-service/_utils.cjs +1 -1
  16. package/dist/transfer-service/_utils.cjs.map +1 -1
  17. package/dist/transfer-service/_utils.d.ts +1 -0
  18. package/dist/transfer-service/_utils.js +1 -1
  19. package/dist/transfer-service/_utils.js.map +1 -1
  20. package/dist/transfer-service/avalanche-cct/_handlers/estimate-native-fee.cjs +1 -1
  21. package/dist/transfer-service/avalanche-cct/_handlers/estimate-native-fee.js +1 -1
  22. package/dist/transfer-service/avalanche-cct/_handlers/track-transfer.cjs +1 -1
  23. package/dist/transfer-service/avalanche-cct/_handlers/track-transfer.js +1 -1
  24. package/dist/transfer-service/avalanche-cct/_handlers/transfer-asset.cjs +1 -1
  25. package/dist/transfer-service/avalanche-cct/_handlers/transfer-asset.js +1 -1
  26. package/dist/transfer-service/avalanche-cct/_utils/fees.cjs +1 -1
  27. package/dist/transfer-service/avalanche-cct/_utils/fees.js +1 -1
  28. package/dist/transfer-service/avalanche-cct/_utils/polling.cjs +1 -1
  29. package/dist/transfer-service/avalanche-cct/_utils/polling.js +1 -1
  30. package/dist/transfer-service/avalanche-evm/_handlers/estimate-native-fee.cjs +1 -1
  31. package/dist/transfer-service/avalanche-evm/_handlers/estimate-native-fee.js +1 -1
  32. package/dist/transfer-service/markr/_api.cjs +1 -1
  33. package/dist/transfer-service/markr/_api.cjs.map +1 -1
  34. package/dist/transfer-service/markr/_api.js +1 -1
  35. package/dist/transfer-service/markr/_api.js.map +1 -1
  36. package/dist/transfer-service/markr/_handlers/estimate-native-fee.cjs +1 -1
  37. package/dist/transfer-service/markr/_handlers/estimate-native-fee.cjs.map +1 -1
  38. package/dist/transfer-service/markr/_handlers/estimate-native-fee.js +1 -1
  39. package/dist/transfer-service/markr/_handlers/estimate-native-fee.js.map +1 -1
  40. package/dist/transfer-service/markr/_handlers/stream-quotes.cjs +1 -1
  41. package/dist/transfer-service/markr/_handlers/stream-quotes.cjs.map +1 -1
  42. package/dist/transfer-service/markr/_handlers/stream-quotes.js +1 -1
  43. package/dist/transfer-service/markr/_handlers/stream-quotes.js.map +1 -1
  44. package/dist/transfer-service/markr/_handlers/transfer-asset.cjs +1 -1
  45. package/dist/transfer-service/markr/_handlers/transfer-asset.cjs.map +1 -1
  46. package/dist/transfer-service/markr/_handlers/transfer-asset.js +1 -1
  47. package/dist/transfer-service/markr/_handlers/transfer-asset.js.map +1 -1
  48. package/dist/transfer-service/markr/_schema.cjs +1 -1
  49. package/dist/transfer-service/markr/_schema.cjs.map +1 -1
  50. package/dist/transfer-service/markr/_schema.js +1 -1
  51. package/dist/transfer-service/markr/_schema.js.map +1 -1
  52. package/dist/transfer-service/markr/_utils.cjs +1 -1
  53. package/dist/transfer-service/markr/_utils.cjs.map +1 -1
  54. package/dist/transfer-service/markr/_utils.js +1 -1
  55. package/dist/transfer-service/markr/_utils.js.map +1 -1
  56. package/dist/transfer-service/markr/markr-service.cjs +1 -1
  57. package/dist/transfer-service/markr/markr-service.cjs.map +1 -1
  58. package/dist/transfer-service/markr/markr-service.d.cts +26 -0
  59. package/dist/transfer-service/markr/markr-service.d.ts +26 -0
  60. package/dist/transfer-service/markr/markr-service.js +1 -1
  61. package/dist/transfer-service/markr/markr-service.js.map +1 -1
  62. package/dist/transfer-service/markr/recurring/_api.cjs +2 -0
  63. package/dist/transfer-service/markr/recurring/_api.cjs.map +1 -0
  64. package/dist/transfer-service/markr/recurring/_api.js +2 -0
  65. package/dist/transfer-service/markr/recurring/_api.js.map +1 -0
  66. package/dist/transfer-service/markr/recurring/_chain-info.cjs +2 -0
  67. package/dist/transfer-service/markr/recurring/_chain-info.cjs.map +1 -0
  68. package/dist/transfer-service/markr/recurring/_chain-info.js +2 -0
  69. package/dist/transfer-service/markr/recurring/_chain-info.js.map +1 -0
  70. package/dist/transfer-service/markr/recurring/_eligibility.cjs +2 -0
  71. package/dist/transfer-service/markr/recurring/_eligibility.cjs.map +1 -0
  72. package/dist/transfer-service/markr/recurring/_eligibility.js +2 -0
  73. package/dist/transfer-service/markr/recurring/_eligibility.js.map +1 -0
  74. package/dist/transfer-service/markr/recurring/_frequency.cjs +2 -0
  75. package/dist/transfer-service/markr/recurring/_frequency.cjs.map +1 -0
  76. package/dist/transfer-service/markr/recurring/_frequency.d.cts +17 -0
  77. package/dist/transfer-service/markr/recurring/_frequency.d.ts +17 -0
  78. package/dist/transfer-service/markr/recurring/_frequency.js +2 -0
  79. package/dist/transfer-service/markr/recurring/_frequency.js.map +1 -0
  80. package/dist/transfer-service/markr/recurring/_namespace.cjs +2 -0
  81. package/dist/transfer-service/markr/recurring/_namespace.cjs.map +1 -0
  82. package/dist/transfer-service/markr/recurring/_namespace.js +2 -0
  83. package/dist/transfer-service/markr/recurring/_namespace.js.map +1 -0
  84. package/dist/transfer-service/markr/recurring/_schema.cjs +2 -0
  85. package/dist/transfer-service/markr/recurring/_schema.cjs.map +1 -0
  86. package/dist/transfer-service/markr/recurring/_schema.js +2 -0
  87. package/dist/transfer-service/markr/recurring/_schema.js.map +1 -0
  88. package/dist/transfer-service/markr/recurring/index.d.ts +2 -0
  89. package/dist/transfer-service/markr/recurring/types.cjs +2 -0
  90. package/dist/transfer-service/markr/recurring/types.cjs.map +1 -0
  91. package/dist/transfer-service/markr/recurring/types.d.cts +439 -0
  92. package/dist/transfer-service/markr/recurring/types.d.ts +439 -0
  93. package/dist/transfer-service/markr/recurring/types.js +2 -0
  94. package/dist/transfer-service/markr/recurring/types.js.map +1 -0
  95. package/dist/transfer-service/wrap-unwrap/_handlers/transfer-asset.cjs +1 -1
  96. package/dist/transfer-service/wrap-unwrap/_handlers/transfer-asset.js +1 -1
  97. package/dist/types/quote.d.cts +9 -0
  98. package/dist/types/quote.d.ts +9 -0
  99. package/dist/types/transfer-manager.d.cts +16 -0
  100. package/dist/types/transfer-manager.d.ts +16 -0
  101. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"_schema.js","names":[],"sources":["../../../src/transfer-service/markr/_schema.ts"],"sourcesContent":["import type { Signature, Address as SolAddress } from '@solana/kit';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { z } from 'zod';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport {\n EvmAddressSchema,\n HashSchema,\n HexSchema,\n HyperliquidAddressSchema,\n SolAddressSchema,\n SolSignatureSchema,\n} from '../service-schemas';\n\ninterface SupportedChainsResponseItemBase {\n chainId: number | string;\n chainType: string;\n /** Available services on the chain. Each service has specific functionality */\n enabled_services: Array<'cross-chain-swap' | 'cross-chain-quote' | 'quote' | 'swap' | 'token-list'>;\n /** Chain logo URL */\n logo_url: string;\n /** Chain display name */\n name: string;\n /**\n * List of chain IDs that this chain can swap to via cross-chain aggregators.\n *\n * Empty array means no cross-chain routes available.\n */\n lanes: ReadonlyArray<number | Caip2ChainId>;\n}\n\nexport interface SupportedChainsResponseItemEvm extends SupportedChainsResponseItemBase {\n /** Chain identifier */\n chainId: number;\n /** Chain virtual machine type */\n chainType: 'evm';\n /** Router contract address */\n router?: EvmAddress;\n /** Native token wrapped contract address */\n wrapped_token?: EvmAddress;\n}\n\nexport interface SupportedChainsResponseItemSvm extends SupportedChainsResponseItemBase {\n /** Chain identifier */\n chainId: Caip2ChainId;\n /** Chain virtual machine type */\n chainType: 'svm';\n}\n\nexport type SupportedChainsResponse = Array<\n SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm | SupportedChainsResponseItemBase\n>;\n\nexport const Caip2ChainIdSchema: z.ZodType<Caip2ChainId> = z\n .string()\n .refine((value) => isCaip2ChainId(value), {\n message: 'Invalid CAIP-2 chain ID',\n })\n .transform((value) => value as Caip2ChainId);\n\nconst SupportedChainsResponseItemBaseSchema = z.object({\n chainId: z.union([z.number(), z.string()]),\n chainType: z.string(),\n enabled_services: z.array(z.enum(['cross-chain-swap', 'cross-chain-quote', 'quote', 'swap', 'token-list'])),\n logo_url: z.url(),\n name: z.string(),\n lanes: z.array(z.union([z.coerce.number().int().nonnegative(), Caip2ChainIdSchema])),\n});\n\nconst SupportedChainsResponseItemEvmSchema: z.ZodType<SupportedChainsResponseItemEvm> =\n SupportedChainsResponseItemBaseSchema.extend({\n chainId: z.coerce.number().int().nonnegative(),\n chainType: z.literal('evm'),\n router: EvmAddressSchema.optional(),\n wrapped_token: EvmAddressSchema.optional(),\n });\n\nconst SupportedChainsResponseItemSvmSchema: z.ZodType<SupportedChainsResponseItemSvm> =\n SupportedChainsResponseItemBaseSchema.extend({\n chainId: z\n .string()\n .refine((value) => isCaip2ChainId(value) && value.startsWith('solana:'), {\n error: 'Is not a valid Solana CAIP-2 ID',\n })\n .transform((value) => value as Caip2ChainId),\n chainType: z.literal('svm'),\n });\n\n/**\n * Schema for the response from Markr's /info/chains endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1info~1chains/get\n */\nexport const SupportedChainsResponseSchema: z.ZodType<SupportedChainsResponse> = z.array(\n z.union([\n SupportedChainsResponseItemEvmSchema,\n SupportedChainsResponseItemSvmSchema,\n SupportedChainsResponseItemBaseSchema.refine(\n (item) => item.chainType !== 'evm' && item.chainType !== 'svm',\n 'Known chain types must match their expected schema',\n ),\n ]),\n);\n\nexport type TokenListResponse = Array<{\n address: EvmAddress;\n decimals: number;\n logo_url: string;\n name: string;\n symbol: string;\n}>;\n\n/**\n * Schema for the response Markr's /tokens/{chainId}/list endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1tokens~1%7BchainId%7D~1list/get\n */\nexport const TokenListResponseSchema: z.ZodType<TokenListResponse> = z.array(\n z.object({\n address: EvmAddressSchema,\n decimals: z.number().int().nonnegative().max(18),\n logo_url: z.url(),\n name: z.string(),\n symbol: z.string(),\n }),\n);\n\nexport interface QuoteResponseData {\n aggregator: {\n id: string;\n logo_url: string;\n name: string;\n };\n amountIn: bigint;\n amountOut: bigint;\n /** Chain identifier (number for EVM chains, CAIP-2 ID for SVM chains) */\n chainId: number | Caip2ChainId;\n expiredAt: number;\n /**\n * Fee breakdown for cross-chain bridge transactions.\n *\n * Only included in quotes from cross-chain aggregators (DeBridge, LiFi).\n */\n fees?: ReadonlyArray<{\n type: 'protocol' | 'gas' | 'bridge' | 'slippage' | 'swap' | 'other' | 'relay';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\n /**\n * When `true`, indicates the fee is an additional fee on top of the input\n * amount that the user needs to pay. These fees need checked against the user's\n * balance to prevent insufficient balance errors.\n */\n extra?: boolean;\n /** Token the fee is deducted from */\n token: {\n /** Chain ID where fee is deducted */\n chainId: number | Caip2ChainId;\n /** Token address (EVM hex or Solana base58) */\n address: EvmAddress | SolAddress;\n };\n }>;\n gasEstimate?: bigint;\n recommendedSlippage: number;\n /** Input token address (EVM hex or Solana base58) */\n tokenIn: EvmAddress | SolAddress;\n tokenInDecimals: number;\n /** Output token address (EVM hex or Solana base58) */\n tokenOut: EvmAddress | SolAddress;\n tokenOutDecimals: number;\n uuid: string;\n}\n\nexport interface QuoteResponseDataDone {\n done: true;\n}\n\nexport type QuoteResponse = QuoteResponseData | QuoteResponseDataDone;\n\nconst MarkrQuoteTokenAddressSchema = z.union([EvmAddressSchema, SolAddressSchema, HyperliquidAddressSchema]);\n\n/**\n * Schema for the response from Markr's /quote endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1quote/post\n */\nexport const QuoteResponseSchema: z.ZodType<QuoteResponse> = z.union([\n z.object({\n aggregator: z.object({\n id: z.string(),\n logo_url: z.url(),\n name: z.string(),\n }),\n amountIn: z.coerce.bigint().nonnegative(),\n amountOut: z.coerce.bigint().nonnegative(),\n chainId: z.union([z.number().int().nonnegative(), Caip2ChainIdSchema]),\n /**\n * Unix time in seconds when the quote expires.\n */\n expiredAt: z.number().int().nonnegative(),\n fees: z\n .array(\n z.object({\n type: z.enum(['protocol', 'gas', 'bridge', 'slippage', 'swap', 'other', 'relay']),\n name: z.string(),\n amount: z.coerce.bigint().nonnegative(),\n token: z.object({\n chainId: z.union([z.number().int().nonnegative(), Caip2ChainIdSchema]),\n address: MarkrQuoteTokenAddressSchema,\n }),\n extra: z.boolean().optional(),\n }),\n )\n .optional(),\n /**\n * Estimated gas for the swap transaction.\n * Markr estimates already include a buffer.\n *\n * The API docs do not specify this field as optional, but in practice it can be missing.\n */\n gasEstimate: z.coerce.bigint().nonnegative().optional(),\n /** Recommended slippage in basis points. */\n recommendedSlippage: z.number().int().nonnegative(),\n tokenIn: MarkrQuoteTokenAddressSchema,\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: MarkrQuoteTokenAddressSchema,\n tokenOutDecimals: z.number().int().nonnegative().max(18),\n uuid: z.uuid(),\n }),\n z.object({\n done: z.literal(true),\n }),\n]);\n\n/**\n * Response type for Markr's /swap endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1swap/post\n */\nexport interface WrappedSwapTransactionResponse {\n data: Hex;\n to: EvmAddress;\n value: bigint;\n}\n\nexport const WrappedSwapTransactionResponseSchema: z.ZodType<WrappedSwapTransactionResponse> = z.object({\n data: HexSchema,\n to: EvmAddressSchema,\n value: z.coerce.bigint().nonnegative(),\n});\n\n/**\n * Solana swap transaction (returned for SVM chains).\n */\nexport interface SolanaSwapTransactionResponse {\n /** Chain type identifier */\n chainType: 'svm';\n /** Base64-encoded Solana transaction to be signed and sent by the client */\n swapTransaction: string;\n}\n\nexport const SolanaSwapTransactionResponseSchema: z.ZodType<SolanaSwapTransactionResponse> = z.object({\n chainType: z.literal('svm'),\n swapTransaction: z.base64(),\n});\n\n/**\n * `sendAsset` action parameters Relay produces for the deposit step.\n *\n * These are the exact strings the SDK must (a) include in the EIP-712 message\n * it signs and (b) submit verbatim as the `action` body to HL `/exchange`.\n * Keeping them pre-formatted by Relay (rather than reconstructed by the SDK)\n * eliminates drift — notably on `amount`, which Relay formats at the spot\n * token's display precision (e.g. `\"0.200000\"` for USDC, not the perps-side\n * `\"0.20000000\"`). Any mismatch between what we sign / submit and what Relay\n * recorded in the order makes Relay's indexer skip the on-chain `sendAsset`.\n */\nexport interface HyperliquidSendAssetParameters {\n /** `\"Mainnet\"` or `\"Testnet\"`. */\n hyperliquidChain: string;\n /** Relay's HL custodian — where the sendAsset transfers to. */\n destination: EvmAddress;\n /** Currently always `\"\"` for non-DEX withdrawals. */\n sourceDex: string;\n /** Currently always `\"\"` for non-DEX withdrawals. */\n destinationDex: string;\n /** HL `\"{symbol}:{spotEvmContract}\"` (e.g. `\"USDC:0x6d1e…054\"`). */\n token: string;\n /** Human-readable decimal, Relay-formatted at the spot token's display precision. */\n amount: string;\n /** Currently always `\"\"` for non-sub-account withdrawals. */\n fromSubAccount: string;\n}\n\nconst HyperliquidSendAssetParametersSchema: z.ZodType<HyperliquidSendAssetParameters> = z.object({\n hyperliquidChain: z.string().min(1),\n destination: EvmAddressSchema,\n sourceDex: z.string(),\n destinationDex: z.string(),\n token: z.string().min(1),\n amount: z.string().regex(/^\\d+(\\.\\d+)?$/, 'amount must be a positive decimal string'),\n fromSubAccount: z.string(),\n});\n\n/**\n * Pass-through EIP-712 envelope Relay returns inside the v2 swap response.\n *\n * The SDK no longer hardcodes Relay's `RelayNonceMapping` schema — instead it\n * forwards `domain` / `types` / `primaryType` / `value` to the wallet's typed-\n * data signer verbatim. Future Relay-side schema additions (e.g. `depositor`\n * was added in v2) propagate automatically without an SDK release.\n */\nexport interface RelayEip712SignEnvelope {\n signatureKind: 'eip712';\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: EvmAddress;\n };\n types: Record<string, ReadonlyArray<{ name: string; type: string }>>;\n primaryType: string;\n /** Relay binds at minimum these fields; additional keys (e.g. `depositor`) are forwarded verbatim. */\n value: {\n wallet: EvmAddress;\n chainId: string;\n id: Hex;\n nonce: number;\n [key: string]: unknown;\n };\n}\n\nconst RelayEip712SignEnvelopeSchema: z.ZodType<RelayEip712SignEnvelope> = z.object({\n signatureKind: z.literal('eip712'),\n domain: z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n chainId: z.number().int().nonnegative(),\n verifyingContract: EvmAddressSchema,\n }),\n types: z.record(z.string(), z.array(z.object({ name: z.string(), type: z.string() }))),\n primaryType: z.string().min(1),\n value: z\n .object({\n wallet: EvmAddressSchema,\n chainId: z.string().min(1),\n id: HashSchema,\n nonce: z.number().int().nonnegative(),\n })\n .loose(),\n});\n\n/**\n * Pass-through `/authorize` POST body Relay returns inside the v2 swap response.\n *\n * The SDK forwards `body` verbatim to Markr (which forwards verbatim to Relay).\n * Markr only normalizes `nonce` to a JSON number on the wire; everything else\n * is untouched, so new fields Relay adds are not rejected.\n */\nexport interface RelayAuthorizeEnvelope {\n endpoint: string;\n method: string;\n body: {\n type: string;\n id: Hex;\n nonce: number;\n wallet: EvmAddress;\n walletChainId: number;\n signatureChainId: number;\n [key: string]: unknown;\n };\n}\n\nconst RelayAuthorizeEnvelopeSchema: z.ZodType<RelayAuthorizeEnvelope> = z.object({\n endpoint: z.string().min(1),\n method: z.string().min(1),\n body: z\n .object({\n type: z.string().min(1),\n id: HashSchema,\n nonce: z.number().int().nonnegative(),\n wallet: EvmAddressSchema,\n walletChainId: z.number().int().nonnegative(),\n signatureChainId: z.number().int().nonnegative(),\n })\n .loose(),\n});\n\n/**\n * Hyperliquid 2-phase withdrawal variant (source chain = `eip155:1337`).\n *\n * Markr returns:\n * - the dynamic envelope (`nonce`, `id`, `requestId`) used for the authorize\n * signature and status polling, and\n * - the full `parameters` object Relay produced for the deposit step's\n * `sendAsset` action, which the SDK signs verbatim and submits to HL.\n *\n * Starting at `protocolVersion: 2`, Relay's full EIP-712 envelope (`sign`) and\n * the `/authorize` POST body (`authorize`) are passed through verbatim — the\n * SDK no longer reconstructs Relay's schemas, so additive Relay changes (e.g.\n * `depositor` field) flow through without an SDK release.\n *\n * Important: `id` and `requestId` are TWO DIFFERENT bytes32s.\n * - `id` is the **order id** — it goes into the EIP-712 `NonceMapping`\n * message and Relay's `/authorize` POST body. Sourced from\n * `steps[0].items[0].data.sign.value.id` (== `data.post.body.id` ==\n * `protocol.v2.orderId`).\n * - `requestId` is the **tracking id** used only for\n * `/intents/status/v3?requestId=…` polling. Sourced from\n * `steps[0].requestId`.\n *\n * Swapping these two looks superficially correct (both are `0x{64hex}`) but\n * makes the on-chain `sendAsset` un-matchable by Relay's indexer.\n *\n * The SDK pins the static HL-side `SendAsset` shape (which HL owns) as a\n * constant in `_hyperliquid-eip712.ts`. Relay's nonce-mapping shape is now\n * dynamic via the `sign` envelope.\n */\nexport interface HyperliquidWithdrawSwapResponse {\n type: 'hyperliquid-withdraw';\n /** SDK validates against `SUPPORTED_HL_PROTOCOL_VERSIONS`; bumps when Relay/HL EIP-712 schemas change. */\n protocolVersion: number;\n /** Shared between authorize + sendAsset signatures; uint64 decimal string. */\n nonce: string;\n /** Order id signed inside the `NonceMapping` message and posted to `/authorize`. */\n id: Hex;\n /** Tracking id for cross-chain status polling (`/intents/status/v3?requestId=…`). */\n requestId: Hex;\n /** Relay-canonical `sendAsset` action parameters; signed and submitted verbatim. */\n parameters: HyperliquidSendAssetParameters;\n /** Relay's full EIP-712 nonce-mapping envelope. v2+. */\n sign?: RelayEip712SignEnvelope;\n /** Relay's `/authorize` POST descriptor (we forward `body` verbatim). v2+. */\n authorize?: RelayAuthorizeEnvelope;\n}\n\nexport const HyperliquidWithdrawSwapResponseSchema: z.ZodType<HyperliquidWithdrawSwapResponse> = z.object({\n type: z.literal('hyperliquid-withdraw'),\n protocolVersion: z.number().int().positive(),\n nonce: z.string().regex(/^\\d+$/, 'nonce must be a decimal string'),\n id: HashSchema,\n requestId: HashSchema,\n parameters: HyperliquidSendAssetParametersSchema,\n sign: RelayEip712SignEnvelopeSchema.optional(),\n authorize: RelayAuthorizeEnvelopeSchema.optional(),\n});\n\nexport type SwapResponse =\n | WrappedSwapTransactionResponse\n | SolanaSwapTransactionResponse\n | HyperliquidWithdrawSwapResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\n HyperliquidWithdrawSwapResponseSchema,\n]);\n\n/**\n * Markr `/authorize` response.\n *\n * The success body is documented as opaque, so we only assert that:\n * 1. the parsed JSON isn't an error envelope (`{ error: \"...\" }`) — Markr's\n * upstream (Relay) can return a 200 with an error payload when the\n * authorize is rejected after HTTP success;\n * 2. nothing else, by design — schema bumps when Markr publishes a spec.\n */\nexport const MarkrAuthorizeResponseSchema: z.ZodType<unknown> = z\n .unknown()\n .refine(\n (data) =>\n !(\n data !== null &&\n typeof data === 'object' &&\n 'error' in data &&\n typeof (data as { error: unknown }).error === 'string'\n ),\n { message: 'Markr /authorize returned an error envelope despite 2xx status.' },\n );\n\nexport interface PartnerInfoResponse {\n /**\n * The partner fee in basis points collected on each swap.\n */\n fee: number;\n name: string;\n}\n\nexport const PartnerInfoResponseSchema: z.ZodType<PartnerInfoResponse> = z.object({\n fee: z.int().nonnegative(),\n name: z.string(),\n});\n\n/**\n * If the destination token is USDC, the flow is:\n * - pending -> committed -> completed\n *\n * If the destination token is not USDC, the flow is:\n * - pending -> committed -> pending_execution -> completed\n *\n * If the transaction fails at any point, the status will be 'failed'.\n */\nexport type CrossChainStatus =\n | /** Transaction submitted to CCIP */\n 'pending'\n /** Message committed, awaiting execution on destination chain */\n | 'committed'\n /** Message received on destination, swap pending execution by relayer */\n | 'pending_execution'\n /** Message executed successfully on destination chain */\n | 'completed'\n /** Swap expired, and funds were refunded (CCIP only) */\n | 'refunded'\n /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /**\n * Cross-chain transaction identifier.\n *\n * For CCIP: The CCIP message ID.\n * For DeBridge: The DeBridge order ID.\n */\n messageId: string | null;\n /** Current status of the cross-chain transaction. */\n status: CrossChainStatus;\n /** Human-readable status description */\n description: string;\n /** Source chain information */\n sourceChain: {\n /** Source chain network name */\n name: string;\n /** Source chain transaction hash */\n transactionHash: Hash | Signature;\n /** Transaction timestamp on source chain (ISO 8601) */\n timestamp: string;\n /** When the source transaction was finalized (ISO 8601) */\n finalized: string | boolean | null;\n };\n /** Destination chain information */\n destinationChain: {\n /** Destination chain network name */\n name: string | null;\n /**\n * Destination chain tx hash.\n *\n * - For direct transfers (USDC -> USDC): The CCIP bridge transaction hash.\n * - For successful swaps: The actual swap transaction hash from the relayer.\n * - For pending swaps: null (swap not yet executed).\n */\n transactionHash: Hash | Signature | null;\n /**\n * CCIP bridge tx hash (only present for swaps, not direct transfers).\n *\n * This is the transaction that delivered USDC to the destination chain via CCIP.\n * The `transactionHash` field contains the subsequent swap transaction.\n */\n bridgeHash?: Hash | Signature | null;\n /** Transaction timestamp on destination chain (null if not yet executed) (ISO 8601) */\n timestamp: string | null;\n /** When the destination transaction was finalized (null if not yet executed) (ISO 8601) */\n finalized: string | null;\n };\n /** Transaction progress information */\n progress: {\n /** Whether the message has been committed on destination chain */\n committed: boolean;\n /** When the message was committed (null if not committed) (ISO 8601) */\n commitTimestamp?: string | null;\n /** Whether the message has been executed on destination chain */\n executed: boolean;\n };\n /** Fee information */\n fees: {\n /** Fee token address */\n token: EvmAddress | SolAddress | null;\n /** Fee amount in wei */\n amount: bigint | null;\n } | null;\n /** Tokens transferred in this cross-chain transaction */\n transferredTokens: ReadonlyArray<{\n /** Token address */\n token: EvmAddress | SolAddress;\n /** Token amount */\n amount: bigint;\n }>;\n /**\n * Debug information from Markr transaction API (only present for swaps that have been executed).\n *\n * Contains detailed information about the relayer execution, retry attempts, and transaction details.\n */\n debug?: Partial<{\n /** CCIP message ID */\n messageId: string;\n /** Execution status from relayer */\n status: string;\n /** Destination chain name */\n destinationChain: string;\n /** Destination swap transaction hash */\n destinationTxHash: string;\n /** Relay transaction hash */\n relayTxHash: string;\n /** Number of retry attempts */\n retryCount: number;\n /** Timestamp of last retry attempt (ISO 8601) */\n lastRetryAt: string;\n /** Source chain name */\n sourceChain: string;\n /** Source transaction hash */\n sourceTxHash: string;\n /** When the record was created (ISO 8601) */\n createdAt: string;\n }> | null;\n}\n\nconst ISO_8601_TIMEZONE_DESIGNATOR_REGEX = /[zZ]|[+-]\\d{2}:?\\d{2}$/;\n\n// Markr API returns ISO-8601 datetime strings that are sometimes missing a timezone designator (\"local\" ISO).\n// We assume these are meant to be UTC and append 'Z' if missing, then validate as strict ISO-8601 with timezone.\nconst datetime = z.iso\n .datetime({ local: true })\n .refine(\n (value) => {\n // Accept at least local ISO format\n // If missing timezone, treat as UTC\n const hasTimezone = ISO_8601_TIMEZONE_DESIGNATOR_REGEX.test(value);\n const isoString = hasTimezone ? value : `${value}Z`;\n // Validate as strict ISO-8601 with timezone\n return z.iso.datetime().safeParse(isoString).success;\n },\n {\n error: 'Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)',\n },\n )\n .transform((value) => {\n const hasTimezone = ISO_8601_TIMEZONE_DESIGNATOR_REGEX.test(value);\n return hasTimezone ? value : `${value}Z`;\n });\n\nexport const CrossChainStatusResponseSchema: z.ZodType<CrossChainStatusResponse> = z.object({\n messageId: z.string().nullable(),\n status: z.enum(['pending', 'committed', 'pending_execution', 'completed', 'failed', 'refunded', 'unknown']),\n description: z.string(),\n sourceChain: z.object({\n name: z.string(),\n transactionHash: z.union([HashSchema, SolSignatureSchema]),\n timestamp: datetime,\n finalized: datetime.or(z.boolean()).nullable(),\n }),\n destinationChain: z.object({\n name: z.string().nullable(),\n transactionHash: z.union([HashSchema, SolSignatureSchema]).nullable(),\n bridgeHash: z.union([HashSchema, SolSignatureSchema]).nullable().optional(),\n timestamp: datetime.nullable(),\n finalized: datetime.nullable(),\n }),\n progress: z.object({\n committed: z.boolean(),\n commitTimestamp: datetime.nullable().optional(),\n executed: z.boolean(),\n }),\n fees: z\n .object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n })\n .nullable(),\n transferredTokens: z.array(\n z.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]),\n amount: z.coerce.bigint().nonnegative(),\n }),\n ),\n debug: z\n .looseObject({\n messageId: z.string(),\n status: z.string(),\n destinationChain: z.string(),\n destinationTxHash: z.string(),\n relayTxHash: z.string(),\n retryCount: z.number().int().nonnegative(),\n lastRetryAt: z.iso.datetime(),\n sourceChain: z.string(),\n sourceTxHash: z.string(),\n createdAt: z.iso.datetime(),\n })\n .partial()\n .nullable()\n .optional(),\n});\n\nexport interface SpenderAddressResponse {\n address: EvmAddress;\n}\n\nexport const SpenderAddressResponseSchema: z.ZodType<SpenderAddressResponse> = z.object({\n address: EvmAddressSchema,\n});\n"],"mappings":"iPAsDA,MAAa,EAA8C,EACxD,QAAQ,CACR,OAAQ,GAAU,EAAe,EAAM,CAAE,CACxC,QAAS,0BACV,CAAC,CACD,UAAW,GAAU,EAAsB,CAExC,EAAwC,EAAE,OAAO,CACrD,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAE,EAAE,QAAQ,CAAC,CAAC,CAC1C,UAAW,EAAE,QAAQ,CACrB,iBAAkB,EAAE,MAAM,EAAE,KAAK,CAAC,mBAAoB,oBAAqB,QAAS,OAAQ,aAAa,CAAC,CAAC,CAC3G,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CAChB,MAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CAAC,CACrF,CAAC,CAEI,EACJ,EAAsC,OAAO,CAC3C,QAAS,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC9C,UAAW,EAAE,QAAQ,MAAM,CAC3B,OAAQ,EAAiB,UAAU,CACnC,cAAe,EAAiB,UAAU,CAC3C,CAAC,CAEE,EACJ,EAAsC,OAAO,CAC3C,QAAS,EACN,QAAQ,CACR,OAAQ,GAAU,EAAe,EAAM,EAAI,EAAM,WAAW,UAAU,CAAE,CACvE,MAAO,kCACR,CAAC,CACD,UAAW,GAAU,EAAsB,CAC9C,UAAW,EAAE,QAAQ,MAAM,CAC5B,CAAC,CAOS,EAAoE,EAAE,MACjF,EAAE,MAAM,CACN,EACA,EACA,EAAsC,OACnC,GAAS,EAAK,YAAc,OAAS,EAAK,YAAc,MACzD,qDACD,CACF,CAAC,CACH,CAeY,EAAwD,EAAE,MACrE,EAAE,OAAO,CACP,QAAS,EACT,SAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CAChD,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CAChB,OAAQ,EAAE,QAAQ,CACnB,CAAC,CACH,CAuDK,EAA+B,EAAE,MAAM,CAAC,EAAkB,EAAkB,EAAyB,CAAC,CAO/F,EAAgD,EAAE,MAAM,CACnE,EAAE,OAAO,CACP,WAAY,EAAE,OAAO,CACnB,GAAI,EAAE,QAAQ,CACd,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CACjB,CAAC,CACF,SAAU,EAAE,OAAO,QAAQ,CAAC,aAAa,CACzC,UAAW,EAAE,OAAO,QAAQ,CAAC,aAAa,CAC1C,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CAItE,UAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACzC,KAAM,EACH,MACC,EAAE,OAAO,CACP,KAAM,EAAE,KAAK,CAAC,WAAY,MAAO,SAAU,WAAY,OAAQ,QAAS,QAAQ,CAAC,CACjF,KAAM,EAAE,QAAQ,CAChB,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CACvC,MAAO,EAAE,OAAO,CACd,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CACtE,QAAS,EACV,CAAC,CACF,MAAO,EAAE,SAAS,CAAC,UAAU,CAC9B,CAAC,CACH,CACA,UAAU,CAOb,YAAa,EAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,UAAU,CAEvD,oBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACnD,QAAS,EACT,gBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CACvD,SAAU,EACV,iBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CACxD,KAAM,EAAE,MAAM,CACf,CAAC,CACF,EAAE,OAAO,CACP,KAAM,EAAE,QAAQ,GAAK,CACtB,CAAC,CACH,CAAC,CAaW,EAAkF,EAAE,OAAO,CACtG,KAAM,EACN,GAAI,EACJ,MAAO,EAAE,OAAO,QAAQ,CAAC,aAAa,CACvC,CAAC,CAYW,EAAgF,EAAE,OAAO,CACpG,UAAW,EAAE,QAAQ,MAAM,CAC3B,gBAAiB,EAAE,QAAQ,CAC5B,CAAC,CA8BI,EAAkF,EAAE,OAAO,CAC/F,iBAAkB,EAAE,QAAQ,CAAC,IAAI,EAAE,CACnC,YAAa,EACb,UAAW,EAAE,QAAQ,CACrB,eAAgB,EAAE,QAAQ,CAC1B,MAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CACxB,OAAQ,EAAE,QAAQ,CAAC,MAAM,gBAAiB,2CAA2C,CACrF,eAAgB,EAAE,QAAQ,CAC3B,CAAC,CA8BI,EAAoE,EAAE,OAAO,CACjF,cAAe,EAAE,QAAQ,SAAS,CAClC,OAAQ,EAAE,OAAO,CACf,KAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CACvB,QAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC1B,QAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACvC,kBAAmB,EACpB,CAAC,CACF,MAAO,EAAE,OAAO,EAAE,QAAQ,CAAE,EAAE,MAAM,EAAE,OAAO,CAAE,KAAM,EAAE,QAAQ,CAAE,KAAM,EAAE,QAAQ,CAAE,CAAC,CAAC,CAAC,CACtF,YAAa,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC9B,MAAO,EACJ,OAAO,CACN,OAAQ,EACR,QAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC1B,GAAI,EACJ,MAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACtC,CAAC,CACD,OAAO,CACX,CAAC,CAuBI,EAAkE,EAAE,OAAO,CAC/E,SAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC3B,OAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CACzB,KAAM,EACH,OAAO,CACN,KAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CACvB,GAAI,EACJ,MAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACrC,OAAQ,EACR,cAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC7C,iBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACjD,CAAC,CACD,OAAO,CACX,CAAC,CAkDW,EAAoF,EAAE,OAAO,CACxG,KAAM,EAAE,QAAQ,uBAAuB,CACvC,gBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAC5C,MAAO,EAAE,QAAQ,CAAC,MAAM,QAAS,iCAAiC,CAClE,GAAI,EACJ,UAAW,EACX,WAAY,EACZ,KAAM,EAA8B,UAAU,CAC9C,UAAW,EAA6B,UAAU,CACnD,CAAC,CAOW,EAA8C,EAAE,MAAM,CACjE,EACA,EACA,EACD,CAAC,CAWW,EAAmD,EAC7D,SAAS,CACT,OACE,GACC,EAEE,OAAO,GAAS,UADhB,GAEA,UAAW,GACX,OAAQ,EAA4B,OAAU,UAElD,CAAE,QAAS,kEAAmE,CAC/E,CAUU,EAA4D,EAAE,OAAO,CAChF,IAAK,EAAE,KAAK,CAAC,aAAa,CAC1B,KAAM,EAAE,QAAQ,CACjB,CAAC,CA8HI,EAAqC,yBAIrC,EAAW,EAAE,IAChB,SAAS,CAAE,MAAO,GAAM,CAAC,CACzB,OACE,GAAU,CAIT,IAAM,EADc,EAAmC,KAAK,EAAM,CAClC,EAAQ,GAAG,EAAM,GAEjD,OAAO,EAAE,IAAI,UAAU,CAAC,UAAU,EAAU,CAAC,SAE/C,CACE,MAAO,gFACR,CACF,CACA,UAAW,GACU,EAAmC,KAAK,EAAM,CAC7C,EAAQ,GAAG,EAAM,GACtC,CAES,EAAsE,EAAE,OAAO,CAC1F,UAAW,EAAE,QAAQ,CAAC,UAAU,CAChC,OAAQ,EAAE,KAAK,CAAC,UAAW,YAAa,oBAAqB,YAAa,SAAU,WAAY,UAAU,CAAC,CAC3G,YAAa,EAAE,QAAQ,CACvB,YAAa,EAAE,OAAO,CACpB,KAAM,EAAE,QAAQ,CAChB,gBAAiB,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAC1D,UAAW,EACX,UAAW,EAAS,GAAG,EAAE,SAAS,CAAC,CAAC,UAAU,CAC/C,CAAC,CACF,iBAAkB,EAAE,OAAO,CACzB,KAAM,EAAE,QAAQ,CAAC,UAAU,CAC3B,gBAAiB,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAAC,UAAU,CACrE,WAAY,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAAC,UAAU,CAAC,UAAU,CAC3E,UAAW,EAAS,UAAU,CAC9B,UAAW,EAAS,UAAU,CAC/B,CAAC,CACF,SAAU,EAAE,OAAO,CACjB,UAAW,EAAE,SAAS,CACtB,gBAAiB,EAAS,UAAU,CAAC,UAAU,CAC/C,SAAU,EAAE,SAAS,CACtB,CAAC,CACF,KAAM,EACH,OAAO,CACN,MAAO,EAAE,MAAM,CAAC,EAAkB,EAAiB,CAAC,CAAC,UAAU,CAC/D,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,UAAU,CACnD,CAAC,CACD,UAAU,CACb,kBAAmB,EAAE,MACnB,EAAE,OAAO,CACP,MAAO,EAAE,MAAM,CAAC,EAAkB,EAAiB,CAAC,CACpD,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CACxC,CAAC,CACH,CACD,MAAO,EACJ,YAAY,CACX,UAAW,EAAE,QAAQ,CACrB,OAAQ,EAAE,QAAQ,CAClB,iBAAkB,EAAE,QAAQ,CAC5B,kBAAmB,EAAE,QAAQ,CAC7B,YAAa,EAAE,QAAQ,CACvB,WAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC1C,YAAa,EAAE,IAAI,UAAU,CAC7B,YAAa,EAAE,QAAQ,CACvB,aAAc,EAAE,QAAQ,CACxB,UAAW,EAAE,IAAI,UAAU,CAC5B,CAAC,CACD,SAAS,CACT,UAAU,CACV,UAAU,CACd,CAAC,CAMW,EAAkE,EAAE,OAAO,CACtF,QAAS,EACV,CAAC"}
1
+ {"version":3,"file":"_schema.js","names":[],"sources":["../../../src/transfer-service/markr/_schema.ts"],"sourcesContent":["import type { Signature, Address as SolAddress } from '@solana/kit';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { z } from 'zod';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport {\n EvmAddressSchema,\n HashSchema,\n HexSchema,\n HyperliquidAddressSchema,\n SolAddressSchema,\n SolSignatureSchema,\n} from '../service-schemas';\n\ninterface SupportedChainsResponseItemBase {\n chainId: number | string;\n chainType: string;\n /** Available services on the chain. Each service has specific functionality */\n enabled_services: Array<'cross-chain-swap' | 'cross-chain-quote' | 'quote' | 'swap' | 'token-list'>;\n /** Chain logo URL */\n logo_url: string;\n /** Chain display name */\n name: string;\n /**\n * List of chain IDs that this chain can swap to via cross-chain aggregators.\n *\n * Empty array means no cross-chain routes available.\n */\n lanes: ReadonlyArray<number | Caip2ChainId>;\n}\n\nexport interface SupportedChainsResponseItemEvm extends SupportedChainsResponseItemBase {\n /** Chain identifier */\n chainId: number;\n /** Chain virtual machine type */\n chainType: 'evm';\n /** Router contract address */\n router?: EvmAddress;\n /** Native token wrapped contract address */\n wrapped_token?: EvmAddress;\n /**\n * Recurring-swap (DCA) capability metadata for this chain. Absent when the\n * orchestrator does not enable recurring swaps for the chain.\n *\n * @see https://orchestrator-docs.markr.io/#/Recurring%20Swaps\n */\n recurring?: {\n /** Lower bound for `intervalSeconds` accepted by `/recurring/quote`. */\n minFrequencySeconds: number;\n supportedTokens: ReadonlyArray<{\n address: EvmAddress;\n /** Smallest-unit decimal string — per-order minimum input. */\n minimumAmount: string;\n }>;\n };\n}\n\nexport interface SupportedChainsResponseItemSvm extends SupportedChainsResponseItemBase {\n /** Chain identifier */\n chainId: Caip2ChainId;\n /** Chain virtual machine type */\n chainType: 'svm';\n}\n\nexport type SupportedChainsResponse = Array<\n SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm | SupportedChainsResponseItemBase\n>;\n\nexport const Caip2ChainIdSchema: z.ZodType<Caip2ChainId> = z\n .string()\n .refine((value) => isCaip2ChainId(value), {\n message: 'Invalid CAIP-2 chain ID',\n })\n .transform((value) => value as Caip2ChainId);\n\nconst SupportedChainsResponseItemBaseSchema = z.object({\n chainId: z.union([z.number(), z.string()]),\n chainType: z.string(),\n enabled_services: z.array(z.enum(['cross-chain-swap', 'cross-chain-quote', 'quote', 'swap', 'token-list'])),\n logo_url: z.url(),\n name: z.string(),\n lanes: z.array(z.union([z.coerce.number().int().nonnegative(), Caip2ChainIdSchema])),\n});\n\nconst SupportedChainsResponseItemEvmSchema: z.ZodType<SupportedChainsResponseItemEvm> =\n SupportedChainsResponseItemBaseSchema.extend({\n chainId: z.coerce.number().int().nonnegative(),\n chainType: z.literal('evm'),\n router: EvmAddressSchema.optional(),\n wrapped_token: EvmAddressSchema.optional(),\n recurring: z\n .object({\n minFrequencySeconds: z.number().int().nonnegative(),\n supportedTokens: z.array(\n z.object({\n address: EvmAddressSchema,\n // Decimal string — must be `BigInt()`-parseable (see\n // checkRecurringEligibility's `BigInt(minimumAmount)` call).\n minimumAmount: z.string().regex(/^\\d+$/, 'minimumAmount must be a decimal string'),\n }),\n ),\n })\n .optional(),\n });\n\nconst SupportedChainsResponseItemSvmSchema: z.ZodType<SupportedChainsResponseItemSvm> =\n SupportedChainsResponseItemBaseSchema.extend({\n chainId: z\n .string()\n .refine((value) => isCaip2ChainId(value) && value.startsWith('solana:'), {\n error: 'Is not a valid Solana CAIP-2 ID',\n })\n .transform((value) => value as Caip2ChainId),\n chainType: z.literal('svm'),\n });\n\n/**\n * Schema for the response from Markr's /info/chains endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1info~1chains/get\n */\nexport const SupportedChainsResponseSchema: z.ZodType<SupportedChainsResponse> = z.array(\n z.union([\n SupportedChainsResponseItemEvmSchema,\n SupportedChainsResponseItemSvmSchema,\n SupportedChainsResponseItemBaseSchema.refine(\n (item) => item.chainType !== 'evm' && item.chainType !== 'svm',\n 'Known chain types must match their expected schema',\n ),\n ]),\n);\n\nexport type TokenListResponse = Array<{\n address: EvmAddress;\n decimals: number;\n logo_url: string;\n name: string;\n symbol: string;\n}>;\n\n/**\n * Schema for the response Markr's /tokens/{chainId}/list endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1tokens~1%7BchainId%7D~1list/get\n */\nexport const TokenListResponseSchema: z.ZodType<TokenListResponse> = z.array(\n z.object({\n address: EvmAddressSchema,\n decimals: z.number().int().nonnegative().max(18),\n logo_url: z.url(),\n name: z.string(),\n symbol: z.string(),\n }),\n);\n\nexport interface QuoteResponseData {\n aggregator: {\n id: string;\n logo_url: string;\n name: string;\n };\n amountIn: bigint;\n amountOut: bigint;\n /** Chain identifier (number for EVM chains, CAIP-2 ID for SVM chains) */\n chainId: number | Caip2ChainId;\n expiredAt: number;\n /**\n * Fee breakdown for cross-chain bridge transactions.\n *\n * Only included in quotes from cross-chain aggregators (DeBridge, LiFi).\n */\n fees?: ReadonlyArray<{\n type: 'protocol' | 'gas' | 'bridge' | 'slippage' | 'swap' | 'other' | 'relay';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\n /**\n * Docs document `extra` as `boolean or object`. The boolean form is the\n * legacy \"additive one-time charge\" flag; the object form is reserved\n * for future structured metadata. Consumers should treat any truthy\n * value as \"this fee is on top of the input amount and must be balance-\n * checked separately.\"\n */\n extra?: boolean | Record<string, unknown>;\n /** Token the fee is deducted from */\n token: {\n /** Chain ID where fee is deducted */\n chainId: number | Caip2ChainId;\n /** Token address (EVM hex or Solana base58) */\n address: EvmAddress | SolAddress;\n };\n }>;\n gasEstimate?: bigint;\n recommendedSlippage: number;\n /** Input token address (EVM hex or Solana base58) */\n tokenIn: EvmAddress | SolAddress;\n tokenInDecimals: number;\n /** Output token address (EVM hex or Solana base58) */\n tokenOut: EvmAddress | SolAddress;\n tokenOutDecimals: number;\n uuid: string;\n}\n\nexport interface QuoteResponseDataDone {\n done: true;\n}\n\nexport type QuoteResponse = QuoteResponseData | QuoteResponseDataDone;\n\nconst MarkrQuoteTokenAddressSchema = z.union([EvmAddressSchema, SolAddressSchema, HyperliquidAddressSchema]);\n\n/**\n * Schema for the response from Markr's /quote endpoint.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1quote/post\n */\nexport const QuoteResponseSchema: z.ZodType<QuoteResponse> = z.union([\n z.object({\n aggregator: z.object({\n id: z.string(),\n logo_url: z.url(),\n name: z.string(),\n }),\n amountIn: z.coerce.bigint().nonnegative(),\n amountOut: z.coerce.bigint().nonnegative(),\n chainId: z.union([z.number().int().nonnegative(), Caip2ChainIdSchema]),\n /**\n * Unix time in seconds when the quote expires.\n */\n expiredAt: z.number().int().nonnegative(),\n fees: z\n .array(\n z.object({\n type: z.enum(['protocol', 'gas', 'bridge', 'slippage', 'swap', 'other', 'relay']),\n name: z.string(),\n amount: z.coerce.bigint().nonnegative(),\n token: z.object({\n chainId: z.union([z.number().int().nonnegative(), Caip2ChainIdSchema]),\n address: MarkrQuoteTokenAddressSchema,\n }),\n // Docs: `extra: boolean or object` — accept both. The boolean form\n // is the legacy \"is this an additive one-time charge\" flag; the\n // object form is reserved for future structured metadata.\n extra: z.union([z.boolean(), z.record(z.string(), z.unknown())]).optional(),\n }),\n )\n .optional(),\n /**\n * Estimated gas for the swap transaction.\n * Markr estimates already include a buffer.\n *\n * The API docs do not specify this field as optional, but in practice it can be missing.\n */\n gasEstimate: z.coerce.bigint().nonnegative().optional(),\n /** Recommended slippage in basis points. */\n recommendedSlippage: z.number().int().nonnegative(),\n tokenIn: MarkrQuoteTokenAddressSchema,\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: MarkrQuoteTokenAddressSchema,\n tokenOutDecimals: z.number().int().nonnegative().max(18),\n uuid: z.uuid(),\n }),\n z.object({\n done: z.literal(true),\n }),\n]);\n\n/**\n * Response type for Markr's /swap, /recurring/swap, and\n * /recurring/orders/{orderId}/cancel endpoints — all return the same\n * `WrappedTransaction` calldata shape per the orchestrator docs.\n *\n * @see https://orchestrator-docs.markr.io/#/paths/~1swap/post\n */\nexport interface WrappedSwapTransactionResponse {\n data: Hex;\n to: EvmAddress;\n value: bigint;\n /**\n * Sender address per the docs' `WrappedTransaction` schema. Optional in\n * the SDK because the caller (the wallet broadcasting the TX) already\n * knows their own from-address and the field has historically been\n * dropped on parse without consumer impact.\n */\n from?: EvmAddress;\n}\n\nexport const WrappedSwapTransactionResponseSchema: z.ZodType<WrappedSwapTransactionResponse> = z.object({\n data: HexSchema,\n to: EvmAddressSchema,\n value: z.coerce.bigint().nonnegative(),\n from: EvmAddressSchema.optional(),\n});\n\n/**\n * Solana swap transaction (returned for SVM chains).\n */\nexport interface SolanaSwapTransactionResponse {\n /** Chain type identifier */\n chainType: 'svm';\n /** Base64-encoded Solana transaction to be signed and sent by the client */\n swapTransaction: string;\n}\n\nexport const SolanaSwapTransactionResponseSchema: z.ZodType<SolanaSwapTransactionResponse> = z.object({\n chainType: z.literal('svm'),\n swapTransaction: z.base64(),\n});\n\n/**\n * `sendAsset` action parameters Relay produces for the deposit step.\n *\n * These are the exact strings the SDK must (a) include in the EIP-712 message\n * it signs and (b) submit verbatim as the `action` body to HL `/exchange`.\n * Keeping them pre-formatted by Relay (rather than reconstructed by the SDK)\n * eliminates drift — notably on `amount`, which Relay formats at the spot\n * token's display precision (e.g. `\"0.200000\"` for USDC, not the perps-side\n * `\"0.20000000\"`). Any mismatch between what we sign / submit and what Relay\n * recorded in the order makes Relay's indexer skip the on-chain `sendAsset`.\n */\nexport interface HyperliquidSendAssetParameters {\n /** `\"Mainnet\"` or `\"Testnet\"`. */\n hyperliquidChain: string;\n /** Relay's HL custodian — where the sendAsset transfers to. */\n destination: EvmAddress;\n /** Currently always `\"\"` for non-DEX withdrawals. */\n sourceDex: string;\n /** Currently always `\"\"` for non-DEX withdrawals. */\n destinationDex: string;\n /** HL `\"{symbol}:{spotEvmContract}\"` (e.g. `\"USDC:0x6d1e…054\"`). */\n token: string;\n /** Human-readable decimal, Relay-formatted at the spot token's display precision. */\n amount: string;\n /** Currently always `\"\"` for non-sub-account withdrawals. */\n fromSubAccount: string;\n}\n\nconst HyperliquidSendAssetParametersSchema: z.ZodType<HyperliquidSendAssetParameters> = z.object({\n hyperliquidChain: z.string().min(1),\n destination: EvmAddressSchema,\n sourceDex: z.string(),\n destinationDex: z.string(),\n token: z.string().min(1),\n amount: z.string().regex(/^\\d+(\\.\\d+)?$/, 'amount must be a positive decimal string'),\n fromSubAccount: z.string(),\n});\n\n/**\n * Pass-through EIP-712 envelope Relay returns inside the v2 swap response.\n *\n * The SDK no longer hardcodes Relay's `RelayNonceMapping` schema — instead it\n * forwards `domain` / `types` / `primaryType` / `value` to the wallet's typed-\n * data signer verbatim. Future Relay-side schema additions (e.g. `depositor`\n * was added in v2) propagate automatically without an SDK release.\n */\nexport interface RelayEip712SignEnvelope {\n signatureKind: 'eip712';\n domain: {\n name: string;\n version: string;\n chainId: number;\n verifyingContract: EvmAddress;\n };\n types: Record<string, ReadonlyArray<{ name: string; type: string }>>;\n primaryType: string;\n /** Relay binds at minimum these fields; additional keys (e.g. `depositor`) are forwarded verbatim. */\n value: {\n wallet: EvmAddress;\n chainId: string;\n id: Hex;\n nonce: number;\n [key: string]: unknown;\n };\n}\n\nconst RelayEip712SignEnvelopeSchema: z.ZodType<RelayEip712SignEnvelope> = z.object({\n signatureKind: z.literal('eip712'),\n domain: z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n chainId: z.number().int().nonnegative(),\n verifyingContract: EvmAddressSchema,\n }),\n types: z.record(z.string(), z.array(z.object({ name: z.string(), type: z.string() }))),\n primaryType: z.string().min(1),\n value: z\n .object({\n wallet: EvmAddressSchema,\n chainId: z.string().min(1),\n id: HashSchema,\n nonce: z.number().int().nonnegative(),\n })\n .loose(),\n});\n\n/**\n * Pass-through `/authorize` POST body Relay returns inside the v2 swap response.\n *\n * The SDK forwards `body` verbatim to Markr (which forwards verbatim to Relay).\n * Markr only normalizes `nonce` to a JSON number on the wire; everything else\n * is untouched, so new fields Relay adds are not rejected.\n */\nexport interface RelayAuthorizeEnvelope {\n endpoint: string;\n method: string;\n body: {\n type: string;\n id: Hex;\n nonce: number;\n wallet: EvmAddress;\n walletChainId: number;\n signatureChainId: number;\n [key: string]: unknown;\n };\n}\n\nconst RelayAuthorizeEnvelopeSchema: z.ZodType<RelayAuthorizeEnvelope> = z.object({\n endpoint: z.string().min(1),\n method: z.string().min(1),\n body: z\n .object({\n type: z.string().min(1),\n id: HashSchema,\n nonce: z.number().int().nonnegative(),\n wallet: EvmAddressSchema,\n walletChainId: z.number().int().nonnegative(),\n signatureChainId: z.number().int().nonnegative(),\n })\n .loose(),\n});\n\n/**\n * Hyperliquid 2-phase withdrawal variant (source chain = `eip155:1337`).\n *\n * Markr returns:\n * - the dynamic envelope (`nonce`, `id`, `requestId`) used for the authorize\n * signature and status polling, and\n * - the full `parameters` object Relay produced for the deposit step's\n * `sendAsset` action, which the SDK signs verbatim and submits to HL.\n *\n * Starting at `protocolVersion: 2`, Relay's full EIP-712 envelope (`sign`) and\n * the `/authorize` POST body (`authorize`) are passed through verbatim — the\n * SDK no longer reconstructs Relay's schemas, so additive Relay changes (e.g.\n * `depositor` field) flow through without an SDK release.\n *\n * Important: `id` and `requestId` are TWO DIFFERENT bytes32s.\n * - `id` is the **order id** — it goes into the EIP-712 `NonceMapping`\n * message and Relay's `/authorize` POST body. Sourced from\n * `steps[0].items[0].data.sign.value.id` (== `data.post.body.id` ==\n * `protocol.v2.orderId`).\n * - `requestId` is the **tracking id** used only for\n * `/intents/status/v3?requestId=…` polling. Sourced from\n * `steps[0].requestId`.\n *\n * Swapping these two looks superficially correct (both are `0x{64hex}`) but\n * makes the on-chain `sendAsset` un-matchable by Relay's indexer.\n *\n * The SDK pins the static HL-side `SendAsset` shape (which HL owns) as a\n * constant in `_hyperliquid-eip712.ts`. Relay's nonce-mapping shape is now\n * dynamic via the `sign` envelope.\n */\nexport interface HyperliquidWithdrawSwapResponse {\n type: 'hyperliquid-withdraw';\n /** SDK validates against `SUPPORTED_HL_PROTOCOL_VERSIONS`; bumps when Relay/HL EIP-712 schemas change. */\n protocolVersion: number;\n /** Shared between authorize + sendAsset signatures; uint64 decimal string. */\n nonce: string;\n /** Order id signed inside the `NonceMapping` message and posted to `/authorize`. */\n id: Hex;\n /** Tracking id for cross-chain status polling (`/intents/status/v3?requestId=…`). */\n requestId: Hex;\n /** Relay-canonical `sendAsset` action parameters; signed and submitted verbatim. */\n parameters: HyperliquidSendAssetParameters;\n /** Relay's full EIP-712 nonce-mapping envelope. v2+. */\n sign?: RelayEip712SignEnvelope;\n /** Relay's `/authorize` POST descriptor (we forward `body` verbatim). v2+. */\n authorize?: RelayAuthorizeEnvelope;\n}\n\nexport const HyperliquidWithdrawSwapResponseSchema: z.ZodType<HyperliquidWithdrawSwapResponse> = z.object({\n type: z.literal('hyperliquid-withdraw'),\n protocolVersion: z.number().int().positive(),\n nonce: z.string().regex(/^\\d+$/, 'nonce must be a decimal string'),\n id: HashSchema,\n requestId: HashSchema,\n parameters: HyperliquidSendAssetParametersSchema,\n sign: RelayEip712SignEnvelopeSchema.optional(),\n authorize: RelayAuthorizeEnvelopeSchema.optional(),\n});\n\nexport type SwapResponse =\n | WrappedSwapTransactionResponse\n | SolanaSwapTransactionResponse\n | HyperliquidWithdrawSwapResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\n HyperliquidWithdrawSwapResponseSchema,\n]);\n\n/**\n * Markr `/authorize` response.\n *\n * The success body is documented as opaque, so we only assert that:\n * 1. the parsed JSON isn't an error envelope (`{ error: \"...\" }`) — Markr's\n * upstream (Relay) can return a 200 with an error payload when the\n * authorize is rejected after HTTP success;\n * 2. nothing else, by design — schema bumps when Markr publishes a spec.\n */\nexport const MarkrAuthorizeResponseSchema: z.ZodType<unknown> = z\n .unknown()\n .refine(\n (data) =>\n !(\n data !== null &&\n typeof data === 'object' &&\n 'error' in data &&\n typeof (data as { error: unknown }).error === 'string'\n ),\n { message: 'Markr /authorize returned an error envelope despite 2xx status.' },\n );\n\nexport interface PartnerInfoResponse {\n /**\n * The partner fee in basis points collected on each swap.\n */\n fee: number;\n name: string;\n}\n\nexport const PartnerInfoResponseSchema: z.ZodType<PartnerInfoResponse> = z.object({\n fee: z.int().nonnegative(),\n name: z.string(),\n});\n\n/**\n * If the destination token is USDC, the flow is:\n * - pending -> committed -> completed\n *\n * If the destination token is not USDC, the flow is:\n * - pending -> committed -> pending_execution -> completed\n *\n * If the transaction fails at any point, the status will be 'failed'.\n */\nexport type CrossChainStatus =\n | /** Transaction submitted to CCIP */\n 'pending'\n /** Message committed, awaiting execution on destination chain */\n | 'committed'\n /** Message received on destination, swap pending execution by relayer */\n | 'pending_execution'\n /** Message executed successfully on destination chain */\n | 'completed'\n /** Swap expired, and funds were refunded (CCIP only) */\n | 'refunded'\n /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /**\n * Cross-chain transaction identifier.\n *\n * For CCIP: The CCIP message ID.\n * For DeBridge: The DeBridge order ID.\n */\n messageId: string | null;\n /** Current status of the cross-chain transaction. */\n status: CrossChainStatus;\n /** Human-readable status description */\n description: string;\n /** Source chain information */\n sourceChain: {\n /** Source chain network name */\n name: string;\n /** Source chain transaction hash */\n transactionHash: Hash | Signature;\n /** Transaction timestamp on source chain (ISO 8601) */\n timestamp: string;\n /** When the source transaction was finalized (ISO 8601) */\n finalized: string | boolean | null;\n };\n /** Destination chain information */\n destinationChain: {\n /** Destination chain network name */\n name: string | null;\n /**\n * Destination chain tx hash.\n *\n * - For direct transfers (USDC -> USDC): The CCIP bridge transaction hash.\n * - For successful swaps: The actual swap transaction hash from the relayer.\n * - For pending swaps: null (swap not yet executed).\n */\n transactionHash: Hash | Signature | null;\n /**\n * CCIP bridge tx hash (only present for swaps, not direct transfers).\n *\n * This is the transaction that delivered USDC to the destination chain via CCIP.\n * The `transactionHash` field contains the subsequent swap transaction.\n */\n bridgeHash?: Hash | Signature | null;\n /** Transaction timestamp on destination chain (null if not yet executed) (ISO 8601) */\n timestamp: string | null;\n /** When the destination transaction was finalized (null if not yet executed) (ISO 8601) */\n finalized: string | null;\n };\n /** Transaction progress information */\n progress: {\n /** Whether the message has been committed on destination chain */\n committed: boolean;\n /** When the message was committed (null if not committed) (ISO 8601) */\n commitTimestamp?: string | null;\n /** Whether the message has been executed on destination chain */\n executed: boolean;\n };\n /** Fee information */\n fees: {\n /** Fee token address */\n token: EvmAddress | SolAddress | null;\n /** Fee amount in wei */\n amount: bigint | null;\n } | null;\n /** Tokens transferred in this cross-chain transaction */\n transferredTokens: ReadonlyArray<{\n /** Token address */\n token: EvmAddress | SolAddress;\n /** Token amount */\n amount: bigint;\n }>;\n /**\n * Debug information from Markr transaction API (only present for swaps that have been executed).\n *\n * Contains detailed information about the relayer execution, retry attempts, and transaction details.\n */\n debug?: Partial<{\n /** CCIP message ID */\n messageId: string;\n /** Execution status from relayer */\n status: string;\n /** Destination chain name */\n destinationChain: string;\n /** Destination swap transaction hash */\n destinationTxHash: string;\n /** Relay transaction hash */\n relayTxHash: string;\n /** Number of retry attempts */\n retryCount: number;\n /** Timestamp of last retry attempt (ISO 8601) */\n lastRetryAt: string;\n /** Source chain name */\n sourceChain: string;\n /** Source transaction hash */\n sourceTxHash: string;\n /** When the record was created (ISO 8601) */\n createdAt: string;\n }> | null;\n}\n\nconst ISO_8601_TIMEZONE_DESIGNATOR_REGEX = /[zZ]|[+-]\\d{2}:?\\d{2}$/;\n\n// Markr API returns ISO-8601 datetime strings that are sometimes missing a timezone designator (\"local\" ISO).\n// We assume these are meant to be UTC and append 'Z' if missing, then validate as strict ISO-8601 with timezone.\nconst datetime = z.iso\n .datetime({ local: true })\n .refine(\n (value) => {\n // Accept at least local ISO format\n // If missing timezone, treat as UTC\n const hasTimezone = ISO_8601_TIMEZONE_DESIGNATOR_REGEX.test(value);\n const isoString = hasTimezone ? value : `${value}Z`;\n // Validate as strict ISO-8601 with timezone\n return z.iso.datetime().safeParse(isoString).success;\n },\n {\n error: 'Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)',\n },\n )\n .transform((value) => {\n const hasTimezone = ISO_8601_TIMEZONE_DESIGNATOR_REGEX.test(value);\n return hasTimezone ? value : `${value}Z`;\n });\n\nexport const CrossChainStatusResponseSchema: z.ZodType<CrossChainStatusResponse> = z.object({\n messageId: z.string().nullable(),\n status: z.enum(['pending', 'committed', 'pending_execution', 'completed', 'failed', 'refunded', 'unknown']),\n description: z.string(),\n sourceChain: z.object({\n name: z.string(),\n transactionHash: z.union([HashSchema, SolSignatureSchema]),\n timestamp: datetime,\n finalized: datetime.or(z.boolean()).nullable(),\n }),\n destinationChain: z.object({\n name: z.string().nullable(),\n transactionHash: z.union([HashSchema, SolSignatureSchema]).nullable(),\n bridgeHash: z.union([HashSchema, SolSignatureSchema]).nullable().optional(),\n timestamp: datetime.nullable(),\n finalized: datetime.nullable(),\n }),\n progress: z.object({\n committed: z.boolean(),\n commitTimestamp: datetime.nullable().optional(),\n executed: z.boolean(),\n }),\n fees: z\n .object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n })\n .nullable(),\n transferredTokens: z.array(\n z.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]),\n amount: z.coerce.bigint().nonnegative(),\n }),\n ),\n debug: z\n .looseObject({\n messageId: z.string(),\n status: z.string(),\n destinationChain: z.string(),\n destinationTxHash: z.string(),\n relayTxHash: z.string(),\n retryCount: z.number().int().nonnegative(),\n lastRetryAt: z.iso.datetime(),\n sourceChain: z.string(),\n sourceTxHash: z.string(),\n createdAt: z.iso.datetime(),\n })\n .partial()\n .nullable()\n .optional(),\n});\n\nexport interface SpenderAddressResponse {\n address: EvmAddress;\n}\n\nexport const SpenderAddressResponseSchema: z.ZodType<SpenderAddressResponse> = z.object({\n address: EvmAddressSchema,\n});\n"],"mappings":"iPAqEA,MAAa,EAA8C,EACxD,QAAQ,CACR,OAAQ,GAAU,EAAe,EAAM,CAAE,CACxC,QAAS,0BACV,CAAC,CACD,UAAW,GAAU,EAAsB,CAExC,EAAwC,EAAE,OAAO,CACrD,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAE,EAAE,QAAQ,CAAC,CAAC,CAC1C,UAAW,EAAE,QAAQ,CACrB,iBAAkB,EAAE,MAAM,EAAE,KAAK,CAAC,mBAAoB,oBAAqB,QAAS,OAAQ,aAAa,CAAC,CAAC,CAC3G,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CAChB,MAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CAAC,CACrF,CAAC,CAEI,EACJ,EAAsC,OAAO,CAC3C,QAAS,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC9C,UAAW,EAAE,QAAQ,MAAM,CAC3B,OAAQ,EAAiB,UAAU,CACnC,cAAe,EAAiB,UAAU,CAC1C,UAAW,EACR,OAAO,CACN,oBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACnD,gBAAiB,EAAE,MACjB,EAAE,OAAO,CACP,QAAS,EAGT,cAAe,EAAE,QAAQ,CAAC,MAAM,QAAS,yCAAyC,CACnF,CAAC,CACH,CACF,CAAC,CACD,UAAU,CACd,CAAC,CAEE,EACJ,EAAsC,OAAO,CAC3C,QAAS,EACN,QAAQ,CACR,OAAQ,GAAU,EAAe,EAAM,EAAI,EAAM,WAAW,UAAU,CAAE,CACvE,MAAO,kCACR,CAAC,CACD,UAAW,GAAU,EAAsB,CAC9C,UAAW,EAAE,QAAQ,MAAM,CAC5B,CAAC,CAOS,EAAoE,EAAE,MACjF,EAAE,MAAM,CACN,EACA,EACA,EAAsC,OACnC,GAAS,EAAK,YAAc,OAAS,EAAK,YAAc,MACzD,qDACD,CACF,CAAC,CACH,CAeY,EAAwD,EAAE,MACrE,EAAE,OAAO,CACP,QAAS,EACT,SAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CAChD,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CAChB,OAAQ,EAAE,QAAQ,CACnB,CAAC,CACH,CAyDK,EAA+B,EAAE,MAAM,CAAC,EAAkB,EAAkB,EAAyB,CAAC,CAO/F,EAAgD,EAAE,MAAM,CACnE,EAAE,OAAO,CACP,WAAY,EAAE,OAAO,CACnB,GAAI,EAAE,QAAQ,CACd,SAAU,EAAE,KAAK,CACjB,KAAM,EAAE,QAAQ,CACjB,CAAC,CACF,SAAU,EAAE,OAAO,QAAQ,CAAC,aAAa,CACzC,UAAW,EAAE,OAAO,QAAQ,CAAC,aAAa,CAC1C,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CAItE,UAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACzC,KAAM,EACH,MACC,EAAE,OAAO,CACP,KAAM,EAAE,KAAK,CAAC,WAAY,MAAO,SAAU,WAAY,OAAQ,QAAS,QAAQ,CAAC,CACjF,KAAM,EAAE,QAAQ,CAChB,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CACvC,MAAO,EAAE,OAAO,CACd,QAAS,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAE,EAAmB,CAAC,CACtE,QAAS,EACV,CAAC,CAIF,MAAO,EAAE,MAAM,CAAC,EAAE,SAAS,CAAE,EAAE,OAAO,EAAE,QAAQ,CAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAC5E,CAAC,CACH,CACA,UAAU,CAOb,YAAa,EAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,UAAU,CAEvD,oBAAqB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACnD,QAAS,EACT,gBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CACvD,SAAU,EACV,iBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,CACxD,KAAM,EAAE,MAAM,CACf,CAAC,CACF,EAAE,OAAO,CACP,KAAM,EAAE,QAAQ,GAAK,CACtB,CAAC,CACH,CAAC,CAsBW,EAAkF,EAAE,OAAO,CACtG,KAAM,EACN,GAAI,EACJ,MAAO,EAAE,OAAO,QAAQ,CAAC,aAAa,CACtC,KAAM,EAAiB,UAAU,CAClC,CAAC,CAYW,EAAgF,EAAE,OAAO,CACpG,UAAW,EAAE,QAAQ,MAAM,CAC3B,gBAAiB,EAAE,QAAQ,CAC5B,CAAC,CA8BI,EAAkF,EAAE,OAAO,CAC/F,iBAAkB,EAAE,QAAQ,CAAC,IAAI,EAAE,CACnC,YAAa,EACb,UAAW,EAAE,QAAQ,CACrB,eAAgB,EAAE,QAAQ,CAC1B,MAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CACxB,OAAQ,EAAE,QAAQ,CAAC,MAAM,gBAAiB,2CAA2C,CACrF,eAAgB,EAAE,QAAQ,CAC3B,CAAC,CA8BI,EAAoE,EAAE,OAAO,CACjF,cAAe,EAAE,QAAQ,SAAS,CAClC,OAAQ,EAAE,OAAO,CACf,KAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CACvB,QAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC1B,QAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACvC,kBAAmB,EACpB,CAAC,CACF,MAAO,EAAE,OAAO,EAAE,QAAQ,CAAE,EAAE,MAAM,EAAE,OAAO,CAAE,KAAM,EAAE,QAAQ,CAAE,KAAM,EAAE,QAAQ,CAAE,CAAC,CAAC,CAAC,CACtF,YAAa,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC9B,MAAO,EACJ,OAAO,CACN,OAAQ,EACR,QAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC1B,GAAI,EACJ,MAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACtC,CAAC,CACD,OAAO,CACX,CAAC,CAuBI,EAAkE,EAAE,OAAO,CAC/E,SAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAC3B,OAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CACzB,KAAM,EACH,OAAO,CACN,KAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CACvB,GAAI,EACJ,MAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACrC,OAAQ,EACR,cAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC7C,iBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CACjD,CAAC,CACD,OAAO,CACX,CAAC,CAkDW,EAAoF,EAAE,OAAO,CACxG,KAAM,EAAE,QAAQ,uBAAuB,CACvC,gBAAiB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAC5C,MAAO,EAAE,QAAQ,CAAC,MAAM,QAAS,iCAAiC,CAClE,GAAI,EACJ,UAAW,EACX,WAAY,EACZ,KAAM,EAA8B,UAAU,CAC9C,UAAW,EAA6B,UAAU,CACnD,CAAC,CAOW,EAA8C,EAAE,MAAM,CACjE,EACA,EACA,EACD,CAAC,CAWW,EAAmD,EAC7D,SAAS,CACT,OACE,GACC,EAEE,OAAO,GAAS,UADhB,GAEA,UAAW,GACX,OAAQ,EAA4B,OAAU,UAElD,CAAE,QAAS,kEAAmE,CAC/E,CAUU,EAA4D,EAAE,OAAO,CAChF,IAAK,EAAE,KAAK,CAAC,aAAa,CAC1B,KAAM,EAAE,QAAQ,CACjB,CAAC,CA8HI,EAAqC,yBAIrC,EAAW,EAAE,IAChB,SAAS,CAAE,MAAO,GAAM,CAAC,CACzB,OACE,GAAU,CAIT,IAAM,EADc,EAAmC,KAAK,EAAM,CAClC,EAAQ,GAAG,EAAM,GAEjD,OAAO,EAAE,IAAI,UAAU,CAAC,UAAU,EAAU,CAAC,SAE/C,CACE,MAAO,gFACR,CACF,CACA,UAAW,GACU,EAAmC,KAAK,EAAM,CAC7C,EAAQ,GAAG,EAAM,GACtC,CAES,EAAsE,EAAE,OAAO,CAC1F,UAAW,EAAE,QAAQ,CAAC,UAAU,CAChC,OAAQ,EAAE,KAAK,CAAC,UAAW,YAAa,oBAAqB,YAAa,SAAU,WAAY,UAAU,CAAC,CAC3G,YAAa,EAAE,QAAQ,CACvB,YAAa,EAAE,OAAO,CACpB,KAAM,EAAE,QAAQ,CAChB,gBAAiB,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAC1D,UAAW,EACX,UAAW,EAAS,GAAG,EAAE,SAAS,CAAC,CAAC,UAAU,CAC/C,CAAC,CACF,iBAAkB,EAAE,OAAO,CACzB,KAAM,EAAE,QAAQ,CAAC,UAAU,CAC3B,gBAAiB,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAAC,UAAU,CACrE,WAAY,EAAE,MAAM,CAAC,EAAY,EAAmB,CAAC,CAAC,UAAU,CAAC,UAAU,CAC3E,UAAW,EAAS,UAAU,CAC9B,UAAW,EAAS,UAAU,CAC/B,CAAC,CACF,SAAU,EAAE,OAAO,CACjB,UAAW,EAAE,SAAS,CACtB,gBAAiB,EAAS,UAAU,CAAC,UAAU,CAC/C,SAAU,EAAE,SAAS,CACtB,CAAC,CACF,KAAM,EACH,OAAO,CACN,MAAO,EAAE,MAAM,CAAC,EAAkB,EAAiB,CAAC,CAAC,UAAU,CAC/D,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,UAAU,CACnD,CAAC,CACD,UAAU,CACb,kBAAmB,EAAE,MACnB,EAAE,OAAO,CACP,MAAO,EAAE,MAAM,CAAC,EAAkB,EAAiB,CAAC,CACpD,OAAQ,EAAE,OAAO,QAAQ,CAAC,aAAa,CACxC,CAAC,CACH,CACD,MAAO,EACJ,YAAY,CACX,UAAW,EAAE,QAAQ,CACrB,OAAQ,EAAE,QAAQ,CAClB,iBAAkB,EAAE,QAAQ,CAC5B,kBAAmB,EAAE,QAAQ,CAC7B,YAAa,EAAE,QAAQ,CACvB,WAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,CAC1C,YAAa,EAAE,IAAI,UAAU,CAC7B,YAAa,EAAE,QAAQ,CACvB,aAAc,EAAE,QAAQ,CACxB,UAAW,EAAE,IAAI,UAAU,CAC5B,CAAC,CACD,SAAS,CACT,UAAU,CACV,UAAU,CACd,CAAC,CAMW,EAAkE,EAAE,OAAO,CACtF,QAAS,EACV,CAAC"}
@@ -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/evm-address.cjs`),a=require(`../../_utils/math.cjs`),o=require(`./_api.cjs`),s=require(`../../utils/sol-address.cjs`);let c=require(`viem`);function l(e,t,n){let r=e.get(t),i=e.get(n);return!r||!i?!1:t===n?r.swapEnabled:r.crossChainSwapEnabled&&r.crossChainTargetChainIds.has(n)}async function u(e,r=!1){let i=new Map;try{let t=(await o.markrGetInfoChains(e)).filter(e=>e.chainType===`evm`||e.chainType===`svm`);for(let e of t){let t=typeof e.chainId==`number`?n.eip155ChainIdToCaip2(e.chainId):e.chainId,a=e.enabled_services.includes(`cross-chain-quote`)&&e.enabled_services.includes(`cross-chain-swap`),o=e.enabled_services.includes(`quote`)&&e.enabled_services.includes(`swap`),s=new Set;for(let r of e.lanes){let e=typeof r==`number`?n.eip155ChainIdToCaip2(r):r;e!==t&&s.add(e)}let c=r?!1:a,l=c?s:new Set;!o&&l.size===0||i.set(t,{chainId:e.chainId,crossChainSwapEnabled:c,crossChainTargetChainIds:l,swapEnabled:o,tokenList:e.enabled_services.includes(`token-list`)})}}catch(e){throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch supported chains from Markr API.`})}return i}async function d(e,t){let n=new Map;for(let[r,i]of t.entries())if(typeof i.chainId==`number`&&i.tokenList&&(i.crossChainSwapEnabled||i.swapEnabled))try{let t=o.markrGetTokenList(e,i.chainId);n.set(r,t)}catch{}return n}function f(e){return e===`0x0000000000000000000000000000000000000000`||e===`11111111111111111111111111111111`}function p(t,n){return t.type===e.TokenType.NATIVE?r.isSolanaNamespace(n)?e.NATIVE_SOL_ADDRESS:e.ERC_ZERO_ADDRESS:t.address}function m({amountOut:e,assetOut:t,slippageBps:n}){let r=a.calculateMinimumAmountOut({amountOut:e,assetOut:t,slippageBps:n});return e>0n&&r===0n?1n:r}function h({assetIn:t,fees:n,sourceChain:r},i=3e3){return n.reduce((n,i)=>i.fundingModel!==`additive`||i.chainId!==r.chainId?n:t.type===e.TokenType.NATIVE?i.token.type===e.TokenType.NATIVE?n+i.amount:n:t.type===e.TokenType.ERC20?i.token.type===e.TokenType.ERC20&&(0,c.isAddressEqual)(i.token.address,t.address)?n+i.amount:n:i.token.type===e.TokenType.SPL&&i.token.address===t.address?n+i.amount:n,0n)*BigInt(1e4+i)/10000n}function g({fees:t,sourceChain:n}){return t.reduce((t,r)=>r.fundingModel!==`additive`||r.chainId!==n.chainId?t:r.token.type===e.TokenType.NATIVE?t+r.amount:t,0n)}function _(t,n,r){let i=t.amountOut*BigInt(r)/10000n,a=t.amountOut-i,o=[...y(t.fees),{type:`partner`,fundingModel:`included`,name:`Core Fee`,amount:i,chainId:n.targetChain.chainId,token:b(n.targetAsset)}];return{aggregator:{id:t.aggregator.id,logoUrl:t.aggregator.logo_url,name:t.aggregator.name},amountIn:t.amountIn,amountOut:a,assetIn:n.sourceAsset,assetOut:n.targetAsset,expiresAt:t.expiredAt,fees:o,fromAddress:n.fromAddress,gasEstimate:t.gasEstimate,id:t.uuid,partnerFeeBps:r,serviceType:e.ServiceType.MARKR,slippageBps:n.slippageBps??t.recommendedSlippage,sourceChain:n.sourceChain,targetChain:n.targetChain,toAddress:n.toAddress}}async function v(e){try{return(await o.markrGetPartnerInfo(e)).fee}catch(e){throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch partner info from Markr API.`})}}function y(t){if(!t)return[];let r=[];for(let a of t){let t=typeof a.token.chainId==`number`?n.eip155ChainIdToCaip2(a.token.chainId):a.token.chainId,o;f(a.token.address)?o={type:e.TokenType.NATIVE}:i.isEvmAddress(a.token.address)?o={type:e.TokenType.ERC20,address:a.token.address}:s.isSolAddress(a.token.address)&&(o={type:e.TokenType.SPL,address:a.token.address}),o&&r.push({type:a.type,fundingModel:a.extra?`additive`:`included`,name:a.name,amount:a.amount,chainId:t,token:o})}return r}function b(t){return t.type===e.TokenType.NATIVE?{type:e.TokenType.NATIVE}:t.type===e.TokenType.SPL?{type:e.TokenType.SPL,address:t.address}:{type:e.TokenType.ERC20,address:t.address}}async function x(e){return e?(await Promise.resolve().then(()=>require(`./_abis/cross-chain-swap-wrapper-abi.cjs`))).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI:(await Promise.resolve().then(()=>require(`./_abis/swap-wrapper-abi.cjs`))).MARKR_SWAP_WRAPPER_ABI}exports.assetToAddressString=p,exports.calculateMarkrMinimumAmountOut=m,exports.getAdditiveSourceAssetFeeAmount=h,exports.getAdditiveSourceNativeAssetFeeAmount=g,exports.getMarkrSwapWrapperAbi=x,exports.getPartnerFeeBps=v,exports.getSupportedChains=u,exports.getSupportedTokens=d,exports.isRouteSupported=l,exports.isTokenAddressNative=f,exports.quoteFromMarkrQuoteResponseData=_;
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/evm-address.cjs`),a=require(`../../_utils/math.cjs`),o=require(`./_api.cjs`),s=require(`../../utils/sol-address.cjs`);let c=require(`viem`);function l(e,t,n){let r=e.get(t),i=e.get(n);return!r||!i?!1:t===n?r.swapEnabled:r.crossChainSwapEnabled&&r.crossChainTargetChainIds.has(n)}async function u(e,r=!1){let i=new Map;try{let t=(await o.markrGetInfoChains(e)).filter(e=>e.chainType===`evm`||e.chainType===`svm`);for(let e of t){let t=typeof e.chainId==`number`?n.eip155ChainIdToCaip2(e.chainId):e.chainId,a=e.enabled_services.includes(`cross-chain-quote`)&&e.enabled_services.includes(`cross-chain-swap`),o=e.enabled_services.includes(`quote`)&&e.enabled_services.includes(`swap`),s=new Set;for(let r of e.lanes){let e=typeof r==`number`?n.eip155ChainIdToCaip2(r):r;e!==t&&s.add(e)}let c=r?!1:a,l=c?s:new Set;if(!o&&l.size===0)continue;let u=e.chainType===`evm`&&e.recurring?{minFrequencySeconds:e.recurring.minFrequencySeconds,supportedTokens:e.recurring.supportedTokens}:void 0;i.set(t,{chainId:e.chainId,crossChainSwapEnabled:c,crossChainTargetChainIds:l,swapEnabled:o,tokenList:e.enabled_services.includes(`token-list`),...u?{recurring:u}:{}})}}catch(e){throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch supported chains from Markr API.`})}return i}async function d(e,t){let n=new Map;for(let[r,i]of t.entries())if(typeof i.chainId==`number`&&i.tokenList&&(i.crossChainSwapEnabled||i.swapEnabled))try{let t=o.markrGetTokenList(e,i.chainId);n.set(r,t)}catch{}return n}function f(e){return e===`0x0000000000000000000000000000000000000000`||e===`11111111111111111111111111111111`}function p(t,n){return t.type===e.TokenType.NATIVE?r.isSolanaNamespace(n)?e.NATIVE_SOL_ADDRESS:e.ERC_ZERO_ADDRESS:t.address}function m({amountOut:e,assetOut:t,slippageBps:n}){let r=a.calculateMinimumAmountOut({amountOut:e,assetOut:t,slippageBps:n});return e>0n&&r===0n?1n:r}function h({assetIn:t,fees:n,sourceChain:r},i=3e3){return n.reduce((n,i)=>i.fundingModel!==`additive`||i.chainId!==r.chainId?n:t.type===e.TokenType.NATIVE?i.token.type===e.TokenType.NATIVE?n+i.amount:n:t.type===e.TokenType.ERC20?i.token.type===e.TokenType.ERC20&&(0,c.isAddressEqual)(i.token.address,t.address)?n+i.amount:n:i.token.type===e.TokenType.SPL&&i.token.address===t.address?n+i.amount:n,0n)*BigInt(1e4+i)/10000n}function g({fees:t,sourceChain:n}){return t.reduce((t,r)=>r.fundingModel!==`additive`||r.chainId!==n.chainId?t:r.token.type===e.TokenType.NATIVE?t+r.amount:t,0n)}function _(t,n,r){let i=t.amountOut*BigInt(r)/10000n,a=t.amountOut-i,o=[...y(t.fees),{type:`partner`,fundingModel:`included`,name:`Core Fee`,amount:i,chainId:n.targetChain.chainId,token:b(n.targetAsset)}];return{aggregator:{id:t.aggregator.id,logoUrl:t.aggregator.logo_url,name:t.aggregator.name},amountIn:t.amountIn,amountOut:a,assetIn:n.sourceAsset,assetOut:n.targetAsset,expiresAt:t.expiredAt,fees:o,fromAddress:n.fromAddress,gasEstimate:t.gasEstimate,id:t.uuid,partnerFeeBps:r,serviceType:e.ServiceType.MARKR,slippageBps:n.slippageBps??t.recommendedSlippage,sourceChain:n.sourceChain,targetChain:n.targetChain,toAddress:n.toAddress}}async function v(e){try{return(await o.markrGetPartnerInfo(e)).fee}catch(e){throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch partner info from Markr API.`})}}function y(t){if(!t)return[];let r=[];for(let a of t){let t=typeof a.token.chainId==`number`?n.eip155ChainIdToCaip2(a.token.chainId):a.token.chainId,o;f(a.token.address)?o={type:e.TokenType.NATIVE}:i.isEvmAddress(a.token.address)?o={type:e.TokenType.ERC20,address:a.token.address}:s.isSolAddress(a.token.address)&&(o={type:e.TokenType.SPL,address:a.token.address}),o&&r.push({type:a.type,fundingModel:a.extra?`additive`:`included`,name:a.name,amount:a.amount,chainId:t,token:o})}return r}function b(t){return t.type===e.TokenType.NATIVE?{type:e.TokenType.NATIVE}:t.type===e.TokenType.SPL?{type:e.TokenType.SPL,address:t.address}:{type:e.TokenType.ERC20,address:t.address}}async function x(e){return e?(await Promise.resolve().then(()=>require(`./_abis/cross-chain-swap-wrapper-abi.cjs`))).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI:(await Promise.resolve().then(()=>require(`./_abis/swap-wrapper-abi.cjs`))).MARKR_SWAP_WRAPPER_ABI}exports.assetToAddressString=p,exports.calculateMarkrMinimumAmountOut=m,exports.getAdditiveSourceAssetFeeAmount=h,exports.getAdditiveSourceNativeAssetFeeAmount=g,exports.getMarkrSwapWrapperAbi=x,exports.getPartnerFeeBps=v,exports.getSupportedChains=u,exports.getSupportedTokens=d,exports.isRouteSupported=l,exports.isTokenAddressNative=f,exports.quoteFromMarkrQuoteResponseData=_;
2
2
  //# sourceMappingURL=_utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_utils.cjs","names":["markrGetInfoChains","eip155ChainIdToCaip2","SdkError","ErrorReason","ErrorCode","markrGetTokenList","TokenType","isSolanaNamespace","NATIVE_SOL_ADDRESS","ERC_ZERO_ADDRESS","calculateMinimumAmountOut","ServiceType","markrGetPartnerInfo","isEvmAddress","isSolAddress"],"sources":["../../../src/transfer-service/markr/_utils.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../errors';\nimport { BaseError, decodeErrorResult, isAddressEqual, isHex, toFunctionSelector, type Hex } from 'viem';\nimport {\n type QuoteResponseData,\n type SupportedChainsResponseItemEvm,\n type SupportedChainsResponseItemSvm,\n type TokenListResponse,\n} from './_schema';\nimport { ERC_ZERO_ADDRESS, NATIVE_SOL_ADDRESS, ServiceType, TokenType } from '../../constants';\nimport { isSolanaNamespace } from '../../_utils/chain';\nimport { calculateMinimumAmountOut } from '../../_utils/math';\nimport { eip155ChainIdToCaip2 } from '../../utils/caip';\nimport type { Asset } from '../../types/asset';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Quote, QuoteFee, QuoteFees, QuoteFeeToken, QuoterProps } from '../../types/quote';\nimport { markrGetInfoChains, markrGetPartnerInfo, markrGetTokenList, type ApiOptions } from './_api';\nimport { isEvmAddress } from '../../utils/evm-address';\nimport { isSolAddress } from '../../utils/sol-address';\n\nexport type SupportedChainsMap = Map<\n Caip2ChainId,\n {\n /** `number` for EVM, `Caip2ChainId` for SVM */\n chainId: number | Caip2ChainId;\n crossChainSwapEnabled: boolean;\n crossChainTargetChainIds: ReadonlySet<Caip2ChainId>;\n swapEnabled: boolean;\n tokenList: boolean;\n }\n>;\n\n/**\n * Checks whether the given source → target chain route is supported by Markr.\n */\nexport function isRouteSupported(\n supportedChains: SupportedChainsMap,\n sourceChainId: Caip2ChainId,\n targetChainId: Caip2ChainId,\n): boolean {\n const sourceChain = supportedChains.get(sourceChainId);\n const targetChain = supportedChains.get(targetChainId);\n\n if (!sourceChain || !targetChain) return false;\n\n if (sourceChainId === targetChainId) {\n return sourceChain.swapEnabled;\n }\n\n return sourceChain.crossChainSwapEnabled && sourceChain.crossChainTargetChainIds.has(targetChainId);\n}\n\nexport async function getSupportedChains(\n apiOptions: ApiOptions,\n disableCrossChainSwaps = false,\n): Promise<SupportedChainsMap> {\n const supportedChains: SupportedChainsMap = new Map();\n\n try {\n const chains = await markrGetInfoChains(apiOptions);\n const filteredSupportedChains = chains.filter(\n (chain): chain is SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm => {\n // Only include chains types that we support in the SDK (EVM and Solana for now).\n return chain.chainType === 'evm' || chain.chainType === 'svm';\n },\n );\n\n for (const chain of filteredSupportedChains) {\n const key: Caip2ChainId = typeof chain.chainId === 'number' ? eip155ChainIdToCaip2(chain.chainId) : chain.chainId;\n\n const isCrossChainSwapEnabled =\n chain.enabled_services.includes('cross-chain-quote') && chain.enabled_services.includes('cross-chain-swap');\n const isSwapEnabled = chain.enabled_services.includes('quote') && chain.enabled_services.includes('swap');\n const normalizedLaneChainIds = new Set<Caip2ChainId>();\n\n for (const lane of chain.lanes) {\n const laneChainId = typeof lane === 'number' ? eip155ChainIdToCaip2(lane) : lane;\n\n if (laneChainId !== key) {\n normalizedLaneChainIds.add(laneChainId);\n }\n }\n\n const crossChainSwapEnabled = disableCrossChainSwaps ? false : isCrossChainSwapEnabled;\n const crossChainTargetChainIds = crossChainSwapEnabled ? normalizedLaneChainIds : new Set<Caip2ChainId>();\n\n if (!isSwapEnabled && crossChainTargetChainIds.size === 0) {\n continue;\n }\n\n supportedChains.set(key, {\n chainId: chain.chainId,\n crossChainSwapEnabled,\n crossChainTargetChainIds,\n swapEnabled: isSwapEnabled,\n tokenList: chain.enabled_services.includes('token-list'),\n });\n }\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch supported chains from Markr API.',\n });\n }\n\n return supportedChains;\n}\n\nexport async function getSupportedTokens(\n apiOptions: ApiOptions,\n supportedChains: SupportedChainsMap,\n): Promise<Map<Caip2ChainId, Promise<TokenListResponse>>> {\n // Parallel fetch token lists for all supported chains.\n const supportedTokens: Map<Caip2ChainId, Promise<TokenListResponse>> = new Map();\n\n for (const [caip2ChainId, chainInfo] of supportedChains.entries()) {\n // Only fetch token list for EVM chains that support swaps.\n if (\n typeof chainInfo.chainId === 'number' &&\n chainInfo.tokenList &&\n (chainInfo.crossChainSwapEnabled || chainInfo.swapEnabled)\n ) {\n try {\n const tokenListPromise = markrGetTokenList(apiOptions, chainInfo.chainId);\n supportedTokens.set(caip2ChainId, tokenListPromise);\n } catch {\n // Ignore errors for individual token list fetches.\n // TODO: Logger?\n }\n }\n }\n\n return supportedTokens;\n}\n\n/**\n * Determine if the provided token address represents the native token for its chain.\n *\n * Markr represents EVM native tokens as the zero address and Solana native SOL\n * as the wrapped SOL mint address.\n */\nexport function isTokenAddressNative(address: string): boolean {\n return address === ERC_ZERO_ADDRESS || address === NATIVE_SOL_ADDRESS;\n}\n\n/**\n * Convert an `Asset` to the address string expected by the Markr API.\n *\n * For NATIVE assets the representation depends on the chain:\n * - EVM chains: `0x0000...0000` (ERC zero address)\n * - Solana chains: `So11111111111111111111111111111111111111112` (wrapped SOL mint)\n *\n * @param asset The asset to convert.\n * @param chainId CAIP-2 chain ID used to disambiguate NATIVE assets across chain types.\n */\nexport function assetToAddressString(asset: Asset, chainId: Caip2ChainId): string {\n if (asset.type === TokenType.NATIVE) {\n if (isSolanaNamespace(chainId)) {\n return NATIVE_SOL_ADDRESS;\n }\n\n return ERC_ZERO_ADDRESS;\n }\n\n return asset.address;\n}\n\n/**\n * Markr rejects `minAmountOut=0` for non-zero quotes.\n *\n * For very small quotes, integer truncation after slippage can produce `0`.\n * Clamp to `1` in that edge case to satisfy Markr API validation while\n * preserving normal slippage behavior for larger quotes.\n */\nexport function calculateMarkrMinimumAmountOut({\n amountOut,\n assetOut,\n slippageBps,\n}: Pick<Quote, 'amountOut' | 'assetOut' | 'slippageBps'>): bigint {\n const minAmountOut = calculateMinimumAmountOut({ amountOut, assetOut, slippageBps });\n\n if (amountOut > 0n && minAmountOut === 0n) {\n return 1n;\n }\n\n return minAmountOut;\n}\n\n/**\n * Returns additive fee amount charged in the source asset on the source chain.\n *\n * This is used for allowance/balance checks where users must fund both the\n * transfer input and any additive source-asset fee components. A safety buffer\n * is applied to the additive fee total to reduce the chance of under-approvals.\n *\n * @see https://docs.debridge.com/dln-details/overview/fee-structure#best-practice-checklist-for-integrators\n *\n * @param quote The quote containing the fees to analyze.\n * @param bufferBps Buffer in basis points applied to the additive fee total.\n * Defaults to 3000 bps (30%).\n */\nexport function getAdditiveSourceAssetFeeAmount(\n { assetIn, fees, sourceChain }: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>,\n bufferBps = 3_000,\n): bigint {\n const additiveSourceAssetFeeAmount = fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n if (assetIn.type === TokenType.NATIVE) {\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }\n\n if (assetIn.type === TokenType.ERC20) {\n return fee.token.type === TokenType.ERC20 && isAddressEqual(fee.token.address, assetIn.address)\n ? total + fee.amount\n : total;\n }\n\n return fee.token.type === TokenType.SPL && fee.token.address === assetIn.address ? total + fee.amount : total;\n }, 0n);\n\n return (additiveSourceAssetFeeAmount * BigInt(10_000 + bufferBps)) / 10_000n;\n}\n\n/**\n * Returns additive fee amount charged in native asset on the source chain.\n */\nexport function getAdditiveSourceNativeAssetFeeAmount({\n fees,\n sourceChain,\n}: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>): bigint {\n return fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }, 0n);\n}\n\nexport function quoteFromMarkrQuoteResponseData(\n data: QuoteResponseData,\n quoterProps: QuoterProps,\n partnerFeeBps: number,\n): Quote {\n const partnerFee: bigint = (data.amountOut * BigInt(partnerFeeBps)) / 10_000n;\n const amountOutAfterFees: bigint = data.amountOut - partnerFee;\n\n const fees: QuoteFees = [\n ...mapMarkrQuoteResponseDataFeesToQuoteFees(data.fees),\n // Add the partner fee as a QuoteFee component for Markr quotes.\n {\n type: 'partner',\n fundingModel: 'included',\n name: 'Core Fee',\n amount: partnerFee,\n chainId: quoterProps.targetChain.chainId,\n token: assetToFeeToken(quoterProps.targetAsset),\n },\n ];\n\n return {\n aggregator: {\n id: data.aggregator.id,\n logoUrl: data.aggregator.logo_url,\n name: data.aggregator.name,\n },\n amountIn: data.amountIn,\n amountOut: amountOutAfterFees,\n assetIn: quoterProps.sourceAsset,\n assetOut: quoterProps.targetAsset,\n expiresAt: data.expiredAt, // Markr returns `expiredAt` as Unix time in seconds; use as-is.\n fees,\n fromAddress: quoterProps.fromAddress,\n /**\n * This gasEstimate is rough or may be missing.\n * Consumers should use TransferManager.estimateGas for a more accurate estimate.\n */\n gasEstimate: data.gasEstimate,\n id: data.uuid,\n partnerFeeBps,\n serviceType: ServiceType.MARKR,\n slippageBps: quoterProps.slippageBps ?? data.recommendedSlippage,\n sourceChain: quoterProps.sourceChain,\n targetChain: quoterProps.targetChain,\n toAddress: quoterProps.toAddress,\n } satisfies Quote;\n}\n\nexport async function getPartnerFeeBps(apiOptions: ApiOptions): Promise<number> {\n try {\n const partnerInfo = await markrGetPartnerInfo(apiOptions);\n return partnerInfo.fee;\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch partner info from Markr API.',\n });\n }\n}\n\nexport function mapMarkrQuoteResponseDataFeesToQuoteFees(markrFees: QuoteResponseData['fees']): QuoteFees {\n if (!markrFees) {\n return [];\n }\n\n const fees: QuoteFee[] = [];\n\n for (const fee of markrFees) {\n const chainId = typeof fee.token.chainId === 'number' ? eip155ChainIdToCaip2(fee.token.chainId) : fee.token.chainId;\n\n let token: QuoteFeeToken | undefined;\n\n if (isTokenAddressNative(fee.token.address)) {\n token = { type: TokenType.NATIVE };\n } else if (isEvmAddress(fee.token.address)) {\n token = { type: TokenType.ERC20, address: fee.token.address };\n } else if (isSolAddress(fee.token.address)) {\n token = { type: TokenType.SPL, address: fee.token.address };\n }\n\n if (!token) {\n // Skip fee if we can't determine token type.\n continue;\n }\n\n fees.push({\n type: fee.type,\n fundingModel: fee.extra ? 'additive' : 'included',\n name: fee.name,\n amount: fee.amount,\n chainId,\n token,\n });\n }\n\n return fees;\n}\n\nfunction assetToFeeToken(asset: Asset): QuoteFeeToken {\n if (asset.type === TokenType.NATIVE) {\n return { type: TokenType.NATIVE };\n }\n\n if (asset.type === TokenType.SPL) {\n return { type: TokenType.SPL, address: asset.address };\n }\n\n return { type: TokenType.ERC20, address: asset.address };\n}\n\nexport type MarkrRouterAbi =\n | (typeof import('./_abis/swap-wrapper-abi'))['MARKR_SWAP_WRAPPER_ABI']\n | (typeof import('./_abis/cross-chain-swap-wrapper-abi'))['MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI'];\n\nexport async function getMarkrSwapWrapperAbi(crossChain: boolean): Promise<MarkrRouterAbi> {\n if (crossChain) {\n return (await import('./_abis/cross-chain-swap-wrapper-abi')).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI;\n }\n\n return (await import('./_abis/swap-wrapper-abi')).MARKR_SWAP_WRAPPER_ABI;\n}\n\nfunction extractHexDataFromError(error: unknown): Hex | undefined {\n if (error instanceof BaseError) {\n const directData = (error as { data?: unknown }).data;\n if (isHex(directData)) return directData;\n\n let walkedData: Hex | undefined;\n error.walk((walkedError) => {\n const nestedData = (walkedError as { data?: unknown }).data;\n if (!walkedData && isHex(nestedData)) walkedData = nestedData;\n return false;\n });\n if (walkedData) return walkedData;\n\n const causeData = (error as { cause?: { data?: unknown } }).cause?.data;\n if (isHex(causeData)) return causeData;\n }\n\n if (!error || typeof error !== 'object') return undefined;\n\n const e = error as {\n data?: unknown;\n error?: { data?: unknown };\n cause?: { data?: unknown };\n response?: { data?: unknown };\n body?: { error?: { data?: unknown } };\n };\n\n if (isHex(e.data)) return e.data;\n if (isHex(e.error?.data)) return e.error.data;\n if (isHex(e.cause?.data)) return e.cause.data;\n if (isHex(e.response?.data)) return e.response.data;\n if (isHex(e.body?.error?.data)) return e.body.error.data;\n\n return undefined;\n}\n\nexport function decodeMarkrRevertError(abi: MarkrRouterAbi, error: unknown): string | null {\n const revertData = extractHexDataFromError(error);\n\n if (!revertData) {\n return null;\n }\n\n try {\n const decoded = decodeErrorResult({ abi, data: revertData });\n const decodedArgs = decoded.args.length > 0 ? `(${decoded.args.map(String).join(', ')})` : '()';\n\n return `${decoded.errorName}${decodedArgs}`;\n } catch {\n const selector = revertData.slice(0, 10).toLowerCase();\n\n for (const abiItem of abi) {\n if (abiItem.type !== 'error') {\n continue;\n }\n\n const signature = `${abiItem.name}(${abiItem.inputs.map((input) => input.type).join(',')})`;\n if (toFunctionSelector(signature).toLowerCase() === selector) {\n return `${abiItem.name}()`;\n }\n }\n }\n\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_utils.cjs","names":["markrGetInfoChains","eip155ChainIdToCaip2","SdkError","ErrorReason","ErrorCode","markrGetTokenList","TokenType","isSolanaNamespace","NATIVE_SOL_ADDRESS","ERC_ZERO_ADDRESS","calculateMinimumAmountOut","ServiceType","markrGetPartnerInfo","isEvmAddress","isSolAddress"],"sources":["../../../src/transfer-service/markr/_utils.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../errors';\nimport {\n BaseError,\n decodeErrorResult,\n isAddressEqual,\n isHex,\n toFunctionSelector,\n type Address as EvmAddress,\n type Hex,\n} from 'viem';\nimport {\n type QuoteResponseData,\n type SupportedChainsResponseItemEvm,\n type SupportedChainsResponseItemSvm,\n type TokenListResponse,\n} from './_schema';\nimport { ERC_ZERO_ADDRESS, NATIVE_SOL_ADDRESS, ServiceType, TokenType } from '../../constants';\nimport { isSolanaNamespace } from '../../_utils/chain';\nimport { calculateMinimumAmountOut } from '../../_utils/math';\nimport { eip155ChainIdToCaip2 } from '../../utils/caip';\nimport type { Asset } from '../../types/asset';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Quote, QuoteFee, QuoteFees, QuoteFeeToken, QuoterProps } from '../../types/quote';\nimport { markrGetInfoChains, markrGetPartnerInfo, markrGetTokenList, type ApiOptions } from './_api';\nimport { isEvmAddress } from '../../utils/evm-address';\nimport { isSolAddress } from '../../utils/sol-address';\n\nexport type SupportedChainsMap = Map<\n Caip2ChainId,\n {\n /** `number` for EVM, `Caip2ChainId` for SVM */\n chainId: number | Caip2ChainId;\n crossChainSwapEnabled: boolean;\n crossChainTargetChainIds: ReadonlySet<Caip2ChainId>;\n swapEnabled: boolean;\n tokenList: boolean;\n /**\n * Recurring-swap metadata (passed through from `/info/chains[].recurring`).\n * Present only on EVM chains where Markr enables recurring swaps. Consumed\n * by `recurring/_chain-info.ts` `deriveRecurringChainInfo` (no second\n * `/info/chains` fetch).\n */\n recurring?: {\n minFrequencySeconds: number;\n supportedTokens: ReadonlyArray<{ address: EvmAddress; minimumAmount: string }>;\n };\n }\n>;\n\n/**\n * Checks whether the given source → target chain route is supported by Markr.\n */\nexport function isRouteSupported(\n supportedChains: SupportedChainsMap,\n sourceChainId: Caip2ChainId,\n targetChainId: Caip2ChainId,\n): boolean {\n const sourceChain = supportedChains.get(sourceChainId);\n const targetChain = supportedChains.get(targetChainId);\n\n if (!sourceChain || !targetChain) return false;\n\n if (sourceChainId === targetChainId) {\n return sourceChain.swapEnabled;\n }\n\n return sourceChain.crossChainSwapEnabled && sourceChain.crossChainTargetChainIds.has(targetChainId);\n}\n\nexport async function getSupportedChains(\n apiOptions: ApiOptions,\n disableCrossChainSwaps = false,\n): Promise<SupportedChainsMap> {\n const supportedChains: SupportedChainsMap = new Map();\n\n try {\n const chains = await markrGetInfoChains(apiOptions);\n const filteredSupportedChains = chains.filter(\n (chain): chain is SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm => {\n // Only include chains types that we support in the SDK (EVM and Solana for now).\n return chain.chainType === 'evm' || chain.chainType === 'svm';\n },\n );\n\n for (const chain of filteredSupportedChains) {\n const key: Caip2ChainId = typeof chain.chainId === 'number' ? eip155ChainIdToCaip2(chain.chainId) : chain.chainId;\n\n const isCrossChainSwapEnabled =\n chain.enabled_services.includes('cross-chain-quote') && chain.enabled_services.includes('cross-chain-swap');\n const isSwapEnabled = chain.enabled_services.includes('quote') && chain.enabled_services.includes('swap');\n const normalizedLaneChainIds = new Set<Caip2ChainId>();\n\n for (const lane of chain.lanes) {\n const laneChainId = typeof lane === 'number' ? eip155ChainIdToCaip2(lane) : lane;\n\n if (laneChainId !== key) {\n normalizedLaneChainIds.add(laneChainId);\n }\n }\n\n const crossChainSwapEnabled = disableCrossChainSwaps ? false : isCrossChainSwapEnabled;\n const crossChainTargetChainIds = crossChainSwapEnabled ? normalizedLaneChainIds : new Set<Caip2ChainId>();\n\n if (!isSwapEnabled && crossChainTargetChainIds.size === 0) {\n continue;\n }\n\n const recurring =\n chain.chainType === 'evm' && chain.recurring\n ? {\n minFrequencySeconds: chain.recurring.minFrequencySeconds,\n supportedTokens: chain.recurring.supportedTokens,\n }\n : undefined;\n\n supportedChains.set(key, {\n chainId: chain.chainId,\n crossChainSwapEnabled,\n crossChainTargetChainIds,\n swapEnabled: isSwapEnabled,\n tokenList: chain.enabled_services.includes('token-list'),\n ...(recurring ? { recurring } : {}),\n });\n }\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch supported chains from Markr API.',\n });\n }\n\n return supportedChains;\n}\n\nexport async function getSupportedTokens(\n apiOptions: ApiOptions,\n supportedChains: SupportedChainsMap,\n): Promise<Map<Caip2ChainId, Promise<TokenListResponse>>> {\n // Parallel fetch token lists for all supported chains.\n const supportedTokens: Map<Caip2ChainId, Promise<TokenListResponse>> = new Map();\n\n for (const [caip2ChainId, chainInfo] of supportedChains.entries()) {\n // Only fetch token list for EVM chains that support swaps.\n if (\n typeof chainInfo.chainId === 'number' &&\n chainInfo.tokenList &&\n (chainInfo.crossChainSwapEnabled || chainInfo.swapEnabled)\n ) {\n try {\n const tokenListPromise = markrGetTokenList(apiOptions, chainInfo.chainId);\n supportedTokens.set(caip2ChainId, tokenListPromise);\n } catch {\n // Ignore errors for individual token list fetches.\n // TODO: Logger?\n }\n }\n }\n\n return supportedTokens;\n}\n\n/**\n * Determine if the provided token address represents the native token for its chain.\n *\n * Markr represents EVM native tokens as the zero address and Solana native SOL\n * as the wrapped SOL mint address.\n */\nexport function isTokenAddressNative(address: string): boolean {\n return address === ERC_ZERO_ADDRESS || address === NATIVE_SOL_ADDRESS;\n}\n\n/**\n * Convert an `Asset` to the address string expected by the Markr API.\n *\n * For NATIVE assets the representation depends on the chain:\n * - EVM chains: `0x0000...0000` (ERC zero address)\n * - Solana chains: `So11111111111111111111111111111111111111112` (wrapped SOL mint)\n *\n * @param asset The asset to convert.\n * @param chainId CAIP-2 chain ID used to disambiguate NATIVE assets across chain types.\n */\nexport function assetToAddressString(asset: Asset, chainId: Caip2ChainId): string {\n if (asset.type === TokenType.NATIVE) {\n if (isSolanaNamespace(chainId)) {\n return NATIVE_SOL_ADDRESS;\n }\n\n return ERC_ZERO_ADDRESS;\n }\n\n return asset.address;\n}\n\n/**\n * Markr rejects `minAmountOut=0` for non-zero quotes.\n *\n * For very small quotes, integer truncation after slippage can produce `0`.\n * Clamp to `1` in that edge case to satisfy Markr API validation while\n * preserving normal slippage behavior for larger quotes.\n */\nexport function calculateMarkrMinimumAmountOut({\n amountOut,\n assetOut,\n slippageBps,\n}: Pick<Quote, 'amountOut' | 'assetOut' | 'slippageBps'>): bigint {\n const minAmountOut = calculateMinimumAmountOut({ amountOut, assetOut, slippageBps });\n\n if (amountOut > 0n && minAmountOut === 0n) {\n return 1n;\n }\n\n return minAmountOut;\n}\n\n/**\n * Returns additive fee amount charged in the source asset on the source chain.\n *\n * This is used for allowance/balance checks where users must fund both the\n * transfer input and any additive source-asset fee components. A safety buffer\n * is applied to the additive fee total to reduce the chance of under-approvals.\n *\n * @see https://docs.debridge.com/dln-details/overview/fee-structure#best-practice-checklist-for-integrators\n *\n * @param quote The quote containing the fees to analyze.\n * @param bufferBps Buffer in basis points applied to the additive fee total.\n * Defaults to 3000 bps (30%).\n */\nexport function getAdditiveSourceAssetFeeAmount(\n { assetIn, fees, sourceChain }: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>,\n bufferBps = 3_000,\n): bigint {\n const additiveSourceAssetFeeAmount = fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n if (assetIn.type === TokenType.NATIVE) {\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }\n\n if (assetIn.type === TokenType.ERC20) {\n return fee.token.type === TokenType.ERC20 && isAddressEqual(fee.token.address, assetIn.address)\n ? total + fee.amount\n : total;\n }\n\n return fee.token.type === TokenType.SPL && fee.token.address === assetIn.address ? total + fee.amount : total;\n }, 0n);\n\n return (additiveSourceAssetFeeAmount * BigInt(10_000 + bufferBps)) / 10_000n;\n}\n\n/**\n * Returns additive fee amount charged in native asset on the source chain.\n */\nexport function getAdditiveSourceNativeAssetFeeAmount({\n fees,\n sourceChain,\n}: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>): bigint {\n return fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }, 0n);\n}\n\nexport function quoteFromMarkrQuoteResponseData(\n data: QuoteResponseData,\n quoterProps: QuoterProps,\n partnerFeeBps: number,\n): Quote {\n const partnerFee: bigint = (data.amountOut * BigInt(partnerFeeBps)) / 10_000n;\n const amountOutAfterFees: bigint = data.amountOut - partnerFee;\n\n const fees: QuoteFees = [\n ...mapMarkrQuoteResponseDataFeesToQuoteFees(data.fees),\n // Add the partner fee as a QuoteFee component for Markr quotes.\n {\n type: 'partner',\n fundingModel: 'included',\n name: 'Core Fee',\n amount: partnerFee,\n chainId: quoterProps.targetChain.chainId,\n token: assetToFeeToken(quoterProps.targetAsset),\n },\n ];\n\n return {\n aggregator: {\n id: data.aggregator.id,\n logoUrl: data.aggregator.logo_url,\n name: data.aggregator.name,\n },\n amountIn: data.amountIn,\n amountOut: amountOutAfterFees,\n assetIn: quoterProps.sourceAsset,\n assetOut: quoterProps.targetAsset,\n expiresAt: data.expiredAt, // Markr returns `expiredAt` as Unix time in seconds; use as-is.\n fees,\n fromAddress: quoterProps.fromAddress,\n /**\n * This gasEstimate is rough or may be missing.\n * Consumers should use TransferManager.estimateGas for a more accurate estimate.\n */\n gasEstimate: data.gasEstimate,\n id: data.uuid,\n partnerFeeBps,\n serviceType: ServiceType.MARKR,\n slippageBps: quoterProps.slippageBps ?? data.recommendedSlippage,\n sourceChain: quoterProps.sourceChain,\n targetChain: quoterProps.targetChain,\n toAddress: quoterProps.toAddress,\n } satisfies Quote;\n}\n\nexport async function getPartnerFeeBps(apiOptions: ApiOptions): Promise<number> {\n try {\n const partnerInfo = await markrGetPartnerInfo(apiOptions);\n return partnerInfo.fee;\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch partner info from Markr API.',\n });\n }\n}\n\nexport function mapMarkrQuoteResponseDataFeesToQuoteFees(markrFees: QuoteResponseData['fees']): QuoteFees {\n if (!markrFees) {\n return [];\n }\n\n const fees: QuoteFee[] = [];\n\n for (const fee of markrFees) {\n const chainId = typeof fee.token.chainId === 'number' ? eip155ChainIdToCaip2(fee.token.chainId) : fee.token.chainId;\n\n let token: QuoteFeeToken | undefined;\n\n if (isTokenAddressNative(fee.token.address)) {\n token = { type: TokenType.NATIVE };\n } else if (isEvmAddress(fee.token.address)) {\n token = { type: TokenType.ERC20, address: fee.token.address };\n } else if (isSolAddress(fee.token.address)) {\n token = { type: TokenType.SPL, address: fee.token.address };\n }\n\n if (!token) {\n // Skip fee if we can't determine token type.\n continue;\n }\n\n fees.push({\n type: fee.type,\n fundingModel: fee.extra ? 'additive' : 'included',\n name: fee.name,\n amount: fee.amount,\n chainId,\n token,\n });\n }\n\n return fees;\n}\n\nfunction assetToFeeToken(asset: Asset): QuoteFeeToken {\n if (asset.type === TokenType.NATIVE) {\n return { type: TokenType.NATIVE };\n }\n\n if (asset.type === TokenType.SPL) {\n return { type: TokenType.SPL, address: asset.address };\n }\n\n return { type: TokenType.ERC20, address: asset.address };\n}\n\nexport type MarkrRouterAbi =\n | (typeof import('./_abis/swap-wrapper-abi'))['MARKR_SWAP_WRAPPER_ABI']\n | (typeof import('./_abis/cross-chain-swap-wrapper-abi'))['MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI'];\n\nexport async function getMarkrSwapWrapperAbi(crossChain: boolean): Promise<MarkrRouterAbi> {\n if (crossChain) {\n return (await import('./_abis/cross-chain-swap-wrapper-abi')).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI;\n }\n\n return (await import('./_abis/swap-wrapper-abi')).MARKR_SWAP_WRAPPER_ABI;\n}\n\nfunction extractHexDataFromError(error: unknown): Hex | undefined {\n if (error instanceof BaseError) {\n const directData = (error as { data?: unknown }).data;\n if (isHex(directData)) return directData;\n\n let walkedData: Hex | undefined;\n error.walk((walkedError) => {\n const nestedData = (walkedError as { data?: unknown }).data;\n if (!walkedData && isHex(nestedData)) walkedData = nestedData;\n return false;\n });\n if (walkedData) return walkedData;\n\n const causeData = (error as { cause?: { data?: unknown } }).cause?.data;\n if (isHex(causeData)) return causeData;\n }\n\n if (!error || typeof error !== 'object') return undefined;\n\n const e = error as {\n data?: unknown;\n error?: { data?: unknown };\n cause?: { data?: unknown };\n response?: { data?: unknown };\n body?: { error?: { data?: unknown } };\n };\n\n if (isHex(e.data)) return e.data;\n if (isHex(e.error?.data)) return e.error.data;\n if (isHex(e.cause?.data)) return e.cause.data;\n if (isHex(e.response?.data)) return e.response.data;\n if (isHex(e.body?.error?.data)) return e.body.error.data;\n\n return undefined;\n}\n\nexport function decodeMarkrRevertError(abi: MarkrRouterAbi, error: unknown): string | null {\n const revertData = extractHexDataFromError(error);\n\n if (!revertData) {\n return null;\n }\n\n try {\n const decoded = decodeErrorResult({ abi, data: revertData });\n const decodedArgs = decoded.args.length > 0 ? `(${decoded.args.map(String).join(', ')})` : '()';\n\n return `${decoded.errorName}${decodedArgs}`;\n } catch {\n const selector = revertData.slice(0, 10).toLowerCase();\n\n for (const abiItem of abi) {\n if (abiItem.type !== 'error') {\n continue;\n }\n\n const signature = `${abiItem.name}(${abiItem.inputs.map((input) => input.type).join(',')})`;\n if (toFunctionSelector(signature).toLowerCase() === selector) {\n return `${abiItem.name}()`;\n }\n }\n }\n\n return null;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{ERC_ZERO_ADDRESS as e,NATIVE_SOL_ADDRESS as t,ServiceType as n,TokenType as r}from"../../constants.js";import{ErrorCode as i,ErrorReason as a,SdkError as o}from"../../errors.js";import{eip155ChainIdToCaip2 as s}from"../../utils/caip.js";import{isSolanaNamespace as c}from"../../_utils/chain.js";import{isEvmAddress as l}from"../../utils/evm-address.js";import{calculateMinimumAmountOut as u}from"../../_utils/math.js";import{markrGetInfoChains as d,markrGetPartnerInfo as f,markrGetTokenList as p}from"./_api.js";import{isSolAddress as m}from"../../utils/sol-address.js";import{isAddressEqual as h}from"viem";function g(e,t,n){let r=e.get(t),i=e.get(n);return!r||!i?!1:t===n?r.swapEnabled:r.crossChainSwapEnabled&&r.crossChainTargetChainIds.has(n)}async function _(e,t=!1){let n=new Map;try{let r=(await d(e)).filter(e=>e.chainType===`evm`||e.chainType===`svm`);for(let e of r){let r=typeof e.chainId==`number`?s(e.chainId):e.chainId,i=e.enabled_services.includes(`cross-chain-quote`)&&e.enabled_services.includes(`cross-chain-swap`),a=e.enabled_services.includes(`quote`)&&e.enabled_services.includes(`swap`),o=new Set;for(let t of e.lanes){let e=typeof t==`number`?s(t):t;e!==r&&o.add(e)}let c=t?!1:i,l=c?o:new Set;!a&&l.size===0||n.set(r,{chainId:e.chainId,crossChainSwapEnabled:c,crossChainTargetChainIds:l,swapEnabled:a,tokenList:e.enabled_services.includes(`token-list`)})}}catch(e){throw new o(a.UNKNOWN,i.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch supported chains from Markr API.`})}return n}async function v(e,t){let n=new Map;for(let[r,i]of t.entries())if(typeof i.chainId==`number`&&i.tokenList&&(i.crossChainSwapEnabled||i.swapEnabled))try{let t=p(e,i.chainId);n.set(r,t)}catch{}return n}function y(e){return e===`0x0000000000000000000000000000000000000000`||e===`11111111111111111111111111111111`}function b(n,i){return n.type===r.NATIVE?c(i)?t:e:n.address}function x({amountOut:e,assetOut:t,slippageBps:n}){let r=u({amountOut:e,assetOut:t,slippageBps:n});return e>0n&&r===0n?1n:r}function S({assetIn:e,fees:t,sourceChain:n},i=3e3){return t.reduce((t,i)=>i.fundingModel!==`additive`||i.chainId!==n.chainId?t:e.type===r.NATIVE?i.token.type===r.NATIVE?t+i.amount:t:e.type===r.ERC20?i.token.type===r.ERC20&&h(i.token.address,e.address)?t+i.amount:t:i.token.type===r.SPL&&i.token.address===e.address?t+i.amount:t,0n)*BigInt(1e4+i)/10000n}function C({fees:e,sourceChain:t}){return e.reduce((e,n)=>n.fundingModel!==`additive`||n.chainId!==t.chainId?e:n.token.type===r.NATIVE?e+n.amount:e,0n)}function w(e,t,r){let i=e.amountOut*BigInt(r)/10000n,a=e.amountOut-i,o=[...E(e.fees),{type:`partner`,fundingModel:`included`,name:`Core Fee`,amount:i,chainId:t.targetChain.chainId,token:D(t.targetAsset)}];return{aggregator:{id:e.aggregator.id,logoUrl:e.aggregator.logo_url,name:e.aggregator.name},amountIn:e.amountIn,amountOut:a,assetIn:t.sourceAsset,assetOut:t.targetAsset,expiresAt:e.expiredAt,fees:o,fromAddress:t.fromAddress,gasEstimate:e.gasEstimate,id:e.uuid,partnerFeeBps:r,serviceType:n.MARKR,slippageBps:t.slippageBps??e.recommendedSlippage,sourceChain:t.sourceChain,targetChain:t.targetChain,toAddress:t.toAddress}}async function T(e){try{return(await f(e)).fee}catch(e){throw new o(a.UNKNOWN,i.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch partner info from Markr API.`})}}function E(e){if(!e)return[];let t=[];for(let n of e){let e=typeof n.token.chainId==`number`?s(n.token.chainId):n.token.chainId,i;y(n.token.address)?i={type:r.NATIVE}:l(n.token.address)?i={type:r.ERC20,address:n.token.address}:m(n.token.address)&&(i={type:r.SPL,address:n.token.address}),i&&t.push({type:n.type,fundingModel:n.extra?`additive`:`included`,name:n.name,amount:n.amount,chainId:e,token:i})}return t}function D(e){return e.type===r.NATIVE?{type:r.NATIVE}:e.type===r.SPL?{type:r.SPL,address:e.address}:{type:r.ERC20,address:e.address}}async function O(e){return e?(await import(`./_abis/cross-chain-swap-wrapper-abi.js`)).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI:(await import(`./_abis/swap-wrapper-abi.js`)).MARKR_SWAP_WRAPPER_ABI}export{b as assetToAddressString,x as calculateMarkrMinimumAmountOut,S as getAdditiveSourceAssetFeeAmount,C as getAdditiveSourceNativeAssetFeeAmount,O as getMarkrSwapWrapperAbi,T as getPartnerFeeBps,_ as getSupportedChains,v as getSupportedTokens,g as isRouteSupported,y as isTokenAddressNative,w as quoteFromMarkrQuoteResponseData};
1
+ import{ERC_ZERO_ADDRESS as e,NATIVE_SOL_ADDRESS as t,ServiceType as n,TokenType as r}from"../../constants.js";import{ErrorCode as i,ErrorReason as a,SdkError as o}from"../../errors.js";import{eip155ChainIdToCaip2 as s}from"../../utils/caip.js";import{isSolanaNamespace as c}from"../../_utils/chain.js";import{isEvmAddress as l}from"../../utils/evm-address.js";import{calculateMinimumAmountOut as u}from"../../_utils/math.js";import{markrGetInfoChains as d,markrGetPartnerInfo as f,markrGetTokenList as p}from"./_api.js";import{isSolAddress as m}from"../../utils/sol-address.js";import{isAddressEqual as h}from"viem";function g(e,t,n){let r=e.get(t),i=e.get(n);return!r||!i?!1:t===n?r.swapEnabled:r.crossChainSwapEnabled&&r.crossChainTargetChainIds.has(n)}async function _(e,t=!1){let n=new Map;try{let r=(await d(e)).filter(e=>e.chainType===`evm`||e.chainType===`svm`);for(let e of r){let r=typeof e.chainId==`number`?s(e.chainId):e.chainId,i=e.enabled_services.includes(`cross-chain-quote`)&&e.enabled_services.includes(`cross-chain-swap`),a=e.enabled_services.includes(`quote`)&&e.enabled_services.includes(`swap`),o=new Set;for(let t of e.lanes){let e=typeof t==`number`?s(t):t;e!==r&&o.add(e)}let c=t?!1:i,l=c?o:new Set;if(!a&&l.size===0)continue;let u=e.chainType===`evm`&&e.recurring?{minFrequencySeconds:e.recurring.minFrequencySeconds,supportedTokens:e.recurring.supportedTokens}:void 0;n.set(r,{chainId:e.chainId,crossChainSwapEnabled:c,crossChainTargetChainIds:l,swapEnabled:a,tokenList:e.enabled_services.includes(`token-list`),...u?{recurring:u}:{}})}}catch(e){throw new o(a.UNKNOWN,i.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch supported chains from Markr API.`})}return n}async function v(e,t){let n=new Map;for(let[r,i]of t.entries())if(typeof i.chainId==`number`&&i.tokenList&&(i.crossChainSwapEnabled||i.swapEnabled))try{let t=p(e,i.chainId);n.set(r,t)}catch{}return n}function y(e){return e===`0x0000000000000000000000000000000000000000`||e===`11111111111111111111111111111111`}function b(n,i){return n.type===r.NATIVE?c(i)?t:e:n.address}function x({amountOut:e,assetOut:t,slippageBps:n}){let r=u({amountOut:e,assetOut:t,slippageBps:n});return e>0n&&r===0n?1n:r}function S({assetIn:e,fees:t,sourceChain:n},i=3e3){return t.reduce((t,i)=>i.fundingModel!==`additive`||i.chainId!==n.chainId?t:e.type===r.NATIVE?i.token.type===r.NATIVE?t+i.amount:t:e.type===r.ERC20?i.token.type===r.ERC20&&h(i.token.address,e.address)?t+i.amount:t:i.token.type===r.SPL&&i.token.address===e.address?t+i.amount:t,0n)*BigInt(1e4+i)/10000n}function C({fees:e,sourceChain:t}){return e.reduce((e,n)=>n.fundingModel!==`additive`||n.chainId!==t.chainId?e:n.token.type===r.NATIVE?e+n.amount:e,0n)}function w(e,t,r){let i=e.amountOut*BigInt(r)/10000n,a=e.amountOut-i,o=[...E(e.fees),{type:`partner`,fundingModel:`included`,name:`Core Fee`,amount:i,chainId:t.targetChain.chainId,token:D(t.targetAsset)}];return{aggregator:{id:e.aggregator.id,logoUrl:e.aggregator.logo_url,name:e.aggregator.name},amountIn:e.amountIn,amountOut:a,assetIn:t.sourceAsset,assetOut:t.targetAsset,expiresAt:e.expiredAt,fees:o,fromAddress:t.fromAddress,gasEstimate:e.gasEstimate,id:e.uuid,partnerFeeBps:r,serviceType:n.MARKR,slippageBps:t.slippageBps??e.recommendedSlippage,sourceChain:t.sourceChain,targetChain:t.targetChain,toAddress:t.toAddress}}async function T(e){try{return(await f(e)).fee}catch(e){throw new o(a.UNKNOWN,i.INITIALIZATION_FAILED,{cause:e,details:`Failed to fetch partner info from Markr API.`})}}function E(e){if(!e)return[];let t=[];for(let n of e){let e=typeof n.token.chainId==`number`?s(n.token.chainId):n.token.chainId,i;y(n.token.address)?i={type:r.NATIVE}:l(n.token.address)?i={type:r.ERC20,address:n.token.address}:m(n.token.address)&&(i={type:r.SPL,address:n.token.address}),i&&t.push({type:n.type,fundingModel:n.extra?`additive`:`included`,name:n.name,amount:n.amount,chainId:e,token:i})}return t}function D(e){return e.type===r.NATIVE?{type:r.NATIVE}:e.type===r.SPL?{type:r.SPL,address:e.address}:{type:r.ERC20,address:e.address}}async function O(e){return e?(await import(`./_abis/cross-chain-swap-wrapper-abi.js`)).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI:(await import(`./_abis/swap-wrapper-abi.js`)).MARKR_SWAP_WRAPPER_ABI}export{b as assetToAddressString,x as calculateMarkrMinimumAmountOut,S as getAdditiveSourceAssetFeeAmount,C as getAdditiveSourceNativeAssetFeeAmount,O as getMarkrSwapWrapperAbi,T as getPartnerFeeBps,_ as getSupportedChains,v as getSupportedTokens,g as isRouteSupported,y as isTokenAddressNative,w as quoteFromMarkrQuoteResponseData};
2
2
  //# sourceMappingURL=_utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_utils.js","names":[],"sources":["../../../src/transfer-service/markr/_utils.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../errors';\nimport { BaseError, decodeErrorResult, isAddressEqual, isHex, toFunctionSelector, type Hex } from 'viem';\nimport {\n type QuoteResponseData,\n type SupportedChainsResponseItemEvm,\n type SupportedChainsResponseItemSvm,\n type TokenListResponse,\n} from './_schema';\nimport { ERC_ZERO_ADDRESS, NATIVE_SOL_ADDRESS, ServiceType, TokenType } from '../../constants';\nimport { isSolanaNamespace } from '../../_utils/chain';\nimport { calculateMinimumAmountOut } from '../../_utils/math';\nimport { eip155ChainIdToCaip2 } from '../../utils/caip';\nimport type { Asset } from '../../types/asset';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Quote, QuoteFee, QuoteFees, QuoteFeeToken, QuoterProps } from '../../types/quote';\nimport { markrGetInfoChains, markrGetPartnerInfo, markrGetTokenList, type ApiOptions } from './_api';\nimport { isEvmAddress } from '../../utils/evm-address';\nimport { isSolAddress } from '../../utils/sol-address';\n\nexport type SupportedChainsMap = Map<\n Caip2ChainId,\n {\n /** `number` for EVM, `Caip2ChainId` for SVM */\n chainId: number | Caip2ChainId;\n crossChainSwapEnabled: boolean;\n crossChainTargetChainIds: ReadonlySet<Caip2ChainId>;\n swapEnabled: boolean;\n tokenList: boolean;\n }\n>;\n\n/**\n * Checks whether the given source → target chain route is supported by Markr.\n */\nexport function isRouteSupported(\n supportedChains: SupportedChainsMap,\n sourceChainId: Caip2ChainId,\n targetChainId: Caip2ChainId,\n): boolean {\n const sourceChain = supportedChains.get(sourceChainId);\n const targetChain = supportedChains.get(targetChainId);\n\n if (!sourceChain || !targetChain) return false;\n\n if (sourceChainId === targetChainId) {\n return sourceChain.swapEnabled;\n }\n\n return sourceChain.crossChainSwapEnabled && sourceChain.crossChainTargetChainIds.has(targetChainId);\n}\n\nexport async function getSupportedChains(\n apiOptions: ApiOptions,\n disableCrossChainSwaps = false,\n): Promise<SupportedChainsMap> {\n const supportedChains: SupportedChainsMap = new Map();\n\n try {\n const chains = await markrGetInfoChains(apiOptions);\n const filteredSupportedChains = chains.filter(\n (chain): chain is SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm => {\n // Only include chains types that we support in the SDK (EVM and Solana for now).\n return chain.chainType === 'evm' || chain.chainType === 'svm';\n },\n );\n\n for (const chain of filteredSupportedChains) {\n const key: Caip2ChainId = typeof chain.chainId === 'number' ? eip155ChainIdToCaip2(chain.chainId) : chain.chainId;\n\n const isCrossChainSwapEnabled =\n chain.enabled_services.includes('cross-chain-quote') && chain.enabled_services.includes('cross-chain-swap');\n const isSwapEnabled = chain.enabled_services.includes('quote') && chain.enabled_services.includes('swap');\n const normalizedLaneChainIds = new Set<Caip2ChainId>();\n\n for (const lane of chain.lanes) {\n const laneChainId = typeof lane === 'number' ? eip155ChainIdToCaip2(lane) : lane;\n\n if (laneChainId !== key) {\n normalizedLaneChainIds.add(laneChainId);\n }\n }\n\n const crossChainSwapEnabled = disableCrossChainSwaps ? false : isCrossChainSwapEnabled;\n const crossChainTargetChainIds = crossChainSwapEnabled ? normalizedLaneChainIds : new Set<Caip2ChainId>();\n\n if (!isSwapEnabled && crossChainTargetChainIds.size === 0) {\n continue;\n }\n\n supportedChains.set(key, {\n chainId: chain.chainId,\n crossChainSwapEnabled,\n crossChainTargetChainIds,\n swapEnabled: isSwapEnabled,\n tokenList: chain.enabled_services.includes('token-list'),\n });\n }\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch supported chains from Markr API.',\n });\n }\n\n return supportedChains;\n}\n\nexport async function getSupportedTokens(\n apiOptions: ApiOptions,\n supportedChains: SupportedChainsMap,\n): Promise<Map<Caip2ChainId, Promise<TokenListResponse>>> {\n // Parallel fetch token lists for all supported chains.\n const supportedTokens: Map<Caip2ChainId, Promise<TokenListResponse>> = new Map();\n\n for (const [caip2ChainId, chainInfo] of supportedChains.entries()) {\n // Only fetch token list for EVM chains that support swaps.\n if (\n typeof chainInfo.chainId === 'number' &&\n chainInfo.tokenList &&\n (chainInfo.crossChainSwapEnabled || chainInfo.swapEnabled)\n ) {\n try {\n const tokenListPromise = markrGetTokenList(apiOptions, chainInfo.chainId);\n supportedTokens.set(caip2ChainId, tokenListPromise);\n } catch {\n // Ignore errors for individual token list fetches.\n // TODO: Logger?\n }\n }\n }\n\n return supportedTokens;\n}\n\n/**\n * Determine if the provided token address represents the native token for its chain.\n *\n * Markr represents EVM native tokens as the zero address and Solana native SOL\n * as the wrapped SOL mint address.\n */\nexport function isTokenAddressNative(address: string): boolean {\n return address === ERC_ZERO_ADDRESS || address === NATIVE_SOL_ADDRESS;\n}\n\n/**\n * Convert an `Asset` to the address string expected by the Markr API.\n *\n * For NATIVE assets the representation depends on the chain:\n * - EVM chains: `0x0000...0000` (ERC zero address)\n * - Solana chains: `So11111111111111111111111111111111111111112` (wrapped SOL mint)\n *\n * @param asset The asset to convert.\n * @param chainId CAIP-2 chain ID used to disambiguate NATIVE assets across chain types.\n */\nexport function assetToAddressString(asset: Asset, chainId: Caip2ChainId): string {\n if (asset.type === TokenType.NATIVE) {\n if (isSolanaNamespace(chainId)) {\n return NATIVE_SOL_ADDRESS;\n }\n\n return ERC_ZERO_ADDRESS;\n }\n\n return asset.address;\n}\n\n/**\n * Markr rejects `minAmountOut=0` for non-zero quotes.\n *\n * For very small quotes, integer truncation after slippage can produce `0`.\n * Clamp to `1` in that edge case to satisfy Markr API validation while\n * preserving normal slippage behavior for larger quotes.\n */\nexport function calculateMarkrMinimumAmountOut({\n amountOut,\n assetOut,\n slippageBps,\n}: Pick<Quote, 'amountOut' | 'assetOut' | 'slippageBps'>): bigint {\n const minAmountOut = calculateMinimumAmountOut({ amountOut, assetOut, slippageBps });\n\n if (amountOut > 0n && minAmountOut === 0n) {\n return 1n;\n }\n\n return minAmountOut;\n}\n\n/**\n * Returns additive fee amount charged in the source asset on the source chain.\n *\n * This is used for allowance/balance checks where users must fund both the\n * transfer input and any additive source-asset fee components. A safety buffer\n * is applied to the additive fee total to reduce the chance of under-approvals.\n *\n * @see https://docs.debridge.com/dln-details/overview/fee-structure#best-practice-checklist-for-integrators\n *\n * @param quote The quote containing the fees to analyze.\n * @param bufferBps Buffer in basis points applied to the additive fee total.\n * Defaults to 3000 bps (30%).\n */\nexport function getAdditiveSourceAssetFeeAmount(\n { assetIn, fees, sourceChain }: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>,\n bufferBps = 3_000,\n): bigint {\n const additiveSourceAssetFeeAmount = fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n if (assetIn.type === TokenType.NATIVE) {\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }\n\n if (assetIn.type === TokenType.ERC20) {\n return fee.token.type === TokenType.ERC20 && isAddressEqual(fee.token.address, assetIn.address)\n ? total + fee.amount\n : total;\n }\n\n return fee.token.type === TokenType.SPL && fee.token.address === assetIn.address ? total + fee.amount : total;\n }, 0n);\n\n return (additiveSourceAssetFeeAmount * BigInt(10_000 + bufferBps)) / 10_000n;\n}\n\n/**\n * Returns additive fee amount charged in native asset on the source chain.\n */\nexport function getAdditiveSourceNativeAssetFeeAmount({\n fees,\n sourceChain,\n}: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>): bigint {\n return fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }, 0n);\n}\n\nexport function quoteFromMarkrQuoteResponseData(\n data: QuoteResponseData,\n quoterProps: QuoterProps,\n partnerFeeBps: number,\n): Quote {\n const partnerFee: bigint = (data.amountOut * BigInt(partnerFeeBps)) / 10_000n;\n const amountOutAfterFees: bigint = data.amountOut - partnerFee;\n\n const fees: QuoteFees = [\n ...mapMarkrQuoteResponseDataFeesToQuoteFees(data.fees),\n // Add the partner fee as a QuoteFee component for Markr quotes.\n {\n type: 'partner',\n fundingModel: 'included',\n name: 'Core Fee',\n amount: partnerFee,\n chainId: quoterProps.targetChain.chainId,\n token: assetToFeeToken(quoterProps.targetAsset),\n },\n ];\n\n return {\n aggregator: {\n id: data.aggregator.id,\n logoUrl: data.aggregator.logo_url,\n name: data.aggregator.name,\n },\n amountIn: data.amountIn,\n amountOut: amountOutAfterFees,\n assetIn: quoterProps.sourceAsset,\n assetOut: quoterProps.targetAsset,\n expiresAt: data.expiredAt, // Markr returns `expiredAt` as Unix time in seconds; use as-is.\n fees,\n fromAddress: quoterProps.fromAddress,\n /**\n * This gasEstimate is rough or may be missing.\n * Consumers should use TransferManager.estimateGas for a more accurate estimate.\n */\n gasEstimate: data.gasEstimate,\n id: data.uuid,\n partnerFeeBps,\n serviceType: ServiceType.MARKR,\n slippageBps: quoterProps.slippageBps ?? data.recommendedSlippage,\n sourceChain: quoterProps.sourceChain,\n targetChain: quoterProps.targetChain,\n toAddress: quoterProps.toAddress,\n } satisfies Quote;\n}\n\nexport async function getPartnerFeeBps(apiOptions: ApiOptions): Promise<number> {\n try {\n const partnerInfo = await markrGetPartnerInfo(apiOptions);\n return partnerInfo.fee;\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch partner info from Markr API.',\n });\n }\n}\n\nexport function mapMarkrQuoteResponseDataFeesToQuoteFees(markrFees: QuoteResponseData['fees']): QuoteFees {\n if (!markrFees) {\n return [];\n }\n\n const fees: QuoteFee[] = [];\n\n for (const fee of markrFees) {\n const chainId = typeof fee.token.chainId === 'number' ? eip155ChainIdToCaip2(fee.token.chainId) : fee.token.chainId;\n\n let token: QuoteFeeToken | undefined;\n\n if (isTokenAddressNative(fee.token.address)) {\n token = { type: TokenType.NATIVE };\n } else if (isEvmAddress(fee.token.address)) {\n token = { type: TokenType.ERC20, address: fee.token.address };\n } else if (isSolAddress(fee.token.address)) {\n token = { type: TokenType.SPL, address: fee.token.address };\n }\n\n if (!token) {\n // Skip fee if we can't determine token type.\n continue;\n }\n\n fees.push({\n type: fee.type,\n fundingModel: fee.extra ? 'additive' : 'included',\n name: fee.name,\n amount: fee.amount,\n chainId,\n token,\n });\n }\n\n return fees;\n}\n\nfunction assetToFeeToken(asset: Asset): QuoteFeeToken {\n if (asset.type === TokenType.NATIVE) {\n return { type: TokenType.NATIVE };\n }\n\n if (asset.type === TokenType.SPL) {\n return { type: TokenType.SPL, address: asset.address };\n }\n\n return { type: TokenType.ERC20, address: asset.address };\n}\n\nexport type MarkrRouterAbi =\n | (typeof import('./_abis/swap-wrapper-abi'))['MARKR_SWAP_WRAPPER_ABI']\n | (typeof import('./_abis/cross-chain-swap-wrapper-abi'))['MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI'];\n\nexport async function getMarkrSwapWrapperAbi(crossChain: boolean): Promise<MarkrRouterAbi> {\n if (crossChain) {\n return (await import('./_abis/cross-chain-swap-wrapper-abi')).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI;\n }\n\n return (await import('./_abis/swap-wrapper-abi')).MARKR_SWAP_WRAPPER_ABI;\n}\n\nfunction extractHexDataFromError(error: unknown): Hex | undefined {\n if (error instanceof BaseError) {\n const directData = (error as { data?: unknown }).data;\n if (isHex(directData)) return directData;\n\n let walkedData: Hex | undefined;\n error.walk((walkedError) => {\n const nestedData = (walkedError as { data?: unknown }).data;\n if (!walkedData && isHex(nestedData)) walkedData = nestedData;\n return false;\n });\n if (walkedData) return walkedData;\n\n const causeData = (error as { cause?: { data?: unknown } }).cause?.data;\n if (isHex(causeData)) return causeData;\n }\n\n if (!error || typeof error !== 'object') return undefined;\n\n const e = error as {\n data?: unknown;\n error?: { data?: unknown };\n cause?: { data?: unknown };\n response?: { data?: unknown };\n body?: { error?: { data?: unknown } };\n };\n\n if (isHex(e.data)) return e.data;\n if (isHex(e.error?.data)) return e.error.data;\n if (isHex(e.cause?.data)) return e.cause.data;\n if (isHex(e.response?.data)) return e.response.data;\n if (isHex(e.body?.error?.data)) return e.body.error.data;\n\n return undefined;\n}\n\nexport function decodeMarkrRevertError(abi: MarkrRouterAbi, error: unknown): string | null {\n const revertData = extractHexDataFromError(error);\n\n if (!revertData) {\n return null;\n }\n\n try {\n const decoded = decodeErrorResult({ abi, data: revertData });\n const decodedArgs = decoded.args.length > 0 ? `(${decoded.args.map(String).join(', ')})` : '()';\n\n return `${decoded.errorName}${decodedArgs}`;\n } catch {\n const selector = revertData.slice(0, 10).toLowerCase();\n\n for (const abiItem of abi) {\n if (abiItem.type !== 'error') {\n continue;\n }\n\n const signature = `${abiItem.name}(${abiItem.inputs.map((input) => input.type).join(',')})`;\n if (toFunctionSelector(signature).toLowerCase() === selector) {\n return `${abiItem.name}()`;\n }\n }\n }\n\n return null;\n}\n"],"mappings":"wmBAkCA,SAAgB,EACd,EACA,EACA,EACS,CACT,IAAM,EAAc,EAAgB,IAAI,EAAc,CAChD,EAAc,EAAgB,IAAI,EAAc,CAQtD,MANI,CAAC,GAAe,CAAC,EAAoB,GAErC,IAAkB,EACb,EAAY,YAGd,EAAY,uBAAyB,EAAY,yBAAyB,IAAI,EAAc,CAGrG,eAAsB,EACpB,EACA,EAAyB,GACI,CAC7B,IAAM,EAAsC,IAAI,IAEhD,GAAI,CAEF,IAAM,GADS,MAAM,EAAmB,EAAW,EACZ,OACpC,GAEQ,EAAM,YAAc,OAAS,EAAM,YAAc,MAE3D,CAED,IAAK,IAAM,KAAS,EAAyB,CAC3C,IAAM,EAAoB,OAAO,EAAM,SAAY,SAAW,EAAqB,EAAM,QAAQ,CAAG,EAAM,QAEpG,EACJ,EAAM,iBAAiB,SAAS,oBAAoB,EAAI,EAAM,iBAAiB,SAAS,mBAAmB,CACvG,EAAgB,EAAM,iBAAiB,SAAS,QAAQ,EAAI,EAAM,iBAAiB,SAAS,OAAO,CACnG,EAAyB,IAAI,IAEnC,IAAK,IAAM,KAAQ,EAAM,MAAO,CAC9B,IAAM,EAAc,OAAO,GAAS,SAAW,EAAqB,EAAK,CAAG,EAExE,IAAgB,GAClB,EAAuB,IAAI,EAAY,CAI3C,IAAM,EAAwB,EAAyB,GAAQ,EACzD,EAA2B,EAAwB,EAAyB,IAAI,IAElF,CAAC,GAAiB,EAAyB,OAAS,GAIxD,EAAgB,IAAI,EAAK,CACvB,QAAS,EAAM,QACf,wBACA,2BACA,YAAa,EACb,UAAW,EAAM,iBAAiB,SAAS,aAAa,CACzD,CAAC,QAEG,EAAO,CACd,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,sBAAuB,CACvE,MAAO,EACP,QAAS,mDACV,CAAC,CAGJ,OAAO,EAGT,eAAsB,EACpB,EACA,EACwD,CAExD,IAAM,EAAiE,IAAI,IAE3E,IAAK,GAAM,CAAC,EAAc,KAAc,EAAgB,SAAS,CAE/D,GACE,OAAO,EAAU,SAAY,UAC7B,EAAU,YACT,EAAU,uBAAyB,EAAU,aAE9C,GAAI,CACF,IAAM,EAAmB,EAAkB,EAAY,EAAU,QAAQ,CACzE,EAAgB,IAAI,EAAc,EAAiB,MAC7C,EAOZ,OAAO,EAST,SAAgB,EAAqB,EAA0B,CAC7D,OAAO,IAAA,8CAAgC,IAAA,mCAazC,SAAgB,EAAqB,EAAc,EAA+B,CAShF,OARI,EAAM,OAAS,EAAU,OACvB,EAAkB,EAAQ,CACrB,EAGF,EAGF,EAAM,QAUf,SAAgB,EAA+B,CAC7C,YACA,WACA,eACgE,CAChE,IAAM,EAAe,EAA0B,CAAE,YAAW,WAAU,cAAa,CAAC,CAMpF,OAJI,EAAY,IAAM,IAAiB,GAC9B,GAGF,EAgBT,SAAgB,EACd,CAAE,UAAS,OAAM,eACjB,EAAY,IACJ,CAmBR,OAlBqC,EAAK,QAAQ,EAAO,IACnD,EAAI,eAAiB,YAAc,EAAI,UAAY,EAAY,QAC1D,EAGL,EAAQ,OAAS,EAAU,OACtB,EAAI,MAAM,OAAS,EAAU,OAAS,EAAQ,EAAI,OAAS,EAGhE,EAAQ,OAAS,EAAU,MACtB,EAAI,MAAM,OAAS,EAAU,OAAS,EAAe,EAAI,MAAM,QAAS,EAAQ,QAAQ,CAC3F,EAAQ,EAAI,OACZ,EAGC,EAAI,MAAM,OAAS,EAAU,KAAO,EAAI,MAAM,UAAY,EAAQ,QAAU,EAAQ,EAAI,OAAS,EACvG,GAAG,CAEiC,OAAO,IAAS,EAAU,CAAI,OAMvE,SAAgB,EAAsC,CACpD,OACA,eAC0D,CAC1D,OAAO,EAAK,QAAQ,EAAO,IACrB,EAAI,eAAiB,YAAc,EAAI,UAAY,EAAY,QAC1D,EAGF,EAAI,MAAM,OAAS,EAAU,OAAS,EAAQ,EAAI,OAAS,EACjE,GAAG,CAGR,SAAgB,EACd,EACA,EACA,EACO,CACP,IAAM,EAAsB,EAAK,UAAY,OAAO,EAAc,CAAI,OAChE,EAA6B,EAAK,UAAY,EAE9C,EAAkB,CACtB,GAAG,EAAyC,EAAK,KAAK,CAEtD,CACE,KAAM,UACN,aAAc,WACd,KAAM,WACN,OAAQ,EACR,QAAS,EAAY,YAAY,QACjC,MAAO,EAAgB,EAAY,YAAY,CAChD,CACF,CAED,MAAO,CACL,WAAY,CACV,GAAI,EAAK,WAAW,GACpB,QAAS,EAAK,WAAW,SACzB,KAAM,EAAK,WAAW,KACvB,CACD,SAAU,EAAK,SACf,UAAW,EACX,QAAS,EAAY,YACrB,SAAU,EAAY,YACtB,UAAW,EAAK,UAChB,OACA,YAAa,EAAY,YAKzB,YAAa,EAAK,YAClB,GAAI,EAAK,KACT,gBACA,YAAa,EAAY,MACzB,YAAa,EAAY,aAAe,EAAK,oBAC7C,YAAa,EAAY,YACzB,YAAa,EAAY,YACzB,UAAW,EAAY,UACxB,CAGH,eAAsB,EAAiB,EAAyC,CAC9E,GAAI,CAEF,OADoB,MAAM,EAAoB,EAAW,EACtC,UACZ,EAAO,CACd,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,sBAAuB,CACvE,MAAO,EACP,QAAS,+CACV,CAAC,EAIN,SAAgB,EAAyC,EAAiD,CACxG,GAAI,CAAC,EACH,MAAO,EAAE,CAGX,IAAM,EAAmB,EAAE,CAE3B,IAAK,IAAM,KAAO,EAAW,CAC3B,IAAM,EAAU,OAAO,EAAI,MAAM,SAAY,SAAW,EAAqB,EAAI,MAAM,QAAQ,CAAG,EAAI,MAAM,QAExG,EAEA,EAAqB,EAAI,MAAM,QAAQ,CACzC,EAAQ,CAAE,KAAM,EAAU,OAAQ,CACzB,EAAa,EAAI,MAAM,QAAQ,CACxC,EAAQ,CAAE,KAAM,EAAU,MAAO,QAAS,EAAI,MAAM,QAAS,CACpD,EAAa,EAAI,MAAM,QAAQ,GACxC,EAAQ,CAAE,KAAM,EAAU,IAAK,QAAS,EAAI,MAAM,QAAS,EAGxD,GAKL,EAAK,KAAK,CACR,KAAM,EAAI,KACV,aAAc,EAAI,MAAQ,WAAa,WACvC,KAAM,EAAI,KACV,OAAQ,EAAI,OACZ,UACA,QACD,CAAC,CAGJ,OAAO,EAGT,SAAS,EAAgB,EAA6B,CASpD,OARI,EAAM,OAAS,EAAU,OACpB,CAAE,KAAM,EAAU,OAAQ,CAG/B,EAAM,OAAS,EAAU,IACpB,CAAE,KAAM,EAAU,IAAK,QAAS,EAAM,QAAS,CAGjD,CAAE,KAAM,EAAU,MAAO,QAAS,EAAM,QAAS,CAO1D,eAAsB,EAAuB,EAA8C,CAKzF,OAJI,GACM,MAAM,OAAO,4CAAyC,oCAGxD,MAAM,OAAO,gCAA6B"}
1
+ {"version":3,"file":"_utils.js","names":[],"sources":["../../../src/transfer-service/markr/_utils.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../errors';\nimport {\n BaseError,\n decodeErrorResult,\n isAddressEqual,\n isHex,\n toFunctionSelector,\n type Address as EvmAddress,\n type Hex,\n} from 'viem';\nimport {\n type QuoteResponseData,\n type SupportedChainsResponseItemEvm,\n type SupportedChainsResponseItemSvm,\n type TokenListResponse,\n} from './_schema';\nimport { ERC_ZERO_ADDRESS, NATIVE_SOL_ADDRESS, ServiceType, TokenType } from '../../constants';\nimport { isSolanaNamespace } from '../../_utils/chain';\nimport { calculateMinimumAmountOut } from '../../_utils/math';\nimport { eip155ChainIdToCaip2 } from '../../utils/caip';\nimport type { Asset } from '../../types/asset';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Quote, QuoteFee, QuoteFees, QuoteFeeToken, QuoterProps } from '../../types/quote';\nimport { markrGetInfoChains, markrGetPartnerInfo, markrGetTokenList, type ApiOptions } from './_api';\nimport { isEvmAddress } from '../../utils/evm-address';\nimport { isSolAddress } from '../../utils/sol-address';\n\nexport type SupportedChainsMap = Map<\n Caip2ChainId,\n {\n /** `number` for EVM, `Caip2ChainId` for SVM */\n chainId: number | Caip2ChainId;\n crossChainSwapEnabled: boolean;\n crossChainTargetChainIds: ReadonlySet<Caip2ChainId>;\n swapEnabled: boolean;\n tokenList: boolean;\n /**\n * Recurring-swap metadata (passed through from `/info/chains[].recurring`).\n * Present only on EVM chains where Markr enables recurring swaps. Consumed\n * by `recurring/_chain-info.ts` `deriveRecurringChainInfo` (no second\n * `/info/chains` fetch).\n */\n recurring?: {\n minFrequencySeconds: number;\n supportedTokens: ReadonlyArray<{ address: EvmAddress; minimumAmount: string }>;\n };\n }\n>;\n\n/**\n * Checks whether the given source → target chain route is supported by Markr.\n */\nexport function isRouteSupported(\n supportedChains: SupportedChainsMap,\n sourceChainId: Caip2ChainId,\n targetChainId: Caip2ChainId,\n): boolean {\n const sourceChain = supportedChains.get(sourceChainId);\n const targetChain = supportedChains.get(targetChainId);\n\n if (!sourceChain || !targetChain) return false;\n\n if (sourceChainId === targetChainId) {\n return sourceChain.swapEnabled;\n }\n\n return sourceChain.crossChainSwapEnabled && sourceChain.crossChainTargetChainIds.has(targetChainId);\n}\n\nexport async function getSupportedChains(\n apiOptions: ApiOptions,\n disableCrossChainSwaps = false,\n): Promise<SupportedChainsMap> {\n const supportedChains: SupportedChainsMap = new Map();\n\n try {\n const chains = await markrGetInfoChains(apiOptions);\n const filteredSupportedChains = chains.filter(\n (chain): chain is SupportedChainsResponseItemEvm | SupportedChainsResponseItemSvm => {\n // Only include chains types that we support in the SDK (EVM and Solana for now).\n return chain.chainType === 'evm' || chain.chainType === 'svm';\n },\n );\n\n for (const chain of filteredSupportedChains) {\n const key: Caip2ChainId = typeof chain.chainId === 'number' ? eip155ChainIdToCaip2(chain.chainId) : chain.chainId;\n\n const isCrossChainSwapEnabled =\n chain.enabled_services.includes('cross-chain-quote') && chain.enabled_services.includes('cross-chain-swap');\n const isSwapEnabled = chain.enabled_services.includes('quote') && chain.enabled_services.includes('swap');\n const normalizedLaneChainIds = new Set<Caip2ChainId>();\n\n for (const lane of chain.lanes) {\n const laneChainId = typeof lane === 'number' ? eip155ChainIdToCaip2(lane) : lane;\n\n if (laneChainId !== key) {\n normalizedLaneChainIds.add(laneChainId);\n }\n }\n\n const crossChainSwapEnabled = disableCrossChainSwaps ? false : isCrossChainSwapEnabled;\n const crossChainTargetChainIds = crossChainSwapEnabled ? normalizedLaneChainIds : new Set<Caip2ChainId>();\n\n if (!isSwapEnabled && crossChainTargetChainIds.size === 0) {\n continue;\n }\n\n const recurring =\n chain.chainType === 'evm' && chain.recurring\n ? {\n minFrequencySeconds: chain.recurring.minFrequencySeconds,\n supportedTokens: chain.recurring.supportedTokens,\n }\n : undefined;\n\n supportedChains.set(key, {\n chainId: chain.chainId,\n crossChainSwapEnabled,\n crossChainTargetChainIds,\n swapEnabled: isSwapEnabled,\n tokenList: chain.enabled_services.includes('token-list'),\n ...(recurring ? { recurring } : {}),\n });\n }\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch supported chains from Markr API.',\n });\n }\n\n return supportedChains;\n}\n\nexport async function getSupportedTokens(\n apiOptions: ApiOptions,\n supportedChains: SupportedChainsMap,\n): Promise<Map<Caip2ChainId, Promise<TokenListResponse>>> {\n // Parallel fetch token lists for all supported chains.\n const supportedTokens: Map<Caip2ChainId, Promise<TokenListResponse>> = new Map();\n\n for (const [caip2ChainId, chainInfo] of supportedChains.entries()) {\n // Only fetch token list for EVM chains that support swaps.\n if (\n typeof chainInfo.chainId === 'number' &&\n chainInfo.tokenList &&\n (chainInfo.crossChainSwapEnabled || chainInfo.swapEnabled)\n ) {\n try {\n const tokenListPromise = markrGetTokenList(apiOptions, chainInfo.chainId);\n supportedTokens.set(caip2ChainId, tokenListPromise);\n } catch {\n // Ignore errors for individual token list fetches.\n // TODO: Logger?\n }\n }\n }\n\n return supportedTokens;\n}\n\n/**\n * Determine if the provided token address represents the native token for its chain.\n *\n * Markr represents EVM native tokens as the zero address and Solana native SOL\n * as the wrapped SOL mint address.\n */\nexport function isTokenAddressNative(address: string): boolean {\n return address === ERC_ZERO_ADDRESS || address === NATIVE_SOL_ADDRESS;\n}\n\n/**\n * Convert an `Asset` to the address string expected by the Markr API.\n *\n * For NATIVE assets the representation depends on the chain:\n * - EVM chains: `0x0000...0000` (ERC zero address)\n * - Solana chains: `So11111111111111111111111111111111111111112` (wrapped SOL mint)\n *\n * @param asset The asset to convert.\n * @param chainId CAIP-2 chain ID used to disambiguate NATIVE assets across chain types.\n */\nexport function assetToAddressString(asset: Asset, chainId: Caip2ChainId): string {\n if (asset.type === TokenType.NATIVE) {\n if (isSolanaNamespace(chainId)) {\n return NATIVE_SOL_ADDRESS;\n }\n\n return ERC_ZERO_ADDRESS;\n }\n\n return asset.address;\n}\n\n/**\n * Markr rejects `minAmountOut=0` for non-zero quotes.\n *\n * For very small quotes, integer truncation after slippage can produce `0`.\n * Clamp to `1` in that edge case to satisfy Markr API validation while\n * preserving normal slippage behavior for larger quotes.\n */\nexport function calculateMarkrMinimumAmountOut({\n amountOut,\n assetOut,\n slippageBps,\n}: Pick<Quote, 'amountOut' | 'assetOut' | 'slippageBps'>): bigint {\n const minAmountOut = calculateMinimumAmountOut({ amountOut, assetOut, slippageBps });\n\n if (amountOut > 0n && minAmountOut === 0n) {\n return 1n;\n }\n\n return minAmountOut;\n}\n\n/**\n * Returns additive fee amount charged in the source asset on the source chain.\n *\n * This is used for allowance/balance checks where users must fund both the\n * transfer input and any additive source-asset fee components. A safety buffer\n * is applied to the additive fee total to reduce the chance of under-approvals.\n *\n * @see https://docs.debridge.com/dln-details/overview/fee-structure#best-practice-checklist-for-integrators\n *\n * @param quote The quote containing the fees to analyze.\n * @param bufferBps Buffer in basis points applied to the additive fee total.\n * Defaults to 3000 bps (30%).\n */\nexport function getAdditiveSourceAssetFeeAmount(\n { assetIn, fees, sourceChain }: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>,\n bufferBps = 3_000,\n): bigint {\n const additiveSourceAssetFeeAmount = fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n if (assetIn.type === TokenType.NATIVE) {\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }\n\n if (assetIn.type === TokenType.ERC20) {\n return fee.token.type === TokenType.ERC20 && isAddressEqual(fee.token.address, assetIn.address)\n ? total + fee.amount\n : total;\n }\n\n return fee.token.type === TokenType.SPL && fee.token.address === assetIn.address ? total + fee.amount : total;\n }, 0n);\n\n return (additiveSourceAssetFeeAmount * BigInt(10_000 + bufferBps)) / 10_000n;\n}\n\n/**\n * Returns additive fee amount charged in native asset on the source chain.\n */\nexport function getAdditiveSourceNativeAssetFeeAmount({\n fees,\n sourceChain,\n}: Pick<Quote, 'assetIn' | 'fees' | 'sourceChain'>): bigint {\n return fees.reduce((total, fee) => {\n if (fee.fundingModel !== 'additive' || fee.chainId !== sourceChain.chainId) {\n return total;\n }\n\n return fee.token.type === TokenType.NATIVE ? total + fee.amount : total;\n }, 0n);\n}\n\nexport function quoteFromMarkrQuoteResponseData(\n data: QuoteResponseData,\n quoterProps: QuoterProps,\n partnerFeeBps: number,\n): Quote {\n const partnerFee: bigint = (data.amountOut * BigInt(partnerFeeBps)) / 10_000n;\n const amountOutAfterFees: bigint = data.amountOut - partnerFee;\n\n const fees: QuoteFees = [\n ...mapMarkrQuoteResponseDataFeesToQuoteFees(data.fees),\n // Add the partner fee as a QuoteFee component for Markr quotes.\n {\n type: 'partner',\n fundingModel: 'included',\n name: 'Core Fee',\n amount: partnerFee,\n chainId: quoterProps.targetChain.chainId,\n token: assetToFeeToken(quoterProps.targetAsset),\n },\n ];\n\n return {\n aggregator: {\n id: data.aggregator.id,\n logoUrl: data.aggregator.logo_url,\n name: data.aggregator.name,\n },\n amountIn: data.amountIn,\n amountOut: amountOutAfterFees,\n assetIn: quoterProps.sourceAsset,\n assetOut: quoterProps.targetAsset,\n expiresAt: data.expiredAt, // Markr returns `expiredAt` as Unix time in seconds; use as-is.\n fees,\n fromAddress: quoterProps.fromAddress,\n /**\n * This gasEstimate is rough or may be missing.\n * Consumers should use TransferManager.estimateGas for a more accurate estimate.\n */\n gasEstimate: data.gasEstimate,\n id: data.uuid,\n partnerFeeBps,\n serviceType: ServiceType.MARKR,\n slippageBps: quoterProps.slippageBps ?? data.recommendedSlippage,\n sourceChain: quoterProps.sourceChain,\n targetChain: quoterProps.targetChain,\n toAddress: quoterProps.toAddress,\n } satisfies Quote;\n}\n\nexport async function getPartnerFeeBps(apiOptions: ApiOptions): Promise<number> {\n try {\n const partnerInfo = await markrGetPartnerInfo(apiOptions);\n return partnerInfo.fee;\n } catch (error) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INITIALIZATION_FAILED, {\n cause: error,\n details: 'Failed to fetch partner info from Markr API.',\n });\n }\n}\n\nexport function mapMarkrQuoteResponseDataFeesToQuoteFees(markrFees: QuoteResponseData['fees']): QuoteFees {\n if (!markrFees) {\n return [];\n }\n\n const fees: QuoteFee[] = [];\n\n for (const fee of markrFees) {\n const chainId = typeof fee.token.chainId === 'number' ? eip155ChainIdToCaip2(fee.token.chainId) : fee.token.chainId;\n\n let token: QuoteFeeToken | undefined;\n\n if (isTokenAddressNative(fee.token.address)) {\n token = { type: TokenType.NATIVE };\n } else if (isEvmAddress(fee.token.address)) {\n token = { type: TokenType.ERC20, address: fee.token.address };\n } else if (isSolAddress(fee.token.address)) {\n token = { type: TokenType.SPL, address: fee.token.address };\n }\n\n if (!token) {\n // Skip fee if we can't determine token type.\n continue;\n }\n\n fees.push({\n type: fee.type,\n fundingModel: fee.extra ? 'additive' : 'included',\n name: fee.name,\n amount: fee.amount,\n chainId,\n token,\n });\n }\n\n return fees;\n}\n\nfunction assetToFeeToken(asset: Asset): QuoteFeeToken {\n if (asset.type === TokenType.NATIVE) {\n return { type: TokenType.NATIVE };\n }\n\n if (asset.type === TokenType.SPL) {\n return { type: TokenType.SPL, address: asset.address };\n }\n\n return { type: TokenType.ERC20, address: asset.address };\n}\n\nexport type MarkrRouterAbi =\n | (typeof import('./_abis/swap-wrapper-abi'))['MARKR_SWAP_WRAPPER_ABI']\n | (typeof import('./_abis/cross-chain-swap-wrapper-abi'))['MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI'];\n\nexport async function getMarkrSwapWrapperAbi(crossChain: boolean): Promise<MarkrRouterAbi> {\n if (crossChain) {\n return (await import('./_abis/cross-chain-swap-wrapper-abi')).MARKR_CROSS_CHAIN_SWAP_WRAPPER_ABI;\n }\n\n return (await import('./_abis/swap-wrapper-abi')).MARKR_SWAP_WRAPPER_ABI;\n}\n\nfunction extractHexDataFromError(error: unknown): Hex | undefined {\n if (error instanceof BaseError) {\n const directData = (error as { data?: unknown }).data;\n if (isHex(directData)) return directData;\n\n let walkedData: Hex | undefined;\n error.walk((walkedError) => {\n const nestedData = (walkedError as { data?: unknown }).data;\n if (!walkedData && isHex(nestedData)) walkedData = nestedData;\n return false;\n });\n if (walkedData) return walkedData;\n\n const causeData = (error as { cause?: { data?: unknown } }).cause?.data;\n if (isHex(causeData)) return causeData;\n }\n\n if (!error || typeof error !== 'object') return undefined;\n\n const e = error as {\n data?: unknown;\n error?: { data?: unknown };\n cause?: { data?: unknown };\n response?: { data?: unknown };\n body?: { error?: { data?: unknown } };\n };\n\n if (isHex(e.data)) return e.data;\n if (isHex(e.error?.data)) return e.error.data;\n if (isHex(e.cause?.data)) return e.cause.data;\n if (isHex(e.response?.data)) return e.response.data;\n if (isHex(e.body?.error?.data)) return e.body.error.data;\n\n return undefined;\n}\n\nexport function decodeMarkrRevertError(abi: MarkrRouterAbi, error: unknown): string | null {\n const revertData = extractHexDataFromError(error);\n\n if (!revertData) {\n return null;\n }\n\n try {\n const decoded = decodeErrorResult({ abi, data: revertData });\n const decodedArgs = decoded.args.length > 0 ? `(${decoded.args.map(String).join(', ')})` : '()';\n\n return `${decoded.errorName}${decodedArgs}`;\n } catch {\n const selector = revertData.slice(0, 10).toLowerCase();\n\n for (const abiItem of abi) {\n if (abiItem.type !== 'error') {\n continue;\n }\n\n const signature = `${abiItem.name}(${abiItem.inputs.map((input) => input.type).join(',')})`;\n if (toFunctionSelector(signature).toLowerCase() === selector) {\n return `${abiItem.name}()`;\n }\n }\n }\n\n return null;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../constants.cjs`),t=require(`./_utils.cjs`),n=require(`./_handlers/analyze-support.cjs`),r=require(`./_handlers/estimate-native-fee.cjs`),i=require(`./_handlers/get-assets.cjs`),a=require(`./_handlers/get-bridgeable-assets.cjs`),o=require(`./_handlers/get-minimum-transfer-amount.cjs`),s=require(`./_handlers/stream-quotes.cjs`);require(`./constants.cjs`);const c=require(`./_handlers/track-transfer.cjs`),l=require(`./_handlers/transfer-asset.cjs`);async function u({apiBaseUrl:u,apiToken:d,appId:f,disableCrossChainSwaps:p,environment:m,evmSigner:h,fetch:g,getTargetChainAssets:_,solanaSigner:v}){let y={apiBaseUrl:new URL(u??`https://proxy-api.avax.network/proxy/markr-helium`),apiToken:d,fetch:g},[b,x]=await Promise.all([t.getPartnerFeeBps(y),t.getSupportedChains(y,p)]),S=await t.getSupportedTokens(y,x),C=n.analyzeSupportFactory({hasSolanaSigner:!!v,supportedChains:x});return{analyzeSupport:C,estimateNativeFee:r.estimateNativeFeeFactory({apiOptions:y,appId:f}),getAssets:i.getAssetsFactory({supportedChains:x,supportedTokens:S}),getBridgeableAssets:a.getBridgeableAssetsFactory({getTargetChainAssets:_,supportedChains:x}),getMinimumTransferAmount:o.getMinimumTransferAmountFactory({analyzeSupport:C,partnerFeeBps:b}),getSupportedChains:async()=>{let e=new Map;for(let[t,{crossChainTargetChainIds:n,swapEnabled:r}]of x.entries()){if(!r&&n.size===0)continue;let i=new Set;r&&i.add(t);for(let e of n)e!==t&&x.has(e)&&i.add(e);i.size>0&&e.set(t,i)}return e},streamQuotes:s.streamQuotesFactory({apiOptions:y,appId:f,partnerFeeBps:b}),trackTransfer:c.trackTransferFactory({apiOptions:y}),transferAsset:l.transferAssetFactory({apiOptions:y,appId:f,environment:m,evmSigner:h,solanaSigner:v}),type:e.ServiceType.MARKR}}exports.createMarkrService=u;
1
+ const e=require(`../../constants.cjs`),t=require(`./_utils.cjs`),n=require(`./_handlers/analyze-support.cjs`),r=require(`./_handlers/estimate-native-fee.cjs`),i=require(`./_handlers/get-assets.cjs`),a=require(`./_handlers/get-bridgeable-assets.cjs`),o=require(`./_handlers/get-minimum-transfer-amount.cjs`),s=require(`./_handlers/stream-quotes.cjs`);require(`./constants.cjs`);const c=require(`./_handlers/track-transfer.cjs`),l=require(`./_handlers/transfer-asset.cjs`),u=require(`./recurring/_namespace.cjs`),d=require(`./recurring/_chain-info.cjs`);async function f({apiBaseUrl:f,apiToken:p,appId:m,disableCrossChainSwaps:h,environment:g,evmSigner:_,fetch:v,getTargetChainAssets:y,solanaSigner:b}){let x={apiBaseUrl:new URL(f??`https://proxy-api.avax.network/proxy/markr-helium`),apiToken:p,fetch:v},[S,C]=await Promise.all([t.getPartnerFeeBps(x),t.getSupportedChains(x,h)]),w=await t.getSupportedTokens(x,C),T=d.deriveRecurringChainInfo(C),E=n.analyzeSupportFactory({hasSolanaSigner:!!b,supportedChains:C}),D=u.createRecurringNamespace({apiOptions:x,appId:m,evmSigner:_,recurringChainInfo:T});return{analyzeSupport:E,estimateNativeFee:r.estimateNativeFeeFactory({apiOptions:x,appId:m}),getAssets:i.getAssetsFactory({supportedChains:C,supportedTokens:w}),getBridgeableAssets:a.getBridgeableAssetsFactory({getTargetChainAssets:y,supportedChains:C}),getMinimumTransferAmount:o.getMinimumTransferAmountFactory({analyzeSupport:E,partnerFeeBps:S}),getSupportedChains:async()=>{let e=new Map;for(let[t,{crossChainTargetChainIds:n,swapEnabled:r}]of C.entries()){if(!r&&n.size===0)continue;let i=new Set;r&&i.add(t);for(let e of n)e!==t&&C.has(e)&&i.add(e);i.size>0&&e.set(t,i)}return e},recurring:D,streamQuotes:s.streamQuotesFactory({apiOptions:x,appId:m,partnerFeeBps:S}),trackTransfer:c.trackTransferFactory({apiOptions:x}),transferAsset:l.transferAssetFactory({apiOptions:x,appId:m,environment:g,evmSigner:_,solanaSigner:b}),type:e.ServiceType.MARKR}}exports.createMarkrService=f;
2
2
  //# sourceMappingURL=markr-service.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"markr-service.cjs","names":["getPartnerFeeBps","getSupportedChains","getSupportedTokens","analyzeSupportFactory","estimateNativeFeeFactory","getAssetsFactory","getBridgeableAssetsFactory","getMinimumTransferAmountFactory","streamQuotesFactory","trackTransferFactory","transferAssetFactory","ServiceType"],"sources":["../../../src/transfer-service/markr/markr-service.ts"],"sourcesContent":["import { ServiceType } from '../../constants';\nimport type { Environment } from '../../constants';\nimport type { AssetWithExtras } from '../../types/asset';\nimport type { AssetSearchQuery, MutableGetSupportedChainsResult, TransferService } from '../../types/service';\nimport type { EvmSigner, SolanaSigner } from '../../types/signer';\nimport { analyzeSupportFactory } from './_handlers/analyze-support';\nimport { estimateNativeFeeFactory } from './_handlers/estimate-native-fee';\nimport { getAssetsFactory } from './_handlers/get-assets';\nimport { getBridgeableAssetsFactory } from './_handlers/get-bridgeable-assets';\nimport { getMinimumTransferAmountFactory } from './_handlers/get-minimum-transfer-amount';\nimport { streamQuotesFactory } from './_handlers/stream-quotes';\nimport { trackTransferFactory } from './_handlers/track-transfer';\nimport { transferAssetFactory } from './_handlers/transfer-asset';\nimport { getPartnerFeeBps, getSupportedChains, getSupportedTokens } from './_utils';\nimport { DEFAULT_MARKR_API_URL } from './constants';\nimport type { ApiOptions } from './_api';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface MarkrServiceOptions {\n apiBaseUrl?: string;\n apiToken?: string;\n appId: string;\n disableCrossChainSwaps?: boolean;\n environment: Environment;\n /**\n * EVM signer. Wire up `signTypedData` on the signer to enable Hyperliquid\n * 2-phase withdrawals; otherwise a plain {@link EvmSigner} is sufficient\n * for the legacy EVM swap path.\n */\n evmSigner: EvmSigner;\n fetch?: Fetch;\n getTargetChainAssets: (queryProps: {\n search?: AssetSearchQuery;\n limit: number;\n page: number;\n targetChainId: Caip2ChainId;\n }) => Promise<{\n readonly assets: readonly AssetWithExtras[];\n readonly meta: { readonly currentPage: number; readonly hasMore: boolean; readonly nextPage?: number };\n }>;\n solanaSigner?: SolanaSigner;\n}\n\nexport async function createMarkrService({\n apiBaseUrl: apiBaseUrlString,\n apiToken,\n appId,\n disableCrossChainSwaps,\n environment,\n evmSigner,\n fetch: customFetch,\n getTargetChainAssets,\n solanaSigner,\n}: MarkrServiceOptions): Promise<TransferService> {\n const apiBaseUrl = new URL(apiBaseUrlString ?? DEFAULT_MARKR_API_URL);\n\n const apiOptions: ApiOptions = {\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n };\n\n // Parallelize fetching.\n const [partnerFeeBps, supportedChains] = await Promise.all([\n getPartnerFeeBps(apiOptions),\n getSupportedChains(apiOptions, disableCrossChainSwaps),\n ]);\n\n const supportedTokens = await getSupportedTokens(apiOptions, supportedChains);\n\n const hasSolanaSigner = Boolean(solanaSigner);\n const analyzeSupport = analyzeSupportFactory({ hasSolanaSigner, supportedChains });\n\n return {\n analyzeSupport,\n estimateNativeFee: estimateNativeFeeFactory({ apiOptions, appId }),\n getAssets: getAssetsFactory({ supportedChains, supportedTokens }),\n getBridgeableAssets: getBridgeableAssetsFactory({ getTargetChainAssets, supportedChains }),\n getMinimumTransferAmount: getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n }),\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n for (const [sourceChainId, { crossChainTargetChainIds, swapEnabled }] of supportedChains.entries()) {\n if (!swapEnabled && crossChainTargetChainIds.size === 0) {\n // If neither swap nor cross-chain swap is enabled, skip this chain as a source.\n continue;\n }\n\n const supportedTargetChainIds = new Set<Caip2ChainId>();\n\n // Add self as supported target if same-chain swap is enabled.\n if (swapEnabled) {\n supportedTargetChainIds.add(sourceChainId);\n }\n\n for (const chainId of crossChainTargetChainIds) {\n if (chainId !== sourceChainId && supportedChains.has(chainId)) {\n supportedTargetChainIds.add(chainId);\n }\n }\n\n if (supportedTargetChainIds.size > 0) {\n supportedChainsMap.set(sourceChainId, supportedTargetChainIds);\n }\n }\n\n return supportedChainsMap;\n },\n streamQuotes: streamQuotesFactory({ apiOptions, appId, partnerFeeBps }),\n trackTransfer: trackTransferFactory({ apiOptions }),\n transferAsset: transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n }),\n type: ServiceType.MARKR,\n } satisfies TransferService;\n}\n"],"mappings":"udA4CA,eAAsB,EAAmB,CACvC,WAAY,EACZ,WACA,QACA,yBACA,cACA,YACA,MAAO,EACP,uBACA,gBACgD,CAGhD,IAAM,EAAyB,CAC7B,WAHiB,IAAI,IAAI,GAAA,oDAA0C,CAInE,WACA,MAAO,EACR,CAGK,CAAC,EAAe,GAAmB,MAAM,QAAQ,IAAI,CACzDA,EAAAA,iBAAiB,EAAW,CAC5BC,EAAAA,mBAAmB,EAAY,EAAuB,CACvD,CAAC,CAEI,EAAkB,MAAMC,EAAAA,mBAAmB,EAAY,EAAgB,CAGvE,EAAiBC,EAAAA,sBAAsB,CAAE,gBADvB,EAAQ,EACgC,kBAAiB,CAAC,CAElF,MAAO,CACL,iBACA,kBAAmBC,EAAAA,yBAAyB,CAAE,aAAY,QAAO,CAAC,CAClE,UAAWC,EAAAA,iBAAiB,CAAE,kBAAiB,kBAAiB,CAAC,CACjE,oBAAqBC,EAAAA,2BAA2B,CAAE,uBAAsB,kBAAiB,CAAC,CAC1F,yBAA0BC,EAAAA,gCAAgC,CACxD,iBACA,gBACD,CAAC,CACF,mBAAoB,SAAY,CAC9B,IAAM,EAAsD,IAAI,IAEhE,IAAK,GAAM,CAAC,EAAe,CAAE,2BAA0B,kBAAkB,EAAgB,SAAS,CAAE,CAClG,GAAI,CAAC,GAAe,EAAyB,OAAS,EAEpD,SAGF,IAAM,EAA0B,IAAI,IAGhC,GACF,EAAwB,IAAI,EAAc,CAG5C,IAAK,IAAM,KAAW,EAChB,IAAY,GAAiB,EAAgB,IAAI,EAAQ,EAC3D,EAAwB,IAAI,EAAQ,CAIpC,EAAwB,KAAO,GACjC,EAAmB,IAAI,EAAe,EAAwB,CAIlE,OAAO,GAET,aAAcC,EAAAA,oBAAoB,CAAE,aAAY,QAAO,gBAAe,CAAC,CACvE,cAAeC,EAAAA,qBAAqB,CAAE,aAAY,CAAC,CACnD,cAAeC,EAAAA,qBAAqB,CAClC,aACA,QACA,cACA,YACA,eACD,CAAC,CACF,KAAMC,EAAAA,YAAY,MACnB"}
1
+ {"version":3,"file":"markr-service.cjs","names":["getPartnerFeeBps","getSupportedChains","getSupportedTokens","deriveRecurringChainInfo","analyzeSupportFactory","createRecurringNamespace","estimateNativeFeeFactory","getAssetsFactory","getBridgeableAssetsFactory","getMinimumTransferAmountFactory","streamQuotesFactory","trackTransferFactory","transferAssetFactory","ServiceType"],"sources":["../../../src/transfer-service/markr/markr-service.ts"],"sourcesContent":["import { ServiceType } from '../../constants';\nimport type { Environment } from '../../constants';\nimport type { AssetWithExtras } from '../../types/asset';\nimport type { AssetSearchQuery, MutableGetSupportedChainsResult, TransferService } from '../../types/service';\nimport type { EvmSigner, SolanaSigner } from '../../types/signer';\nimport { analyzeSupportFactory } from './_handlers/analyze-support';\nimport { estimateNativeFeeFactory } from './_handlers/estimate-native-fee';\nimport { getAssetsFactory } from './_handlers/get-assets';\nimport { getBridgeableAssetsFactory } from './_handlers/get-bridgeable-assets';\nimport { getMinimumTransferAmountFactory } from './_handlers/get-minimum-transfer-amount';\nimport { streamQuotesFactory } from './_handlers/stream-quotes';\nimport { trackTransferFactory } from './_handlers/track-transfer';\nimport { transferAssetFactory } from './_handlers/transfer-asset';\nimport { getPartnerFeeBps, getSupportedChains, getSupportedTokens } from './_utils';\nimport { DEFAULT_MARKR_API_URL } from './constants';\nimport type { ApiOptions } from './_api';\n// Deep-import the internal factory + chain-info helper directly from their\n// sibling modules. They are NOT re-exported from `recurring/index.ts` (and\n// thus not part of the SDK's public surface) — see the public-surface design\n// note in §A11 of the spec.\nimport { createRecurringNamespace } from './recurring/_namespace';\nimport { deriveRecurringChainInfo } from './recurring/_chain-info';\nimport type { RecurringChainInfoMap, RecurringNamespace } from './recurring/types';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface MarkrServiceOptions {\n apiBaseUrl?: string;\n apiToken?: string;\n appId: string;\n disableCrossChainSwaps?: boolean;\n environment: Environment;\n /**\n * EVM signer. Wire up `signTypedData` on the signer to enable Hyperliquid\n * 2-phase withdrawals; otherwise a plain {@link EvmSigner} is sufficient\n * for the legacy EVM swap path.\n */\n evmSigner: EvmSigner;\n fetch?: Fetch;\n getTargetChainAssets: (queryProps: {\n search?: AssetSearchQuery;\n limit: number;\n page: number;\n targetChainId: Caip2ChainId;\n }) => Promise<{\n readonly assets: readonly AssetWithExtras[];\n readonly meta: { readonly currentPage: number; readonly hasMore: boolean; readonly nextPage?: number };\n }>;\n solanaSigner?: SolanaSigner;\n}\n\n/**\n * Narrowed `TransferService` returned by {@link createMarkrService}. Adds the\n * `.recurring` namespace (Markr's DCA endpoints).\n *\n * Assignable wherever `TransferService` is expected (covariant return).\n *\n * Note on staleness: `partnerFeeBps`, `supportedChains`, `supportedTokens`,\n * and `recurringChainInfo` are all fetched once at init from `/info/chains`\n * + `/info/partner` and frozen by value. Consumers that need to pick up\n * server-side changes (e.g. a newly enabled recurring chain, an updated\n * minimum) must recreate the transfer manager. An earlier draft exposed\n * a `refresh()` method but it was never reachable from the public\n * `TransferManager` surface and was dropped; if staleness ever bites for\n * real, the right fix is a top-level `manager.refresh()` that rebuilds the\n * whole service — not a per-namespace lazy-read pattern.\n */\nexport interface MarkrService extends TransferService {\n readonly recurring: RecurringNamespace;\n}\n\nexport async function createMarkrService({\n apiBaseUrl: apiBaseUrlString,\n apiToken,\n appId,\n disableCrossChainSwaps,\n environment,\n evmSigner,\n fetch: customFetch,\n getTargetChainAssets,\n solanaSigner,\n}: MarkrServiceOptions): Promise<MarkrService> {\n const apiBaseUrl = new URL(apiBaseUrlString ?? DEFAULT_MARKR_API_URL);\n\n const apiOptions: ApiOptions = {\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n };\n\n const [partnerFeeBps, initialSupportedChains] = await Promise.all([\n getPartnerFeeBps(apiOptions),\n getSupportedChains(apiOptions, disableCrossChainSwaps),\n ]);\n\n const supportedTokens = await getSupportedTokens(apiOptions, initialSupportedChains);\n\n const recurringChainInfo: RecurringChainInfoMap = deriveRecurringChainInfo(initialSupportedChains);\n\n const hasSolanaSigner = Boolean(solanaSigner);\n const analyzeSupport = analyzeSupportFactory({ hasSolanaSigner, supportedChains: initialSupportedChains });\n\n const recurring = createRecurringNamespace({\n apiOptions,\n appId,\n evmSigner,\n recurringChainInfo,\n });\n\n return {\n analyzeSupport,\n estimateNativeFee: estimateNativeFeeFactory({ apiOptions, appId }),\n getAssets: getAssetsFactory({ supportedChains: initialSupportedChains, supportedTokens }),\n getBridgeableAssets: getBridgeableAssetsFactory({\n getTargetChainAssets,\n supportedChains: initialSupportedChains,\n }),\n getMinimumTransferAmount: getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n }),\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n for (const [sourceChainId, { crossChainTargetChainIds, swapEnabled }] of initialSupportedChains.entries()) {\n if (!swapEnabled && crossChainTargetChainIds.size === 0) {\n // If neither swap nor cross-chain swap is enabled, skip this chain as a source.\n continue;\n }\n\n const supportedTargetChainIds = new Set<Caip2ChainId>();\n\n // Add self as supported target if same-chain swap is enabled.\n if (swapEnabled) {\n supportedTargetChainIds.add(sourceChainId);\n }\n\n for (const chainId of crossChainTargetChainIds) {\n if (chainId !== sourceChainId && initialSupportedChains.has(chainId)) {\n supportedTargetChainIds.add(chainId);\n }\n }\n\n if (supportedTargetChainIds.size > 0) {\n supportedChainsMap.set(sourceChainId, supportedTargetChainIds);\n }\n }\n\n return supportedChainsMap;\n },\n recurring,\n streamQuotes: streamQuotesFactory({ apiOptions, appId, partnerFeeBps }),\n trackTransfer: trackTransferFactory({ apiOptions }),\n transferAsset: transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n }),\n type: ServiceType.MARKR,\n } satisfies MarkrService;\n}\n"],"mappings":"wiBAuEA,eAAsB,EAAmB,CACvC,WAAY,EACZ,WACA,QACA,yBACA,cACA,YACA,MAAO,EACP,uBACA,gBAC6C,CAG7C,IAAM,EAAyB,CAC7B,WAHiB,IAAI,IAAI,GAAA,oDAA0C,CAInE,WACA,MAAO,EACR,CAEK,CAAC,EAAe,GAA0B,MAAM,QAAQ,IAAI,CAChEA,EAAAA,iBAAiB,EAAW,CAC5BC,EAAAA,mBAAmB,EAAY,EAAuB,CACvD,CAAC,CAEI,EAAkB,MAAMC,EAAAA,mBAAmB,EAAY,EAAuB,CAE9E,EAA4CC,EAAAA,yBAAyB,EAAuB,CAG5F,EAAiBC,EAAAA,sBAAsB,CAAE,gBADvB,EAAQ,EACgC,gBAAiB,EAAwB,CAAC,CAEpG,EAAYC,EAAAA,yBAAyB,CACzC,aACA,QACA,YACA,qBACD,CAAC,CAEF,MAAO,CACL,iBACA,kBAAmBC,EAAAA,yBAAyB,CAAE,aAAY,QAAO,CAAC,CAClE,UAAWC,EAAAA,iBAAiB,CAAE,gBAAiB,EAAwB,kBAAiB,CAAC,CACzF,oBAAqBC,EAAAA,2BAA2B,CAC9C,uBACA,gBAAiB,EAClB,CAAC,CACF,yBAA0BC,EAAAA,gCAAgC,CACxD,iBACA,gBACD,CAAC,CACF,mBAAoB,SAAY,CAC9B,IAAM,EAAsD,IAAI,IAEhE,IAAK,GAAM,CAAC,EAAe,CAAE,2BAA0B,kBAAkB,EAAuB,SAAS,CAAE,CACzG,GAAI,CAAC,GAAe,EAAyB,OAAS,EAEpD,SAGF,IAAM,EAA0B,IAAI,IAGhC,GACF,EAAwB,IAAI,EAAc,CAG5C,IAAK,IAAM,KAAW,EAChB,IAAY,GAAiB,EAAuB,IAAI,EAAQ,EAClE,EAAwB,IAAI,EAAQ,CAIpC,EAAwB,KAAO,GACjC,EAAmB,IAAI,EAAe,EAAwB,CAIlE,OAAO,GAET,YACA,aAAcC,EAAAA,oBAAoB,CAAE,aAAY,QAAO,gBAAe,CAAC,CACvE,cAAeC,EAAAA,qBAAqB,CAAE,aAAY,CAAC,CACnD,cAAeC,EAAAA,qBAAqB,CAClC,aACA,QACA,cACA,YACA,eACD,CAAC,CACF,KAAMC,EAAAA,YAAY,MACnB"}
@@ -0,0 +1,26 @@
1
+ import { TransferService } from "../../types/service.cjs";
2
+ import { RecurringNamespace } from "./recurring/types.cjs";
3
+
4
+ //#region src/transfer-service/markr/markr-service.d.ts
5
+ /**
6
+ * Narrowed `TransferService` returned by {@link createMarkrService}. Adds the
7
+ * `.recurring` namespace (Markr's DCA endpoints).
8
+ *
9
+ * Assignable wherever `TransferService` is expected (covariant return).
10
+ *
11
+ * Note on staleness: `partnerFeeBps`, `supportedChains`, `supportedTokens`,
12
+ * and `recurringChainInfo` are all fetched once at init from `/info/chains`
13
+ * + `/info/partner` and frozen by value. Consumers that need to pick up
14
+ * server-side changes (e.g. a newly enabled recurring chain, an updated
15
+ * minimum) must recreate the transfer manager. An earlier draft exposed
16
+ * a `refresh()` method but it was never reachable from the public
17
+ * `TransferManager` surface and was dropped; if staleness ever bites for
18
+ * real, the right fix is a top-level `manager.refresh()` that rebuilds the
19
+ * whole service — not a per-namespace lazy-read pattern.
20
+ */
21
+ interface MarkrService extends TransferService {
22
+ readonly recurring: RecurringNamespace;
23
+ }
24
+ //#endregion
25
+ export { MarkrService };
26
+ //# sourceMappingURL=markr-service.d.cts.map
@@ -0,0 +1,26 @@
1
+ import { TransferService } from "../../types/service.js";
2
+ import { RecurringNamespace } from "./recurring/types.js";
3
+
4
+ //#region src/transfer-service/markr/markr-service.d.ts
5
+ /**
6
+ * Narrowed `TransferService` returned by {@link createMarkrService}. Adds the
7
+ * `.recurring` namespace (Markr's DCA endpoints).
8
+ *
9
+ * Assignable wherever `TransferService` is expected (covariant return).
10
+ *
11
+ * Note on staleness: `partnerFeeBps`, `supportedChains`, `supportedTokens`,
12
+ * and `recurringChainInfo` are all fetched once at init from `/info/chains`
13
+ * + `/info/partner` and frozen by value. Consumers that need to pick up
14
+ * server-side changes (e.g. a newly enabled recurring chain, an updated
15
+ * minimum) must recreate the transfer manager. An earlier draft exposed
16
+ * a `refresh()` method but it was never reachable from the public
17
+ * `TransferManager` surface and was dropped; if staleness ever bites for
18
+ * real, the right fix is a top-level `manager.refresh()` that rebuilds the
19
+ * whole service — not a per-namespace lazy-read pattern.
20
+ */
21
+ interface MarkrService extends TransferService {
22
+ readonly recurring: RecurringNamespace;
23
+ }
24
+ //#endregion
25
+ export { MarkrService };
26
+ //# sourceMappingURL=markr-service.d.ts.map
@@ -1,2 +1,2 @@
1
- import{ServiceType as e}from"../../constants.js";import{getPartnerFeeBps as t,getSupportedChains as n,getSupportedTokens as r}from"./_utils.js";import{analyzeSupportFactory as i}from"./_handlers/analyze-support.js";import{estimateNativeFeeFactory as a}from"./_handlers/estimate-native-fee.js";import{getAssetsFactory as o}from"./_handlers/get-assets.js";import{getBridgeableAssetsFactory as s}from"./_handlers/get-bridgeable-assets.js";import{getMinimumTransferAmountFactory as c}from"./_handlers/get-minimum-transfer-amount.js";import{streamQuotesFactory as l}from"./_handlers/stream-quotes.js";import"./constants.js";import{trackTransferFactory as u}from"./_handlers/track-transfer.js";import{transferAssetFactory as d}from"./_handlers/transfer-asset.js";async function f({apiBaseUrl:f,apiToken:p,appId:m,disableCrossChainSwaps:h,environment:g,evmSigner:_,fetch:v,getTargetChainAssets:y,solanaSigner:b}){let x={apiBaseUrl:new URL(f??`https://proxy-api.avax.network/proxy/markr-helium`),apiToken:p,fetch:v},[S,C]=await Promise.all([t(x),n(x,h)]),w=await r(x,C),T=i({hasSolanaSigner:!!b,supportedChains:C});return{analyzeSupport:T,estimateNativeFee:a({apiOptions:x,appId:m}),getAssets:o({supportedChains:C,supportedTokens:w}),getBridgeableAssets:s({getTargetChainAssets:y,supportedChains:C}),getMinimumTransferAmount:c({analyzeSupport:T,partnerFeeBps:S}),getSupportedChains:async()=>{let e=new Map;for(let[t,{crossChainTargetChainIds:n,swapEnabled:r}]of C.entries()){if(!r&&n.size===0)continue;let i=new Set;r&&i.add(t);for(let e of n)e!==t&&C.has(e)&&i.add(e);i.size>0&&e.set(t,i)}return e},streamQuotes:l({apiOptions:x,appId:m,partnerFeeBps:S}),trackTransfer:u({apiOptions:x}),transferAsset:d({apiOptions:x,appId:m,environment:g,evmSigner:_,solanaSigner:b}),type:e.MARKR}}export{f as createMarkrService};
1
+ import{ServiceType as e}from"../../constants.js";import{getPartnerFeeBps as t,getSupportedChains as n,getSupportedTokens as r}from"./_utils.js";import{analyzeSupportFactory as i}from"./_handlers/analyze-support.js";import{estimateNativeFeeFactory as a}from"./_handlers/estimate-native-fee.js";import{getAssetsFactory as o}from"./_handlers/get-assets.js";import{getBridgeableAssetsFactory as s}from"./_handlers/get-bridgeable-assets.js";import{getMinimumTransferAmountFactory as c}from"./_handlers/get-minimum-transfer-amount.js";import{streamQuotesFactory as l}from"./_handlers/stream-quotes.js";import"./constants.js";import{trackTransferFactory as u}from"./_handlers/track-transfer.js";import{transferAssetFactory as d}from"./_handlers/transfer-asset.js";import{createRecurringNamespace as f}from"./recurring/_namespace.js";import{deriveRecurringChainInfo as p}from"./recurring/_chain-info.js";async function m({apiBaseUrl:m,apiToken:h,appId:g,disableCrossChainSwaps:_,environment:v,evmSigner:y,fetch:b,getTargetChainAssets:x,solanaSigner:S}){let C={apiBaseUrl:new URL(m??`https://proxy-api.avax.network/proxy/markr-helium`),apiToken:h,fetch:b},[w,T]=await Promise.all([t(C),n(C,_)]),E=await r(C,T),D=p(T),O=i({hasSolanaSigner:!!S,supportedChains:T}),k=f({apiOptions:C,appId:g,evmSigner:y,recurringChainInfo:D});return{analyzeSupport:O,estimateNativeFee:a({apiOptions:C,appId:g}),getAssets:o({supportedChains:T,supportedTokens:E}),getBridgeableAssets:s({getTargetChainAssets:x,supportedChains:T}),getMinimumTransferAmount:c({analyzeSupport:O,partnerFeeBps:w}),getSupportedChains:async()=>{let e=new Map;for(let[t,{crossChainTargetChainIds:n,swapEnabled:r}]of T.entries()){if(!r&&n.size===0)continue;let i=new Set;r&&i.add(t);for(let e of n)e!==t&&T.has(e)&&i.add(e);i.size>0&&e.set(t,i)}return e},recurring:k,streamQuotes:l({apiOptions:C,appId:g,partnerFeeBps:w}),trackTransfer:u({apiOptions:C}),transferAsset:d({apiOptions:C,appId:g,environment:v,evmSigner:y,solanaSigner:S}),type:e.MARKR}}export{m as createMarkrService};
2
2
  //# sourceMappingURL=markr-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markr-service.js","names":[],"sources":["../../../src/transfer-service/markr/markr-service.ts"],"sourcesContent":["import { ServiceType } from '../../constants';\nimport type { Environment } from '../../constants';\nimport type { AssetWithExtras } from '../../types/asset';\nimport type { AssetSearchQuery, MutableGetSupportedChainsResult, TransferService } from '../../types/service';\nimport type { EvmSigner, SolanaSigner } from '../../types/signer';\nimport { analyzeSupportFactory } from './_handlers/analyze-support';\nimport { estimateNativeFeeFactory } from './_handlers/estimate-native-fee';\nimport { getAssetsFactory } from './_handlers/get-assets';\nimport { getBridgeableAssetsFactory } from './_handlers/get-bridgeable-assets';\nimport { getMinimumTransferAmountFactory } from './_handlers/get-minimum-transfer-amount';\nimport { streamQuotesFactory } from './_handlers/stream-quotes';\nimport { trackTransferFactory } from './_handlers/track-transfer';\nimport { transferAssetFactory } from './_handlers/transfer-asset';\nimport { getPartnerFeeBps, getSupportedChains, getSupportedTokens } from './_utils';\nimport { DEFAULT_MARKR_API_URL } from './constants';\nimport type { ApiOptions } from './_api';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface MarkrServiceOptions {\n apiBaseUrl?: string;\n apiToken?: string;\n appId: string;\n disableCrossChainSwaps?: boolean;\n environment: Environment;\n /**\n * EVM signer. Wire up `signTypedData` on the signer to enable Hyperliquid\n * 2-phase withdrawals; otherwise a plain {@link EvmSigner} is sufficient\n * for the legacy EVM swap path.\n */\n evmSigner: EvmSigner;\n fetch?: Fetch;\n getTargetChainAssets: (queryProps: {\n search?: AssetSearchQuery;\n limit: number;\n page: number;\n targetChainId: Caip2ChainId;\n }) => Promise<{\n readonly assets: readonly AssetWithExtras[];\n readonly meta: { readonly currentPage: number; readonly hasMore: boolean; readonly nextPage?: number };\n }>;\n solanaSigner?: SolanaSigner;\n}\n\nexport async function createMarkrService({\n apiBaseUrl: apiBaseUrlString,\n apiToken,\n appId,\n disableCrossChainSwaps,\n environment,\n evmSigner,\n fetch: customFetch,\n getTargetChainAssets,\n solanaSigner,\n}: MarkrServiceOptions): Promise<TransferService> {\n const apiBaseUrl = new URL(apiBaseUrlString ?? DEFAULT_MARKR_API_URL);\n\n const apiOptions: ApiOptions = {\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n };\n\n // Parallelize fetching.\n const [partnerFeeBps, supportedChains] = await Promise.all([\n getPartnerFeeBps(apiOptions),\n getSupportedChains(apiOptions, disableCrossChainSwaps),\n ]);\n\n const supportedTokens = await getSupportedTokens(apiOptions, supportedChains);\n\n const hasSolanaSigner = Boolean(solanaSigner);\n const analyzeSupport = analyzeSupportFactory({ hasSolanaSigner, supportedChains });\n\n return {\n analyzeSupport,\n estimateNativeFee: estimateNativeFeeFactory({ apiOptions, appId }),\n getAssets: getAssetsFactory({ supportedChains, supportedTokens }),\n getBridgeableAssets: getBridgeableAssetsFactory({ getTargetChainAssets, supportedChains }),\n getMinimumTransferAmount: getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n }),\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n for (const [sourceChainId, { crossChainTargetChainIds, swapEnabled }] of supportedChains.entries()) {\n if (!swapEnabled && crossChainTargetChainIds.size === 0) {\n // If neither swap nor cross-chain swap is enabled, skip this chain as a source.\n continue;\n }\n\n const supportedTargetChainIds = new Set<Caip2ChainId>();\n\n // Add self as supported target if same-chain swap is enabled.\n if (swapEnabled) {\n supportedTargetChainIds.add(sourceChainId);\n }\n\n for (const chainId of crossChainTargetChainIds) {\n if (chainId !== sourceChainId && supportedChains.has(chainId)) {\n supportedTargetChainIds.add(chainId);\n }\n }\n\n if (supportedTargetChainIds.size > 0) {\n supportedChainsMap.set(sourceChainId, supportedTargetChainIds);\n }\n }\n\n return supportedChainsMap;\n },\n streamQuotes: streamQuotesFactory({ apiOptions, appId, partnerFeeBps }),\n trackTransfer: trackTransferFactory({ apiOptions }),\n transferAsset: transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n }),\n type: ServiceType.MARKR,\n } satisfies TransferService;\n}\n"],"mappings":"qvBA4CA,eAAsB,EAAmB,CACvC,WAAY,EACZ,WACA,QACA,yBACA,cACA,YACA,MAAO,EACP,uBACA,gBACgD,CAGhD,IAAM,EAAyB,CAC7B,WAHiB,IAAI,IAAI,GAAA,oDAA0C,CAInE,WACA,MAAO,EACR,CAGK,CAAC,EAAe,GAAmB,MAAM,QAAQ,IAAI,CACzD,EAAiB,EAAW,CAC5B,EAAmB,EAAY,EAAuB,CACvD,CAAC,CAEI,EAAkB,MAAM,EAAmB,EAAY,EAAgB,CAGvE,EAAiB,EAAsB,CAAE,gBADvB,EAAQ,EACgC,kBAAiB,CAAC,CAElF,MAAO,CACL,iBACA,kBAAmB,EAAyB,CAAE,aAAY,QAAO,CAAC,CAClE,UAAW,EAAiB,CAAE,kBAAiB,kBAAiB,CAAC,CACjE,oBAAqB,EAA2B,CAAE,uBAAsB,kBAAiB,CAAC,CAC1F,yBAA0B,EAAgC,CACxD,iBACA,gBACD,CAAC,CACF,mBAAoB,SAAY,CAC9B,IAAM,EAAsD,IAAI,IAEhE,IAAK,GAAM,CAAC,EAAe,CAAE,2BAA0B,kBAAkB,EAAgB,SAAS,CAAE,CAClG,GAAI,CAAC,GAAe,EAAyB,OAAS,EAEpD,SAGF,IAAM,EAA0B,IAAI,IAGhC,GACF,EAAwB,IAAI,EAAc,CAG5C,IAAK,IAAM,KAAW,EAChB,IAAY,GAAiB,EAAgB,IAAI,EAAQ,EAC3D,EAAwB,IAAI,EAAQ,CAIpC,EAAwB,KAAO,GACjC,EAAmB,IAAI,EAAe,EAAwB,CAIlE,OAAO,GAET,aAAc,EAAoB,CAAE,aAAY,QAAO,gBAAe,CAAC,CACvE,cAAe,EAAqB,CAAE,aAAY,CAAC,CACnD,cAAe,EAAqB,CAClC,aACA,QACA,cACA,YACA,eACD,CAAC,CACF,KAAM,EAAY,MACnB"}
1
+ {"version":3,"file":"markr-service.js","names":[],"sources":["../../../src/transfer-service/markr/markr-service.ts"],"sourcesContent":["import { ServiceType } from '../../constants';\nimport type { Environment } from '../../constants';\nimport type { AssetWithExtras } from '../../types/asset';\nimport type { AssetSearchQuery, MutableGetSupportedChainsResult, TransferService } from '../../types/service';\nimport type { EvmSigner, SolanaSigner } from '../../types/signer';\nimport { analyzeSupportFactory } from './_handlers/analyze-support';\nimport { estimateNativeFeeFactory } from './_handlers/estimate-native-fee';\nimport { getAssetsFactory } from './_handlers/get-assets';\nimport { getBridgeableAssetsFactory } from './_handlers/get-bridgeable-assets';\nimport { getMinimumTransferAmountFactory } from './_handlers/get-minimum-transfer-amount';\nimport { streamQuotesFactory } from './_handlers/stream-quotes';\nimport { trackTransferFactory } from './_handlers/track-transfer';\nimport { transferAssetFactory } from './_handlers/transfer-asset';\nimport { getPartnerFeeBps, getSupportedChains, getSupportedTokens } from './_utils';\nimport { DEFAULT_MARKR_API_URL } from './constants';\nimport type { ApiOptions } from './_api';\n// Deep-import the internal factory + chain-info helper directly from their\n// sibling modules. They are NOT re-exported from `recurring/index.ts` (and\n// thus not part of the SDK's public surface) — see the public-surface design\n// note in §A11 of the spec.\nimport { createRecurringNamespace } from './recurring/_namespace';\nimport { deriveRecurringChainInfo } from './recurring/_chain-info';\nimport type { RecurringChainInfoMap, RecurringNamespace } from './recurring/types';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface MarkrServiceOptions {\n apiBaseUrl?: string;\n apiToken?: string;\n appId: string;\n disableCrossChainSwaps?: boolean;\n environment: Environment;\n /**\n * EVM signer. Wire up `signTypedData` on the signer to enable Hyperliquid\n * 2-phase withdrawals; otherwise a plain {@link EvmSigner} is sufficient\n * for the legacy EVM swap path.\n */\n evmSigner: EvmSigner;\n fetch?: Fetch;\n getTargetChainAssets: (queryProps: {\n search?: AssetSearchQuery;\n limit: number;\n page: number;\n targetChainId: Caip2ChainId;\n }) => Promise<{\n readonly assets: readonly AssetWithExtras[];\n readonly meta: { readonly currentPage: number; readonly hasMore: boolean; readonly nextPage?: number };\n }>;\n solanaSigner?: SolanaSigner;\n}\n\n/**\n * Narrowed `TransferService` returned by {@link createMarkrService}. Adds the\n * `.recurring` namespace (Markr's DCA endpoints).\n *\n * Assignable wherever `TransferService` is expected (covariant return).\n *\n * Note on staleness: `partnerFeeBps`, `supportedChains`, `supportedTokens`,\n * and `recurringChainInfo` are all fetched once at init from `/info/chains`\n * + `/info/partner` and frozen by value. Consumers that need to pick up\n * server-side changes (e.g. a newly enabled recurring chain, an updated\n * minimum) must recreate the transfer manager. An earlier draft exposed\n * a `refresh()` method but it was never reachable from the public\n * `TransferManager` surface and was dropped; if staleness ever bites for\n * real, the right fix is a top-level `manager.refresh()` that rebuilds the\n * whole service — not a per-namespace lazy-read pattern.\n */\nexport interface MarkrService extends TransferService {\n readonly recurring: RecurringNamespace;\n}\n\nexport async function createMarkrService({\n apiBaseUrl: apiBaseUrlString,\n apiToken,\n appId,\n disableCrossChainSwaps,\n environment,\n evmSigner,\n fetch: customFetch,\n getTargetChainAssets,\n solanaSigner,\n}: MarkrServiceOptions): Promise<MarkrService> {\n const apiBaseUrl = new URL(apiBaseUrlString ?? DEFAULT_MARKR_API_URL);\n\n const apiOptions: ApiOptions = {\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n };\n\n const [partnerFeeBps, initialSupportedChains] = await Promise.all([\n getPartnerFeeBps(apiOptions),\n getSupportedChains(apiOptions, disableCrossChainSwaps),\n ]);\n\n const supportedTokens = await getSupportedTokens(apiOptions, initialSupportedChains);\n\n const recurringChainInfo: RecurringChainInfoMap = deriveRecurringChainInfo(initialSupportedChains);\n\n const hasSolanaSigner = Boolean(solanaSigner);\n const analyzeSupport = analyzeSupportFactory({ hasSolanaSigner, supportedChains: initialSupportedChains });\n\n const recurring = createRecurringNamespace({\n apiOptions,\n appId,\n evmSigner,\n recurringChainInfo,\n });\n\n return {\n analyzeSupport,\n estimateNativeFee: estimateNativeFeeFactory({ apiOptions, appId }),\n getAssets: getAssetsFactory({ supportedChains: initialSupportedChains, supportedTokens }),\n getBridgeableAssets: getBridgeableAssetsFactory({\n getTargetChainAssets,\n supportedChains: initialSupportedChains,\n }),\n getMinimumTransferAmount: getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n }),\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n for (const [sourceChainId, { crossChainTargetChainIds, swapEnabled }] of initialSupportedChains.entries()) {\n if (!swapEnabled && crossChainTargetChainIds.size === 0) {\n // If neither swap nor cross-chain swap is enabled, skip this chain as a source.\n continue;\n }\n\n const supportedTargetChainIds = new Set<Caip2ChainId>();\n\n // Add self as supported target if same-chain swap is enabled.\n if (swapEnabled) {\n supportedTargetChainIds.add(sourceChainId);\n }\n\n for (const chainId of crossChainTargetChainIds) {\n if (chainId !== sourceChainId && initialSupportedChains.has(chainId)) {\n supportedTargetChainIds.add(chainId);\n }\n }\n\n if (supportedTargetChainIds.size > 0) {\n supportedChainsMap.set(sourceChainId, supportedTargetChainIds);\n }\n }\n\n return supportedChainsMap;\n },\n recurring,\n streamQuotes: streamQuotesFactory({ apiOptions, appId, partnerFeeBps }),\n trackTransfer: trackTransferFactory({ apiOptions }),\n transferAsset: transferAssetFactory({\n apiOptions,\n appId,\n environment,\n evmSigner,\n solanaSigner,\n }),\n type: ServiceType.MARKR,\n } satisfies MarkrService;\n}\n"],"mappings":"g4BAuEA,eAAsB,EAAmB,CACvC,WAAY,EACZ,WACA,QACA,yBACA,cACA,YACA,MAAO,EACP,uBACA,gBAC6C,CAG7C,IAAM,EAAyB,CAC7B,WAHiB,IAAI,IAAI,GAAA,oDAA0C,CAInE,WACA,MAAO,EACR,CAEK,CAAC,EAAe,GAA0B,MAAM,QAAQ,IAAI,CAChE,EAAiB,EAAW,CAC5B,EAAmB,EAAY,EAAuB,CACvD,CAAC,CAEI,EAAkB,MAAM,EAAmB,EAAY,EAAuB,CAE9E,EAA4C,EAAyB,EAAuB,CAG5F,EAAiB,EAAsB,CAAE,gBADvB,EAAQ,EACgC,gBAAiB,EAAwB,CAAC,CAEpG,EAAY,EAAyB,CACzC,aACA,QACA,YACA,qBACD,CAAC,CAEF,MAAO,CACL,iBACA,kBAAmB,EAAyB,CAAE,aAAY,QAAO,CAAC,CAClE,UAAW,EAAiB,CAAE,gBAAiB,EAAwB,kBAAiB,CAAC,CACzF,oBAAqB,EAA2B,CAC9C,uBACA,gBAAiB,EAClB,CAAC,CACF,yBAA0B,EAAgC,CACxD,iBACA,gBACD,CAAC,CACF,mBAAoB,SAAY,CAC9B,IAAM,EAAsD,IAAI,IAEhE,IAAK,GAAM,CAAC,EAAe,CAAE,2BAA0B,kBAAkB,EAAuB,SAAS,CAAE,CACzG,GAAI,CAAC,GAAe,EAAyB,OAAS,EAEpD,SAGF,IAAM,EAA0B,IAAI,IAGhC,GACF,EAAwB,IAAI,EAAc,CAG5C,IAAK,IAAM,KAAW,EAChB,IAAY,GAAiB,EAAuB,IAAI,EAAQ,EAClE,EAAwB,IAAI,EAAQ,CAIpC,EAAwB,KAAO,GACjC,EAAmB,IAAI,EAAe,EAAwB,CAIlE,OAAO,GAET,YACA,aAAc,EAAoB,CAAE,aAAY,QAAO,gBAAe,CAAC,CACvE,cAAe,EAAqB,CAAE,aAAY,CAAC,CACnD,cAAe,EAAqB,CAClC,aACA,QACA,cACA,YACA,eACD,CAAC,CACF,KAAM,EAAY,MACnB"}
@@ -0,0 +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:i,apiToken:a,fetch:s},c){let l=`/recurring/swap`,u=await n.fetchJson(n.combineUrlPathnames(i,l),{body:JSON.stringify(c),fetch:s,headers:r.getAuthHeaders(a),method:`POST`,retries:3,retryOn:o}),d=t.WrappedSwapTransactionResponseSchema.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;
2
+ //# sourceMappingURL=_api.cjs.map