@avalabs/fusion-sdk 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/transfer-manager.cjs +1 -1
- package/dist/transfer-manager.cjs.map +1 -1
- package/dist/transfer-manager.js +1 -1
- package/dist/transfer-manager.js.map +1 -1
- package/dist/transfer-service/markr/_api.cjs.map +1 -1
- package/dist/transfer-service/markr/_api.js.map +1 -1
- package/dist/transfer-service/markr/_handlers/stream-quotes.cjs +1 -1
- package/dist/transfer-service/markr/_handlers/stream-quotes.cjs.map +1 -1
- package/dist/transfer-service/markr/_handlers/stream-quotes.js +1 -1
- package/dist/transfer-service/markr/_handlers/stream-quotes.js.map +1 -1
- package/dist/transfer-service/markr/_handlers/track-transfer.cjs +1 -1
- package/dist/transfer-service/markr/_handlers/track-transfer.cjs.map +1 -1
- package/dist/transfer-service/markr/_handlers/track-transfer.js +1 -1
- package/dist/transfer-service/markr/_handlers/track-transfer.js.map +1 -1
- package/dist/transfer-service/markr/_schema.cjs +1 -1
- package/dist/transfer-service/markr/_schema.cjs.map +1 -1
- package/dist/transfer-service/markr/_schema.js +1 -1
- package/dist/transfer-service/markr/_schema.js.map +1 -1
- package/dist/transfer-service/markr/_utils.cjs +1 -1
- package/dist/transfer-service/markr/_utils.cjs.map +1 -1
- package/dist/transfer-service/markr/_utils.js +1 -1
- package/dist/transfer-service/markr/_utils.js.map +1 -1
- package/dist/transfer-service/markr/markr-service.cjs +1 -1
- package/dist/transfer-service/markr/markr-service.cjs.map +1 -1
- package/dist/transfer-service/markr/markr-service.js +1 -1
- package/dist/transfer-service/markr/markr-service.js.map +1 -1
- package/dist/types/service.d.cts +1 -0
- package/dist/types/service.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-transfer.cjs","names":["isSolanaNamespace","trackSameChainEvmTransfer","ErrorCode","getSolanaRpcForChain","SOLANA_TX_TIMEOUT_MS","waitForTimeoutOrAbort","SOLANA_POLLING_INTERVAL_MS","getErrorCodeForSolanaRpcError","isEvmNamespace","getEvmClientForChain","awaitOrAbort","getErrorCodeForViemError","markrGetCrossChainStatus"],"sources":["../../../../src/transfer-service/markr/_handlers/track-transfer.ts"],"sourcesContent":["import { assertIsSignature, type Signature } from '@solana/kit';\nimport { isHash } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode } from '../../../errors';\nimport type { TransferService, TrackTransferProps } from '../../../types/service';\nimport type {\n CompletedTransfer,\n FailedTransfer,\n SourceCompletedTransfer,\n SourcePendingTransfer,\n TargetPendingTransfer,\n Transfer,\n} from '../../../types/transfer';\nimport {\n awaitOrAbort,\n getErrorCodeForSolanaRpcError,\n getErrorCodeForViemError,\n getEvmClientForChain,\n getSolanaRpcForChain,\n waitForTimeoutOrAbort,\n} from '../../_utils';\nimport { trackSameChainEvmTransfer } from '../../_tracking-utilities';\nimport { markrGetCrossChainStatus, type ApiOptions } from '../_api';\nimport type { CrossChainStatusResponse } from '../_schema';\nimport { SOLANA_POLLING_INTERVAL_MS, SOLANA_TX_TIMEOUT_MS } from '../constants';\nimport type { Caip2ChainId } from '../../../mod';\n\nconst CROSS_CHAIN_POLLING_INTERVAL_MS = 3_000;\n\ntype InFlightTransfer = SourcePendingTransfer | SourceCompletedTransfer | TargetPendingTransfer;\n\nexport interface TrackTransferFactoryConfig {\n apiOptions: ApiOptions;\n}\n\nexport function trackTransferFactory({ apiOptions }: TrackTransferFactoryConfig): TransferService['trackTransfer'] {\n return ({ transfer, updateListener }) => {\n if (transfer.sourceChain.chainId === transfer.targetChain.chainId) {\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n return _trackSameChainSolanaTransfer({ transfer, updateListener });\n }\n return trackSameChainEvmTransfer({ transfer, updateListener });\n }\n\n return _trackCrossChainTransfer({ transfer, updateListener }, apiOptions);\n };\n}\n\nexport function _trackSameChainSolanaTransfer({ transfer, updateListener }: TrackTransferProps): {\n cancel: () => void;\n result: Promise<Transfer>;\n} {\n const ac = new AbortController();\n const cancel = () => ac.abort();\n\n if (transfer.status !== 'source-pending') {\n return { cancel, result: Promise.resolve(transfer) };\n }\n\n return { cancel, result: _pollSolanaSignatureStatus(transfer, updateListener, ac.signal) };\n}\n\nasync function _pollSolanaSignatureStatus(\n transfer: SourcePendingTransfer,\n updateListener: (transfer: Transfer) => void,\n signal: AbortSignal,\n): Promise<Transfer> {\n const { txHash } = transfer.source;\n\n try {\n assertIsSignature(txHash);\n } catch {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n const rpc = getSolanaRpcForChain({ chain: transfer.sourceChain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TIMEOUT,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const status = value[0];\n\n if (!status) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (status.err !== null) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n if (status.confirmationStatus === 'finalized') {\n const completed: CompletedTransfer = {\n ...transfer,\n completedAtMs: Date.now(),\n source: {\n ...transfer.source,\n confirmationCount: transfer.source.requiredConfirmationCount,\n },\n status: 'completed',\n target: null,\n };\n updateListener(completed);\n return completed;\n }\n\n const confirmations = Number(status.confirmations ?? 0);\n const cappedCount = Math.min(confirmations, transfer.source.requiredConfirmationCount - 1);\n\n if (cappedCount !== transfer.source.confirmationCount) {\n transfer = {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: cappedCount,\n },\n };\n updateListener(transfer);\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForSolanaRpcError(error),\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n }\n\n return transfer;\n}\n\nexport function _trackCrossChainTransfer(\n { transfer, updateListener }: TrackTransferProps,\n apiOptions: ApiOptions,\n): { cancel: () => void; result: Promise<Transfer> } {\n const ac = new AbortController();\n const cancel = () => {\n ac.abort();\n };\n\n const executeTracking = async (): Promise<Transfer> => {\n let currentTransfer: Transfer = structuredClone(transfer);\n while (!ac.signal.aborted) {\n const updatedTransfer = await _getMarkrCrossChainTxStatus(currentTransfer, apiOptions, ac.signal);\n\n if (ac.signal.aborted) {\n break;\n }\n\n currentTransfer = updatedTransfer;\n\n updateListener(updatedTransfer);\n\n if (updatedTransfer.status === 'completed' || updatedTransfer.status === 'failed') {\n return updatedTransfer;\n }\n\n // Wait before polling again.\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, CROSS_CHAIN_POLLING_INTERVAL_MS);\n ac.signal.addEventListener('abort', () => clearTimeout(timeoutId), { once: true });\n });\n }\n\n return currentTransfer;\n };\n\n return {\n cancel,\n result: executeTracking(),\n };\n}\n\nexport async function _getMarkrCrossChainTxStatus(\n transfer: Transfer,\n apiOptions: ApiOptions,\n signal: AbortSignal,\n): Promise<Transfer> {\n if (transfer.status === 'completed' || transfer.status === 'failed') {\n return transfer;\n }\n\n // We only support tracking EVM or Solana source transactions.\n if (!_isValidSourceTxHash(transfer.source.txHash, transfer.sourceChain.chainId)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n // If transfer is `source-pending`, we first confirm source-chain finality before\n // querying Markr's cross-chain status endpoint.\n // Once source finality is confirmed, we mark the transfer as source-completed and\n // defer Markr polling to subsequent iterations.\n if (transfer.status === 'source-pending') {\n if (isEvmNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n if (!isHash(sourceTxHash)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n const client = getEvmClientForChain({ chain: transfer.sourceChain });\n\n try {\n const receiptResult = await awaitOrAbort(\n client.waitForTransactionReceipt({\n hash: sourceTxHash,\n }),\n signal,\n );\n\n if (receiptResult.status === 'aborted') {\n return transfer;\n }\n\n const receipt = receiptResult.value;\n\n if (receipt.status === 'reverted') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Source transaction was reverted',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForEvmSourceFinalization(client, receipt.blockNumber, signal);\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n } catch (error) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForViemError(error),\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n }\n\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n try {\n assertIsSignature(sourceTxHash);\n } catch {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForSolanaSourceFinalization(transfer.sourceChain, sourceTxHash, signal);\n\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n if (finalityResult.status === 'failed') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: finalityResult.errorCode,\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n }\n }\n\n try {\n const statusResponse = await markrGetCrossChainStatus(apiOptions, transfer.source.txHash, { signal });\n\n switch (statusResponse.status) {\n case 'failed': {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Transaction execution failed.',\n failedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n case 'pending': {\n return _isMarkrSourceFinalized(statusResponse.sourceChain.finalized)\n ? _toSourceCompletedTransfer(transfer)\n : transfer;\n }\n\n case 'committed':\n case 'pending_execution': {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n case 'completed': {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n case 'unknown':\n default: {\n return _deriveTransferFromUnknownStatus(transfer, statusResponse);\n }\n }\n } catch (error) {\n // TODO: Clean this console.error up before v1 release.\n // This is just here for now to try to track down tracking issues.\n console.error('[Unified Asset Transfer] Error fetching cross-chain status from Markr API', {\n error,\n now: Date.now(),\n });\n\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.UNKNOWN,\n errorReason: 'Failed to fetch cross-chain tx status',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n}\n\nasync function _waitForEvmSourceFinalization(\n client: ReturnType<typeof getEvmClientForChain>,\n txBlockNumber: bigint,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' }> {\n while (!signal.aborted) {\n const finalizedBlockResult = await awaitOrAbort(client.getBlock({ blockTag: 'finalized' }), signal);\n\n if (finalizedBlockResult.status === 'aborted') {\n return { status: 'aborted' };\n }\n\n if (finalizedBlockResult.value.number >= txBlockNumber) {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({\n timeoutMs: CROSS_CHAIN_POLLING_INTERVAL_MS,\n signal,\n });\n }\n\n return { status: 'aborted' };\n}\n\nasync function _waitForSolanaSourceFinalization(\n chain: SourcePendingTransfer['sourceChain'],\n txHash: Signature,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' } | { status: 'failed'; errorCode: ErrorCode }> {\n const rpc = getSolanaRpcForChain({ chain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TIMEOUT,\n };\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const txStatus = value[0];\n\n if (!txStatus) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (txStatus.err !== null) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n };\n }\n\n if (txStatus.confirmationStatus === 'finalized') {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n return {\n status: 'failed',\n errorCode: getErrorCodeForSolanaRpcError(error),\n };\n }\n }\n\n return { status: 'aborted' };\n}\n\nfunction _isValidSourceTxHash(txHash: string, sourceChainId: Caip2ChainId): boolean {\n if (isEvmNamespace(sourceChainId)) {\n return isHash(txHash);\n }\n\n if (isSolanaNamespace(sourceChainId)) {\n try {\n assertIsSignature(txHash);\n return true;\n } catch {\n return false;\n }\n }\n\n return false;\n}\n\nfunction _isMarkrSourceFinalized(finalized: CrossChainStatusResponse['sourceChain']['finalized']): boolean {\n return finalized === true || typeof finalized === 'string';\n}\n\nfunction _toSourceCompletedTransfer(transfer: InFlightTransfer): SourceCompletedTransfer {\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'source-completed',\n };\n}\n\nfunction _toTargetPendingTransfer(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): TargetPendingTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'target-pending',\n target: {\n confirmationCount: transactionHash ? 1 : 0,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n txHash: transactionHash ?? undefined,\n },\n };\n}\n\nfunction _toCompletedTransfer(transfer: InFlightTransfer, statusResponse: CrossChainStatusResponse): CompletedTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n completedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'completed',\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n target: transactionHash\n ? {\n txHash: transactionHash,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n }\n : null,\n };\n}\n\nfunction _deriveTransferFromUnknownStatus(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): Transfer {\n if (statusResponse.progress.executed === true) {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n if (statusResponse.progress.committed === true) {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n if (_isMarkrSourceFinalized(statusResponse.sourceChain.finalized)) {\n return _toSourceCompletedTransfer(transfer);\n }\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 0,\n requiredConfirmationCount: 2,\n },\n status: 'source-pending',\n };\n}\n\nfunction _getLastStatusActivityTime(response: CrossChainStatusResponse): number {\n if (response.destinationChain.finalized) {\n return new Date(response.destinationChain.finalized).getTime();\n }\n\n if (response.destinationChain.timestamp) {\n return new Date(response.destinationChain.timestamp).getTime();\n }\n\n if (response.sourceChain.finalized) {\n if (typeof response.sourceChain.finalized === 'boolean' && response.sourceChain.finalized === true) {\n // Handle case where finalized is returned as boolean `true` instead of a timestamp.\n return new Date(response.sourceChain.timestamp).getTime();\n }\n return new Date(response.sourceChain.finalized).getTime();\n }\n\n return new Date(response.sourceChain.timestamp).getTime();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"track-transfer.cjs","names":["isSolanaNamespace","trackSameChainEvmTransfer","ErrorCode","getSolanaRpcForChain","SOLANA_TX_TIMEOUT_MS","waitForTimeoutOrAbort","SOLANA_POLLING_INTERVAL_MS","getErrorCodeForSolanaRpcError","isEvmNamespace","getEvmClientForChain","awaitOrAbort","getErrorCodeForViemError","markrGetCrossChainStatus"],"sources":["../../../../src/transfer-service/markr/_handlers/track-transfer.ts"],"sourcesContent":["import { assertIsSignature, type Signature } from '@solana/kit';\nimport { isHash } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode } from '../../../errors';\nimport type { TransferService, TrackTransferProps } from '../../../types/service';\nimport type {\n CompletedTransfer,\n FailedTransfer,\n SourceCompletedTransfer,\n SourcePendingTransfer,\n TargetPendingTransfer,\n Transfer,\n} from '../../../types/transfer';\nimport {\n awaitOrAbort,\n getErrorCodeForSolanaRpcError,\n getErrorCodeForViemError,\n getEvmClientForChain,\n getSolanaRpcForChain,\n waitForTimeoutOrAbort,\n} from '../../_utils';\nimport { trackSameChainEvmTransfer } from '../../_tracking-utilities';\nimport { markrGetCrossChainStatus, type ApiOptions } from '../_api';\nimport type { CrossChainStatusResponse } from '../_schema';\nimport { SOLANA_POLLING_INTERVAL_MS, SOLANA_TX_TIMEOUT_MS } from '../constants';\nimport type { Caip2ChainId } from '../../../mod';\n\nconst CROSS_CHAIN_POLLING_INTERVAL_MS = 3_000;\n\ntype InFlightTransfer = SourcePendingTransfer | SourceCompletedTransfer | TargetPendingTransfer;\n\nexport interface TrackTransferFactoryConfig {\n apiOptions: ApiOptions;\n}\n\nexport function trackTransferFactory({ apiOptions }: TrackTransferFactoryConfig): TransferService['trackTransfer'] {\n return ({ transfer, updateListener }) => {\n if (transfer.sourceChain.chainId === transfer.targetChain.chainId) {\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n return _trackSameChainSolanaTransfer({ transfer, updateListener });\n }\n return trackSameChainEvmTransfer({ transfer, updateListener });\n }\n\n return _trackCrossChainTransfer({ transfer, updateListener }, apiOptions);\n };\n}\n\nexport function _trackSameChainSolanaTransfer({ transfer, updateListener }: TrackTransferProps): {\n cancel: () => void;\n result: Promise<Transfer>;\n} {\n const ac = new AbortController();\n const cancel = () => ac.abort();\n\n if (transfer.status !== 'source-pending') {\n return { cancel, result: Promise.resolve(transfer) };\n }\n\n return { cancel, result: _pollSolanaSignatureStatus(transfer, updateListener, ac.signal) };\n}\n\nasync function _pollSolanaSignatureStatus(\n transfer: SourcePendingTransfer,\n updateListener: (transfer: Transfer) => void,\n signal: AbortSignal,\n): Promise<Transfer> {\n const { txHash } = transfer.source;\n\n try {\n assertIsSignature(txHash);\n } catch {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n const rpc = getSolanaRpcForChain({ chain: transfer.sourceChain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TIMEOUT,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const status = value[0];\n\n if (!status) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (status.err !== null) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n if (status.confirmationStatus === 'finalized') {\n const completed: CompletedTransfer = {\n ...transfer,\n completedAtMs: Date.now(),\n source: {\n ...transfer.source,\n confirmationCount: transfer.source.requiredConfirmationCount,\n },\n status: 'completed',\n target: null,\n };\n updateListener(completed);\n return completed;\n }\n\n const confirmations = Number(status.confirmations ?? 0);\n const cappedCount = Math.min(confirmations, transfer.source.requiredConfirmationCount - 1);\n\n if (cappedCount !== transfer.source.confirmationCount) {\n transfer = {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: cappedCount,\n },\n };\n updateListener(transfer);\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForSolanaRpcError(error),\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n }\n\n return transfer;\n}\n\nexport function _trackCrossChainTransfer(\n { transfer, updateListener }: TrackTransferProps,\n apiOptions: ApiOptions,\n): { cancel: () => void; result: Promise<Transfer> } {\n const ac = new AbortController();\n const cancel = () => {\n ac.abort();\n };\n\n const executeTracking = async (): Promise<Transfer> => {\n let currentTransfer: Transfer = structuredClone(transfer);\n while (!ac.signal.aborted) {\n const updatedTransfer = await _getMarkrCrossChainTxStatus(currentTransfer, apiOptions, ac.signal);\n\n if (ac.signal.aborted) {\n break;\n }\n\n currentTransfer = updatedTransfer;\n\n updateListener(updatedTransfer);\n\n if (updatedTransfer.status === 'completed' || updatedTransfer.status === 'failed') {\n return updatedTransfer;\n }\n\n // Wait before polling again.\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, CROSS_CHAIN_POLLING_INTERVAL_MS);\n ac.signal.addEventListener('abort', () => clearTimeout(timeoutId), { once: true });\n });\n }\n\n return currentTransfer;\n };\n\n return {\n cancel,\n result: executeTracking(),\n };\n}\n\nexport async function _getMarkrCrossChainTxStatus(\n transfer: Transfer,\n apiOptions: ApiOptions,\n signal: AbortSignal,\n): Promise<Transfer> {\n if (transfer.status === 'completed' || transfer.status === 'failed') {\n return transfer;\n }\n\n // We only support tracking EVM or Solana source transactions.\n if (!_isValidSourceTxHash(transfer.source.txHash, transfer.sourceChain.chainId)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n // If transfer is `source-pending`, we first confirm source-chain finality before\n // querying Markr's cross-chain status endpoint.\n // Once source finality is confirmed, we mark the transfer as source-completed and\n // defer Markr polling to subsequent iterations.\n if (transfer.status === 'source-pending') {\n if (isEvmNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n if (!isHash(sourceTxHash)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n const client = getEvmClientForChain({ chain: transfer.sourceChain });\n\n try {\n const receiptResult = await awaitOrAbort(\n client.waitForTransactionReceipt({\n hash: sourceTxHash,\n }),\n signal,\n );\n\n if (receiptResult.status === 'aborted') {\n return transfer;\n }\n\n const receipt = receiptResult.value;\n\n if (receipt.status === 'reverted') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Source transaction was reverted',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForEvmSourceFinalization(client, receipt.blockNumber, signal);\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n } catch (error) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForViemError(error),\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n }\n\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n try {\n assertIsSignature(sourceTxHash);\n } catch {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForSolanaSourceFinalization(transfer.sourceChain, sourceTxHash, signal);\n\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n if (finalityResult.status === 'failed') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: finalityResult.errorCode,\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n }\n }\n\n try {\n const statusResponse = await markrGetCrossChainStatus(apiOptions, transfer.source.txHash, { signal });\n const transferWithMarkrMetadata = _withMarkrTrackingMetadata(transfer, statusResponse);\n\n switch (statusResponse.status) {\n case 'failed': {\n const failedTransfer: FailedTransfer = {\n ...transferWithMarkrMetadata,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Transaction execution failed.',\n failedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n case 'pending': {\n return _isMarkrSourceFinalized(statusResponse.sourceChain.finalized)\n ? _toSourceCompletedTransfer(transferWithMarkrMetadata)\n : transferWithMarkrMetadata;\n }\n\n case 'committed':\n case 'pending_execution': {\n return _toTargetPendingTransfer(transferWithMarkrMetadata, statusResponse);\n }\n\n case 'completed': {\n return _toCompletedTransfer(transferWithMarkrMetadata, statusResponse);\n }\n\n case 'unknown':\n default: {\n return _deriveTransferFromUnknownStatus(transferWithMarkrMetadata, statusResponse);\n }\n }\n } catch (error) {\n // TODO: Clean this console.error up before v1 release.\n // This is just here for now to try to track down tracking issues.\n console.error('[Unified Asset Transfer] Error fetching cross-chain status from Markr API', {\n error,\n now: Date.now(),\n });\n\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.UNKNOWN,\n errorReason: 'Failed to fetch cross-chain tx status',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n}\n\nasync function _waitForEvmSourceFinalization(\n client: ReturnType<typeof getEvmClientForChain>,\n txBlockNumber: bigint,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' }> {\n while (!signal.aborted) {\n const finalizedBlockResult = await awaitOrAbort(client.getBlock({ blockTag: 'finalized' }), signal);\n\n if (finalizedBlockResult.status === 'aborted') {\n return { status: 'aborted' };\n }\n\n if (finalizedBlockResult.value.number >= txBlockNumber) {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({\n timeoutMs: CROSS_CHAIN_POLLING_INTERVAL_MS,\n signal,\n });\n }\n\n return { status: 'aborted' };\n}\n\nasync function _waitForSolanaSourceFinalization(\n chain: SourcePendingTransfer['sourceChain'],\n txHash: Signature,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' } | { status: 'failed'; errorCode: ErrorCode }> {\n const rpc = getSolanaRpcForChain({ chain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TIMEOUT,\n };\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const txStatus = value[0];\n\n if (!txStatus) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (txStatus.err !== null) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n };\n }\n\n if (txStatus.confirmationStatus === 'finalized') {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n return {\n status: 'failed',\n errorCode: getErrorCodeForSolanaRpcError(error),\n };\n }\n }\n\n return { status: 'aborted' };\n}\n\nfunction _isValidSourceTxHash(txHash: string, sourceChainId: Caip2ChainId): boolean {\n if (isEvmNamespace(sourceChainId)) {\n return isHash(txHash);\n }\n\n if (isSolanaNamespace(sourceChainId)) {\n try {\n assertIsSignature(txHash);\n return true;\n } catch {\n return false;\n }\n }\n\n return false;\n}\n\nfunction _isMarkrSourceFinalized(finalized: CrossChainStatusResponse['sourceChain']['finalized']): boolean {\n return finalized === true || typeof finalized === 'string';\n}\n\nfunction _toSourceCompletedTransfer(transfer: InFlightTransfer): SourceCompletedTransfer {\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'source-completed',\n };\n}\n\nfunction _withMarkrTrackingMetadata(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): InFlightTransfer {\n const metadata: Record<string, unknown> = { ...(transfer.metadata ?? {}) };\n\n if (statusResponse.destinationChain.bridgeHash) {\n metadata.bridgeHash = statusResponse.destinationChain.bridgeHash;\n }\n\n if (statusResponse.debug) {\n metadata.debug = statusResponse.debug;\n }\n\n if (Object.keys(metadata).length === 0) {\n return transfer;\n }\n\n return {\n ...transfer,\n metadata,\n };\n}\n\nfunction _toTargetPendingTransfer(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): TargetPendingTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'target-pending',\n target: {\n confirmationCount: transactionHash ? 1 : 0,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n txHash: transactionHash ?? undefined,\n },\n };\n}\n\nfunction _toCompletedTransfer(transfer: InFlightTransfer, statusResponse: CrossChainStatusResponse): CompletedTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n completedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'completed',\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n target: transactionHash\n ? {\n txHash: transactionHash,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n }\n : null,\n };\n}\n\nfunction _deriveTransferFromUnknownStatus(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): Transfer {\n if (statusResponse.progress.executed === true) {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n if (statusResponse.progress.committed === true) {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n if (_isMarkrSourceFinalized(statusResponse.sourceChain.finalized)) {\n return _toSourceCompletedTransfer(transfer);\n }\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 0,\n requiredConfirmationCount: 2,\n },\n status: 'source-pending',\n };\n}\n\nfunction _getLastStatusActivityTime(response: CrossChainStatusResponse): number {\n if (response.destinationChain.finalized) {\n return new Date(response.destinationChain.finalized).getTime();\n }\n\n if (response.destinationChain.timestamp) {\n return new Date(response.destinationChain.timestamp).getTime();\n }\n\n if (response.sourceChain.finalized) {\n if (typeof response.sourceChain.finalized === 'boolean' && response.sourceChain.finalized === true) {\n // Handle case where finalized is returned as boolean `true` instead of a timestamp.\n return new Date(response.sourceChain.timestamp).getTime();\n }\n return new Date(response.sourceChain.finalized).getTime();\n }\n\n return new Date(response.sourceChain.timestamp).getTime();\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ErrorCode as e}from"../../../errors.js";import{isEvmNamespace as t,isSolanaNamespace as n}from"../../../_utils/chain.js";import{awaitOrAbort as r,getErrorCodeForSolanaRpcError as i,getErrorCodeForViemError as a,getEvmClientForChain as o,getSolanaRpcForChain as s,waitForTimeoutOrAbort as c}from"../../_utils.js";import{markrGetCrossChainStatus as l}from"../_api.js";import{trackSameChainEvmTransfer as u}from"../../_tracking-utilities.js";import{SOLANA_POLLING_INTERVAL_MS as d,SOLANA_TX_TIMEOUT_MS as f}from"../constants.js";import{isHash as p}from"viem";import{assertIsSignature as m}from"@solana/kit";const h=3e3;function g({apiOptions:e}){return({transfer:t,updateListener:r})=>t.sourceChain.chainId===t.targetChain.chainId?n(t.sourceChain.chainId)?_({transfer:t,updateListener:r}):u({transfer:t,updateListener:r}):y({transfer:t,updateListener:r},e)}function _({transfer:e,updateListener:t}){let n=new AbortController,r=()=>n.abort();return e.status===`source-pending`?{cancel:r,result:v(e,t,n.signal)}:{cancel:r,result:Promise.resolve(e)}}async function v(t,n,r){let{txHash:a}=t.source;try{m(a)}catch{let r={...t,errorCode:e.INVALID_PARAMS,failedAtMs:Date.now(),status:`failed`};return n(r),r}let o=s({chain:t.sourceChain}),l=Date.now();for(;!r.aborted;){if(Date.now()-l>f){let r={...t,errorCode:e.TIMEOUT,failedAtMs:Date.now(),status:`failed`};return n(r),r}try{let{value:i}=await o.getSignatureStatuses([a],{searchTransactionHistory:!0}).send(),s=i[0];if(!s){await c({timeoutMs:d,signal:r});continue}if(s.err!==null){let r={...t,errorCode:e.TRANSACTION_REVERTED,failedAtMs:Date.now(),status:`failed`};return n(r),r}if(s.confirmationStatus===`finalized`){let e={...t,completedAtMs:Date.now(),source:{...t.source,confirmationCount:t.source.requiredConfirmationCount},status:`completed`,target:null};return n(e),e}let l=Number(s.confirmations??0),u=Math.min(l,t.source.requiredConfirmationCount-1);u!==t.source.confirmationCount&&(t={...t,source:{...t.source,confirmationCount:u}},n(t)),await c({timeoutMs:d,signal:r})}catch(e){let r={...t,errorCode:i(e),failedAtMs:Date.now(),status:`failed`};return n(r),r}}return t}function y({transfer:e,updateListener:t},n){let r=new AbortController;return{cancel:()=>{r.abort()},result:(async()=>{let i=structuredClone(e);for(;!r.signal.aborted;){let e=await b(i,n,r.signal);if(r.signal.aborted)break;if(i=e,t(e),e.status===`completed`||e.status===`failed`)return e;await new Promise(e=>{let t=setTimeout(e,h);r.signal.addEventListener(`abort`,()=>clearTimeout(t),{once:!0})})}return i})()}}async function b(i,s,c){if(i.status===`completed`||i.status===`failed`)return i;if(!C(i.source.txHash,i.sourceChain.chainId))return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};if(i.status===`source-pending`){if(t(i.sourceChain.chainId)){let t=i.source.txHash;if(!p(t))return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};let n=o({chain:i.sourceChain});try{let a=await r(n.waitForTransactionReceipt({hash:t}),c);if(a.status===`aborted`)return i;let o=a.value;return o.status===`reverted`?{...i,errorCode:e.TRANSACTION_REVERTED,errorReason:`Source transaction was reverted`,failedAtMs:Date.now(),status:`failed`}:(await x(n,o.blockNumber,c)).status===`aborted`?i:T(i)}catch(e){return{...i,errorCode:a(e),errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}}}if(n(i.sourceChain.chainId)){let t=i.source.txHash;try{m(t)}catch{return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`}}let n=await S(i.sourceChain,t,c);return n.status===`aborted`?i:n.status===`failed`?{...i,errorCode:n.errorCode,errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}:T(i)}}try{let t=await l(s,i.source.txHash,{signal:c});switch(t.status){case`failed`:return{...
|
|
1
|
+
import{ErrorCode as e}from"../../../errors.js";import{isEvmNamespace as t,isSolanaNamespace as n}from"../../../_utils/chain.js";import{awaitOrAbort as r,getErrorCodeForSolanaRpcError as i,getErrorCodeForViemError as a,getEvmClientForChain as o,getSolanaRpcForChain as s,waitForTimeoutOrAbort as c}from"../../_utils.js";import{markrGetCrossChainStatus as l}from"../_api.js";import{trackSameChainEvmTransfer as u}from"../../_tracking-utilities.js";import{SOLANA_POLLING_INTERVAL_MS as d,SOLANA_TX_TIMEOUT_MS as f}from"../constants.js";import{isHash as p}from"viem";import{assertIsSignature as m}from"@solana/kit";const h=3e3;function g({apiOptions:e}){return({transfer:t,updateListener:r})=>t.sourceChain.chainId===t.targetChain.chainId?n(t.sourceChain.chainId)?_({transfer:t,updateListener:r}):u({transfer:t,updateListener:r}):y({transfer:t,updateListener:r},e)}function _({transfer:e,updateListener:t}){let n=new AbortController,r=()=>n.abort();return e.status===`source-pending`?{cancel:r,result:v(e,t,n.signal)}:{cancel:r,result:Promise.resolve(e)}}async function v(t,n,r){let{txHash:a}=t.source;try{m(a)}catch{let r={...t,errorCode:e.INVALID_PARAMS,failedAtMs:Date.now(),status:`failed`};return n(r),r}let o=s({chain:t.sourceChain}),l=Date.now();for(;!r.aborted;){if(Date.now()-l>f){let r={...t,errorCode:e.TIMEOUT,failedAtMs:Date.now(),status:`failed`};return n(r),r}try{let{value:i}=await o.getSignatureStatuses([a],{searchTransactionHistory:!0}).send(),s=i[0];if(!s){await c({timeoutMs:d,signal:r});continue}if(s.err!==null){let r={...t,errorCode:e.TRANSACTION_REVERTED,failedAtMs:Date.now(),status:`failed`};return n(r),r}if(s.confirmationStatus===`finalized`){let e={...t,completedAtMs:Date.now(),source:{...t.source,confirmationCount:t.source.requiredConfirmationCount},status:`completed`,target:null};return n(e),e}let l=Number(s.confirmations??0),u=Math.min(l,t.source.requiredConfirmationCount-1);u!==t.source.confirmationCount&&(t={...t,source:{...t.source,confirmationCount:u}},n(t)),await c({timeoutMs:d,signal:r})}catch(e){let r={...t,errorCode:i(e),failedAtMs:Date.now(),status:`failed`};return n(r),r}}return t}function y({transfer:e,updateListener:t},n){let r=new AbortController;return{cancel:()=>{r.abort()},result:(async()=>{let i=structuredClone(e);for(;!r.signal.aborted;){let e=await b(i,n,r.signal);if(r.signal.aborted)break;if(i=e,t(e),e.status===`completed`||e.status===`failed`)return e;await new Promise(e=>{let t=setTimeout(e,h);r.signal.addEventListener(`abort`,()=>clearTimeout(t),{once:!0})})}return i})()}}async function b(i,s,c){if(i.status===`completed`||i.status===`failed`)return i;if(!C(i.source.txHash,i.sourceChain.chainId))return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};if(i.status===`source-pending`){if(t(i.sourceChain.chainId)){let t=i.source.txHash;if(!p(t))return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};let n=o({chain:i.sourceChain});try{let a=await r(n.waitForTransactionReceipt({hash:t}),c);if(a.status===`aborted`)return i;let o=a.value;return o.status===`reverted`?{...i,errorCode:e.TRANSACTION_REVERTED,errorReason:`Source transaction was reverted`,failedAtMs:Date.now(),status:`failed`}:(await x(n,o.blockNumber,c)).status===`aborted`?i:T(i)}catch(e){return{...i,errorCode:a(e),errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}}}if(n(i.sourceChain.chainId)){let t=i.source.txHash;try{m(t)}catch{return{...i,errorCode:e.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`}}let n=await S(i.sourceChain,t,c);return n.status===`aborted`?i:n.status===`failed`?{...i,errorCode:n.errorCode,errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}:T(i)}}try{let t=await l(s,i.source.txHash,{signal:c}),n=E(i,t);switch(t.status){case`failed`:return{...n,errorCode:e.TRANSACTION_REVERTED,errorReason:`Transaction execution failed.`,failedAtMs:A(t),status:`failed`};case`pending`:return w(t.sourceChain.finalized)?T(n):n;case`committed`:case`pending_execution`:return D(n,t);case`completed`:return O(n,t);default:return k(n,t)}}catch(t){return console.error(`[Unified Asset Transfer] Error fetching cross-chain status from Markr API`,{error:t,now:Date.now()}),{...i,errorCode:e.UNKNOWN,errorReason:`Failed to fetch cross-chain tx status`,failedAtMs:Date.now(),status:`failed`}}}async function x(e,t,n){for(;!n.aborted;){let i=await r(e.getBlock({blockTag:`finalized`}),n);if(i.status===`aborted`)return{status:`aborted`};if(i.value.number>=t)return{status:`ok`};await c({timeoutMs:h,signal:n})}return{status:`aborted`}}async function S(t,n,r){let a=s({chain:t}),o=Date.now();for(;!r.aborted;){if(Date.now()-o>f)return{status:`failed`,errorCode:e.TIMEOUT};try{let{value:t}=await a.getSignatureStatuses([n],{searchTransactionHistory:!0}).send(),i=t[0];if(!i){await c({timeoutMs:d,signal:r});continue}if(i.err!==null)return{status:`failed`,errorCode:e.TRANSACTION_REVERTED};if(i.confirmationStatus===`finalized`)return{status:`ok`};await c({timeoutMs:d,signal:r})}catch(e){return{status:`failed`,errorCode:i(e)}}}return{status:`aborted`}}function C(e,r){if(t(r))return p(e);if(n(r))try{return m(e),!0}catch{return!1}return!1}function w(e){return e===!0||typeof e==`string`}function T(e){return{...e,source:{...e.source,confirmationCount:2,requiredConfirmationCount:2},status:`source-completed`}}function E(e,t){let n={...e.metadata??{}};return t.destinationChain.bridgeHash&&(n.bridgeHash=t.destinationChain.bridgeHash),t.debug&&(n.debug=t.debug),Object.keys(n).length===0?e:{...e,metadata:n}}function D(e,t){let{timestamp:n,transactionHash:r}=t.destinationChain;return{...e,source:{...e.source,confirmationCount:2,requiredConfirmationCount:2},status:`target-pending`,target:{confirmationCount:r?1:0,requiredConfirmationCount:2,startedAtMs:n?new Date(n).getTime():Date.now(),txHash:r??void 0}}}function O(e,t){let{timestamp:n,transactionHash:r}=t.destinationChain;return{...e,completedAtMs:A(t),status:`completed`,source:{...e.source,confirmationCount:2,requiredConfirmationCount:2},target:r?{txHash:r,confirmationCount:2,requiredConfirmationCount:2,startedAtMs:n?new Date(n).getTime():Date.now()}:null}}function k(e,t){return t.progress.executed===!0?O(e,t):t.progress.committed===!0?D(e,t):w(t.sourceChain.finalized)?T(e):{...e,source:{...e.source,confirmationCount:0,requiredConfirmationCount:2},status:`source-pending`}}function A(e){return e.destinationChain.finalized?new Date(e.destinationChain.finalized).getTime():e.destinationChain.timestamp?new Date(e.destinationChain.timestamp).getTime():e.sourceChain.finalized?typeof e.sourceChain.finalized==`boolean`&&e.sourceChain.finalized===!0?new Date(e.sourceChain.timestamp).getTime():new Date(e.sourceChain.finalized).getTime():new Date(e.sourceChain.timestamp).getTime()}export{g as trackTransferFactory};
|
|
2
2
|
//# sourceMappingURL=track-transfer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-transfer.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/track-transfer.ts"],"sourcesContent":["import { assertIsSignature, type Signature } from '@solana/kit';\nimport { isHash } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode } from '../../../errors';\nimport type { TransferService, TrackTransferProps } from '../../../types/service';\nimport type {\n CompletedTransfer,\n FailedTransfer,\n SourceCompletedTransfer,\n SourcePendingTransfer,\n TargetPendingTransfer,\n Transfer,\n} from '../../../types/transfer';\nimport {\n awaitOrAbort,\n getErrorCodeForSolanaRpcError,\n getErrorCodeForViemError,\n getEvmClientForChain,\n getSolanaRpcForChain,\n waitForTimeoutOrAbort,\n} from '../../_utils';\nimport { trackSameChainEvmTransfer } from '../../_tracking-utilities';\nimport { markrGetCrossChainStatus, type ApiOptions } from '../_api';\nimport type { CrossChainStatusResponse } from '../_schema';\nimport { SOLANA_POLLING_INTERVAL_MS, SOLANA_TX_TIMEOUT_MS } from '../constants';\nimport type { Caip2ChainId } from '../../../mod';\n\nconst CROSS_CHAIN_POLLING_INTERVAL_MS = 3_000;\n\ntype InFlightTransfer = SourcePendingTransfer | SourceCompletedTransfer | TargetPendingTransfer;\n\nexport interface TrackTransferFactoryConfig {\n apiOptions: ApiOptions;\n}\n\nexport function trackTransferFactory({ apiOptions }: TrackTransferFactoryConfig): TransferService['trackTransfer'] {\n return ({ transfer, updateListener }) => {\n if (transfer.sourceChain.chainId === transfer.targetChain.chainId) {\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n return _trackSameChainSolanaTransfer({ transfer, updateListener });\n }\n return trackSameChainEvmTransfer({ transfer, updateListener });\n }\n\n return _trackCrossChainTransfer({ transfer, updateListener }, apiOptions);\n };\n}\n\nexport function _trackSameChainSolanaTransfer({ transfer, updateListener }: TrackTransferProps): {\n cancel: () => void;\n result: Promise<Transfer>;\n} {\n const ac = new AbortController();\n const cancel = () => ac.abort();\n\n if (transfer.status !== 'source-pending') {\n return { cancel, result: Promise.resolve(transfer) };\n }\n\n return { cancel, result: _pollSolanaSignatureStatus(transfer, updateListener, ac.signal) };\n}\n\nasync function _pollSolanaSignatureStatus(\n transfer: SourcePendingTransfer,\n updateListener: (transfer: Transfer) => void,\n signal: AbortSignal,\n): Promise<Transfer> {\n const { txHash } = transfer.source;\n\n try {\n assertIsSignature(txHash);\n } catch {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n const rpc = getSolanaRpcForChain({ chain: transfer.sourceChain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TIMEOUT,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const status = value[0];\n\n if (!status) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (status.err !== null) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n if (status.confirmationStatus === 'finalized') {\n const completed: CompletedTransfer = {\n ...transfer,\n completedAtMs: Date.now(),\n source: {\n ...transfer.source,\n confirmationCount: transfer.source.requiredConfirmationCount,\n },\n status: 'completed',\n target: null,\n };\n updateListener(completed);\n return completed;\n }\n\n const confirmations = Number(status.confirmations ?? 0);\n const cappedCount = Math.min(confirmations, transfer.source.requiredConfirmationCount - 1);\n\n if (cappedCount !== transfer.source.confirmationCount) {\n transfer = {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: cappedCount,\n },\n };\n updateListener(transfer);\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForSolanaRpcError(error),\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n }\n\n return transfer;\n}\n\nexport function _trackCrossChainTransfer(\n { transfer, updateListener }: TrackTransferProps,\n apiOptions: ApiOptions,\n): { cancel: () => void; result: Promise<Transfer> } {\n const ac = new AbortController();\n const cancel = () => {\n ac.abort();\n };\n\n const executeTracking = async (): Promise<Transfer> => {\n let currentTransfer: Transfer = structuredClone(transfer);\n while (!ac.signal.aborted) {\n const updatedTransfer = await _getMarkrCrossChainTxStatus(currentTransfer, apiOptions, ac.signal);\n\n if (ac.signal.aborted) {\n break;\n }\n\n currentTransfer = updatedTransfer;\n\n updateListener(updatedTransfer);\n\n if (updatedTransfer.status === 'completed' || updatedTransfer.status === 'failed') {\n return updatedTransfer;\n }\n\n // Wait before polling again.\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, CROSS_CHAIN_POLLING_INTERVAL_MS);\n ac.signal.addEventListener('abort', () => clearTimeout(timeoutId), { once: true });\n });\n }\n\n return currentTransfer;\n };\n\n return {\n cancel,\n result: executeTracking(),\n };\n}\n\nexport async function _getMarkrCrossChainTxStatus(\n transfer: Transfer,\n apiOptions: ApiOptions,\n signal: AbortSignal,\n): Promise<Transfer> {\n if (transfer.status === 'completed' || transfer.status === 'failed') {\n return transfer;\n }\n\n // We only support tracking EVM or Solana source transactions.\n if (!_isValidSourceTxHash(transfer.source.txHash, transfer.sourceChain.chainId)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n // If transfer is `source-pending`, we first confirm source-chain finality before\n // querying Markr's cross-chain status endpoint.\n // Once source finality is confirmed, we mark the transfer as source-completed and\n // defer Markr polling to subsequent iterations.\n if (transfer.status === 'source-pending') {\n if (isEvmNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n if (!isHash(sourceTxHash)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n const client = getEvmClientForChain({ chain: transfer.sourceChain });\n\n try {\n const receiptResult = await awaitOrAbort(\n client.waitForTransactionReceipt({\n hash: sourceTxHash,\n }),\n signal,\n );\n\n if (receiptResult.status === 'aborted') {\n return transfer;\n }\n\n const receipt = receiptResult.value;\n\n if (receipt.status === 'reverted') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Source transaction was reverted',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForEvmSourceFinalization(client, receipt.blockNumber, signal);\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n } catch (error) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForViemError(error),\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n }\n\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n try {\n assertIsSignature(sourceTxHash);\n } catch {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForSolanaSourceFinalization(transfer.sourceChain, sourceTxHash, signal);\n\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n if (finalityResult.status === 'failed') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: finalityResult.errorCode,\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n }\n }\n\n try {\n const statusResponse = await markrGetCrossChainStatus(apiOptions, transfer.source.txHash, { signal });\n\n switch (statusResponse.status) {\n case 'failed': {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Transaction execution failed.',\n failedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n case 'pending': {\n return _isMarkrSourceFinalized(statusResponse.sourceChain.finalized)\n ? _toSourceCompletedTransfer(transfer)\n : transfer;\n }\n\n case 'committed':\n case 'pending_execution': {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n case 'completed': {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n case 'unknown':\n default: {\n return _deriveTransferFromUnknownStatus(transfer, statusResponse);\n }\n }\n } catch (error) {\n // TODO: Clean this console.error up before v1 release.\n // This is just here for now to try to track down tracking issues.\n console.error('[Unified Asset Transfer] Error fetching cross-chain status from Markr API', {\n error,\n now: Date.now(),\n });\n\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.UNKNOWN,\n errorReason: 'Failed to fetch cross-chain tx status',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n}\n\nasync function _waitForEvmSourceFinalization(\n client: ReturnType<typeof getEvmClientForChain>,\n txBlockNumber: bigint,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' }> {\n while (!signal.aborted) {\n const finalizedBlockResult = await awaitOrAbort(client.getBlock({ blockTag: 'finalized' }), signal);\n\n if (finalizedBlockResult.status === 'aborted') {\n return { status: 'aborted' };\n }\n\n if (finalizedBlockResult.value.number >= txBlockNumber) {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({\n timeoutMs: CROSS_CHAIN_POLLING_INTERVAL_MS,\n signal,\n });\n }\n\n return { status: 'aborted' };\n}\n\nasync function _waitForSolanaSourceFinalization(\n chain: SourcePendingTransfer['sourceChain'],\n txHash: Signature,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' } | { status: 'failed'; errorCode: ErrorCode }> {\n const rpc = getSolanaRpcForChain({ chain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TIMEOUT,\n };\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const txStatus = value[0];\n\n if (!txStatus) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (txStatus.err !== null) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n };\n }\n\n if (txStatus.confirmationStatus === 'finalized') {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n return {\n status: 'failed',\n errorCode: getErrorCodeForSolanaRpcError(error),\n };\n }\n }\n\n return { status: 'aborted' };\n}\n\nfunction _isValidSourceTxHash(txHash: string, sourceChainId: Caip2ChainId): boolean {\n if (isEvmNamespace(sourceChainId)) {\n return isHash(txHash);\n }\n\n if (isSolanaNamespace(sourceChainId)) {\n try {\n assertIsSignature(txHash);\n return true;\n } catch {\n return false;\n }\n }\n\n return false;\n}\n\nfunction _isMarkrSourceFinalized(finalized: CrossChainStatusResponse['sourceChain']['finalized']): boolean {\n return finalized === true || typeof finalized === 'string';\n}\n\nfunction _toSourceCompletedTransfer(transfer: InFlightTransfer): SourceCompletedTransfer {\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'source-completed',\n };\n}\n\nfunction _toTargetPendingTransfer(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): TargetPendingTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'target-pending',\n target: {\n confirmationCount: transactionHash ? 1 : 0,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n txHash: transactionHash ?? undefined,\n },\n };\n}\n\nfunction _toCompletedTransfer(transfer: InFlightTransfer, statusResponse: CrossChainStatusResponse): CompletedTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n completedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'completed',\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n target: transactionHash\n ? {\n txHash: transactionHash,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n }\n : null,\n };\n}\n\nfunction _deriveTransferFromUnknownStatus(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): Transfer {\n if (statusResponse.progress.executed === true) {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n if (statusResponse.progress.committed === true) {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n if (_isMarkrSourceFinalized(statusResponse.sourceChain.finalized)) {\n return _toSourceCompletedTransfer(transfer);\n }\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 0,\n requiredConfirmationCount: 2,\n },\n status: 'source-pending',\n };\n}\n\nfunction _getLastStatusActivityTime(response: CrossChainStatusResponse): number {\n if (response.destinationChain.finalized) {\n return new Date(response.destinationChain.finalized).getTime();\n }\n\n if (response.destinationChain.timestamp) {\n return new Date(response.destinationChain.timestamp).getTime();\n }\n\n if (response.sourceChain.finalized) {\n if (typeof response.sourceChain.finalized === 'boolean' && response.sourceChain.finalized === true) {\n // Handle case where finalized is returned as boolean `true` instead of a timestamp.\n return new Date(response.sourceChain.timestamp).getTime();\n }\n return new Date(response.sourceChain.finalized).getTime();\n }\n\n return new Date(response.sourceChain.timestamp).getTime();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"track-transfer.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/track-transfer.ts"],"sourcesContent":["import { assertIsSignature, type Signature } from '@solana/kit';\nimport { isHash } from 'viem';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode } from '../../../errors';\nimport type { TransferService, TrackTransferProps } from '../../../types/service';\nimport type {\n CompletedTransfer,\n FailedTransfer,\n SourceCompletedTransfer,\n SourcePendingTransfer,\n TargetPendingTransfer,\n Transfer,\n} from '../../../types/transfer';\nimport {\n awaitOrAbort,\n getErrorCodeForSolanaRpcError,\n getErrorCodeForViemError,\n getEvmClientForChain,\n getSolanaRpcForChain,\n waitForTimeoutOrAbort,\n} from '../../_utils';\nimport { trackSameChainEvmTransfer } from '../../_tracking-utilities';\nimport { markrGetCrossChainStatus, type ApiOptions } from '../_api';\nimport type { CrossChainStatusResponse } from '../_schema';\nimport { SOLANA_POLLING_INTERVAL_MS, SOLANA_TX_TIMEOUT_MS } from '../constants';\nimport type { Caip2ChainId } from '../../../mod';\n\nconst CROSS_CHAIN_POLLING_INTERVAL_MS = 3_000;\n\ntype InFlightTransfer = SourcePendingTransfer | SourceCompletedTransfer | TargetPendingTransfer;\n\nexport interface TrackTransferFactoryConfig {\n apiOptions: ApiOptions;\n}\n\nexport function trackTransferFactory({ apiOptions }: TrackTransferFactoryConfig): TransferService['trackTransfer'] {\n return ({ transfer, updateListener }) => {\n if (transfer.sourceChain.chainId === transfer.targetChain.chainId) {\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n return _trackSameChainSolanaTransfer({ transfer, updateListener });\n }\n return trackSameChainEvmTransfer({ transfer, updateListener });\n }\n\n return _trackCrossChainTransfer({ transfer, updateListener }, apiOptions);\n };\n}\n\nexport function _trackSameChainSolanaTransfer({ transfer, updateListener }: TrackTransferProps): {\n cancel: () => void;\n result: Promise<Transfer>;\n} {\n const ac = new AbortController();\n const cancel = () => ac.abort();\n\n if (transfer.status !== 'source-pending') {\n return { cancel, result: Promise.resolve(transfer) };\n }\n\n return { cancel, result: _pollSolanaSignatureStatus(transfer, updateListener, ac.signal) };\n}\n\nasync function _pollSolanaSignatureStatus(\n transfer: SourcePendingTransfer,\n updateListener: (transfer: Transfer) => void,\n signal: AbortSignal,\n): Promise<Transfer> {\n const { txHash } = transfer.source;\n\n try {\n assertIsSignature(txHash);\n } catch {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n const rpc = getSolanaRpcForChain({ chain: transfer.sourceChain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TIMEOUT,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const status = value[0];\n\n if (!status) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (status.err !== null) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n\n if (status.confirmationStatus === 'finalized') {\n const completed: CompletedTransfer = {\n ...transfer,\n completedAtMs: Date.now(),\n source: {\n ...transfer.source,\n confirmationCount: transfer.source.requiredConfirmationCount,\n },\n status: 'completed',\n target: null,\n };\n updateListener(completed);\n return completed;\n }\n\n const confirmations = Number(status.confirmations ?? 0);\n const cappedCount = Math.min(confirmations, transfer.source.requiredConfirmationCount - 1);\n\n if (cappedCount !== transfer.source.confirmationCount) {\n transfer = {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: cappedCount,\n },\n };\n updateListener(transfer);\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n const failed: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForSolanaRpcError(error),\n failedAtMs: Date.now(),\n status: 'failed',\n };\n updateListener(failed);\n return failed;\n }\n }\n\n return transfer;\n}\n\nexport function _trackCrossChainTransfer(\n { transfer, updateListener }: TrackTransferProps,\n apiOptions: ApiOptions,\n): { cancel: () => void; result: Promise<Transfer> } {\n const ac = new AbortController();\n const cancel = () => {\n ac.abort();\n };\n\n const executeTracking = async (): Promise<Transfer> => {\n let currentTransfer: Transfer = structuredClone(transfer);\n while (!ac.signal.aborted) {\n const updatedTransfer = await _getMarkrCrossChainTxStatus(currentTransfer, apiOptions, ac.signal);\n\n if (ac.signal.aborted) {\n break;\n }\n\n currentTransfer = updatedTransfer;\n\n updateListener(updatedTransfer);\n\n if (updatedTransfer.status === 'completed' || updatedTransfer.status === 'failed') {\n return updatedTransfer;\n }\n\n // Wait before polling again.\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, CROSS_CHAIN_POLLING_INTERVAL_MS);\n ac.signal.addEventListener('abort', () => clearTimeout(timeoutId), { once: true });\n });\n }\n\n return currentTransfer;\n };\n\n return {\n cancel,\n result: executeTracking(),\n };\n}\n\nexport async function _getMarkrCrossChainTxStatus(\n transfer: Transfer,\n apiOptions: ApiOptions,\n signal: AbortSignal,\n): Promise<Transfer> {\n if (transfer.status === 'completed' || transfer.status === 'failed') {\n return transfer;\n }\n\n // We only support tracking EVM or Solana source transactions.\n if (!_isValidSourceTxHash(transfer.source.txHash, transfer.sourceChain.chainId)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n // If transfer is `source-pending`, we first confirm source-chain finality before\n // querying Markr's cross-chain status endpoint.\n // Once source finality is confirmed, we mark the transfer as source-completed and\n // defer Markr polling to subsequent iterations.\n if (transfer.status === 'source-pending') {\n if (isEvmNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n if (!isHash(sourceTxHash)) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n const client = getEvmClientForChain({ chain: transfer.sourceChain });\n\n try {\n const receiptResult = await awaitOrAbort(\n client.waitForTransactionReceipt({\n hash: sourceTxHash,\n }),\n signal,\n );\n\n if (receiptResult.status === 'aborted') {\n return transfer;\n }\n\n const receipt = receiptResult.value;\n\n if (receipt.status === 'reverted') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Source transaction was reverted',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForEvmSourceFinalization(client, receipt.blockNumber, signal);\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n } catch (error) {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: getErrorCodeForViemError(error),\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n }\n\n if (isSolanaNamespace(transfer.sourceChain.chainId)) {\n const sourceTxHash = transfer.source.txHash;\n\n try {\n assertIsSignature(sourceTxHash);\n } catch {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.INVALID_PARAMS,\n errorReason: 'Invalid source transaction hash',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n const finalityResult = await _waitForSolanaSourceFinalization(transfer.sourceChain, sourceTxHash, signal);\n\n if (finalityResult.status === 'aborted') {\n return transfer;\n }\n\n if (finalityResult.status === 'failed') {\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: finalityResult.errorCode,\n errorReason: 'Failed to confirm source transaction finality',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n\n return _toSourceCompletedTransfer(transfer);\n }\n }\n\n try {\n const statusResponse = await markrGetCrossChainStatus(apiOptions, transfer.source.txHash, { signal });\n const transferWithMarkrMetadata = _withMarkrTrackingMetadata(transfer, statusResponse);\n\n switch (statusResponse.status) {\n case 'failed': {\n const failedTransfer: FailedTransfer = {\n ...transferWithMarkrMetadata,\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n errorReason: 'Transaction execution failed.',\n failedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'failed',\n };\n\n return failedTransfer;\n }\n\n case 'pending': {\n return _isMarkrSourceFinalized(statusResponse.sourceChain.finalized)\n ? _toSourceCompletedTransfer(transferWithMarkrMetadata)\n : transferWithMarkrMetadata;\n }\n\n case 'committed':\n case 'pending_execution': {\n return _toTargetPendingTransfer(transferWithMarkrMetadata, statusResponse);\n }\n\n case 'completed': {\n return _toCompletedTransfer(transferWithMarkrMetadata, statusResponse);\n }\n\n case 'unknown':\n default: {\n return _deriveTransferFromUnknownStatus(transferWithMarkrMetadata, statusResponse);\n }\n }\n } catch (error) {\n // TODO: Clean this console.error up before v1 release.\n // This is just here for now to try to track down tracking issues.\n console.error('[Unified Asset Transfer] Error fetching cross-chain status from Markr API', {\n error,\n now: Date.now(),\n });\n\n const failedTransfer: FailedTransfer = {\n ...transfer,\n errorCode: ErrorCode.UNKNOWN,\n errorReason: 'Failed to fetch cross-chain tx status',\n failedAtMs: Date.now(),\n status: 'failed',\n };\n return failedTransfer;\n }\n}\n\nasync function _waitForEvmSourceFinalization(\n client: ReturnType<typeof getEvmClientForChain>,\n txBlockNumber: bigint,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' }> {\n while (!signal.aborted) {\n const finalizedBlockResult = await awaitOrAbort(client.getBlock({ blockTag: 'finalized' }), signal);\n\n if (finalizedBlockResult.status === 'aborted') {\n return { status: 'aborted' };\n }\n\n if (finalizedBlockResult.value.number >= txBlockNumber) {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({\n timeoutMs: CROSS_CHAIN_POLLING_INTERVAL_MS,\n signal,\n });\n }\n\n return { status: 'aborted' };\n}\n\nasync function _waitForSolanaSourceFinalization(\n chain: SourcePendingTransfer['sourceChain'],\n txHash: Signature,\n signal: AbortSignal,\n): Promise<{ status: 'aborted' } | { status: 'ok' } | { status: 'failed'; errorCode: ErrorCode }> {\n const rpc = getSolanaRpcForChain({ chain });\n const startTime = Date.now();\n\n while (!signal.aborted) {\n if (Date.now() - startTime > SOLANA_TX_TIMEOUT_MS) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TIMEOUT,\n };\n }\n\n try {\n const { value } = await rpc.getSignatureStatuses([txHash], { searchTransactionHistory: true }).send();\n const txStatus = value[0];\n\n if (!txStatus) {\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n continue;\n }\n\n if (txStatus.err !== null) {\n return {\n status: 'failed',\n errorCode: ErrorCode.TRANSACTION_REVERTED,\n };\n }\n\n if (txStatus.confirmationStatus === 'finalized') {\n return { status: 'ok' };\n }\n\n await waitForTimeoutOrAbort({ timeoutMs: SOLANA_POLLING_INTERVAL_MS, signal });\n } catch (error) {\n return {\n status: 'failed',\n errorCode: getErrorCodeForSolanaRpcError(error),\n };\n }\n }\n\n return { status: 'aborted' };\n}\n\nfunction _isValidSourceTxHash(txHash: string, sourceChainId: Caip2ChainId): boolean {\n if (isEvmNamespace(sourceChainId)) {\n return isHash(txHash);\n }\n\n if (isSolanaNamespace(sourceChainId)) {\n try {\n assertIsSignature(txHash);\n return true;\n } catch {\n return false;\n }\n }\n\n return false;\n}\n\nfunction _isMarkrSourceFinalized(finalized: CrossChainStatusResponse['sourceChain']['finalized']): boolean {\n return finalized === true || typeof finalized === 'string';\n}\n\nfunction _toSourceCompletedTransfer(transfer: InFlightTransfer): SourceCompletedTransfer {\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'source-completed',\n };\n}\n\nfunction _withMarkrTrackingMetadata(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): InFlightTransfer {\n const metadata: Record<string, unknown> = { ...(transfer.metadata ?? {}) };\n\n if (statusResponse.destinationChain.bridgeHash) {\n metadata.bridgeHash = statusResponse.destinationChain.bridgeHash;\n }\n\n if (statusResponse.debug) {\n metadata.debug = statusResponse.debug;\n }\n\n if (Object.keys(metadata).length === 0) {\n return transfer;\n }\n\n return {\n ...transfer,\n metadata,\n };\n}\n\nfunction _toTargetPendingTransfer(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): TargetPendingTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n status: 'target-pending',\n target: {\n confirmationCount: transactionHash ? 1 : 0,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n txHash: transactionHash ?? undefined,\n },\n };\n}\n\nfunction _toCompletedTransfer(transfer: InFlightTransfer, statusResponse: CrossChainStatusResponse): CompletedTransfer {\n const { timestamp, transactionHash } = statusResponse.destinationChain;\n\n return {\n ...transfer,\n completedAtMs: _getLastStatusActivityTime(statusResponse),\n status: 'completed',\n source: {\n ...transfer.source,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n },\n target: transactionHash\n ? {\n txHash: transactionHash,\n confirmationCount: 2,\n requiredConfirmationCount: 2,\n startedAtMs: timestamp ? new Date(timestamp).getTime() : Date.now(),\n }\n : null,\n };\n}\n\nfunction _deriveTransferFromUnknownStatus(\n transfer: InFlightTransfer,\n statusResponse: CrossChainStatusResponse,\n): Transfer {\n if (statusResponse.progress.executed === true) {\n return _toCompletedTransfer(transfer, statusResponse);\n }\n\n if (statusResponse.progress.committed === true) {\n return _toTargetPendingTransfer(transfer, statusResponse);\n }\n\n if (_isMarkrSourceFinalized(statusResponse.sourceChain.finalized)) {\n return _toSourceCompletedTransfer(transfer);\n }\n\n return {\n ...transfer,\n source: {\n ...transfer.source,\n confirmationCount: 0,\n requiredConfirmationCount: 2,\n },\n status: 'source-pending',\n };\n}\n\nfunction _getLastStatusActivityTime(response: CrossChainStatusResponse): number {\n if (response.destinationChain.finalized) {\n return new Date(response.destinationChain.finalized).getTime();\n }\n\n if (response.destinationChain.timestamp) {\n return new Date(response.destinationChain.timestamp).getTime();\n }\n\n if (response.sourceChain.finalized) {\n if (typeof response.sourceChain.finalized === 'boolean' && response.sourceChain.finalized === true) {\n // Handle case where finalized is returned as boolean `true` instead of a timestamp.\n return new Date(response.sourceChain.timestamp).getTime();\n }\n return new Date(response.sourceChain.finalized).getTime();\n }\n\n return new Date(response.sourceChain.timestamp).getTime();\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../utils/caip.cjs`),t=require(`../service-schemas.cjs`);let n=require(`zod`);const r=n.z.string().refine(t=>e.isCaip2ChainId(t),{message:`Invalid CAIP-2 chain ID`}).transform(e=>e),i=n.z.object({chainId:n.z.union([n.z.number(),n.z.string()]),chainType:n.z.string(),enabled_services:n.z.array(n.z.enum([`cross-chain-swap`,`cross-chain-quote`,`quote`,`swap`,`token-list`])),logo_url:n.z.url(),name:n.z.string(),lanes:n.z.array(n.z.union([n.z.coerce.number().int().nonnegative(),r]))}),a=i.extend({chainId:n.z.coerce.number().int().nonnegative(),chainType:n.z.literal(`evm`),router:t.EvmAddressSchema.optional(),wrapped_token:t.EvmAddressSchema.optional()}),o=i.extend({chainId:n.z.string().refine(t=>e.isCaip2ChainId(t)&&t.startsWith(`solana:`),{error:`Is not a valid Solana CAIP-2 ID`}).transform(e=>e),chainType:n.z.literal(`svm`)}),s=n.z.array(n.z.union([a,o,i.refine(e=>e.chainType!==`evm`&&e.chainType!==`svm`,`Known chain types must match their expected schema`)])),c=n.z.array(n.z.object({address:t.EvmAddressSchema,decimals:n.z.number().int().nonnegative().max(18),logo_url:n.z.url(),name:n.z.string(),symbol:n.z.string()})),l=n.z.union([n.z.object({aggregator:n.z.object({id:n.z.string(),logo_url:n.z.url(),name:n.z.string()}),amountIn:n.z.coerce.bigint().nonnegative(),amountOut:n.z.coerce.bigint().nonnegative(),chainId:n.z.union([n.z.number().int().nonnegative(),r]),expiredAt:n.z.number().int().nonnegative(),fees:n.z.array(n.z.object({type:n.z.enum([`protocol`,`gas`,`bridge`,`slippage`,`swap`,`other`]),name:n.z.string(),amount:n.z.coerce.bigint().nonnegative(),token:n.z.object({chainId:n.z.union([n.z.number().int().nonnegative(),r]),address:n.z.union([t.EvmAddressSchema,t.SolAddressSchema])})})).optional(),gasEstimate:n.z.coerce.bigint().nonnegative().optional(),recommendedSlippage:n.z.number().int().nonnegative(),tokenIn:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),tokenInDecimals:n.z.number().int().nonnegative().max(18),tokenOut:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),tokenOutDecimals:n.z.number().int().nonnegative().max(18),uuid:n.z.uuid()}),n.z.object({done:n.z.literal(!0)})]),u=n.z.object({data:t.HexSchema,to:t.EvmAddressSchema,value:n.z.coerce.bigint().nonnegative()}),d=n.z.object({chainType:n.z.literal(`svm`),swapTransaction:n.z.base64()}),f=n.z.union([u,d]),p=n.z.object({fee:n.z.int().nonnegative(),name:n.z.string()}),m=/[zZ]|[+-]\d{2}:?\d{2}$/,h=n.z.iso.datetime({local:!0}).refine(e=>{let t=m.test(e)?e:e+`Z`;return n.z.iso.datetime().safeParse(t).success},{error:`Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)`}).transform(e=>m.test(e)?e:e+`Z`),g=n.z.object({messageId:n.z.string().nullable(),status:n.z.enum([`pending`,`committed`,`pending_execution`,`completed`,`failed`,`unknown`]),description:n.z.string(),sourceChain:n.z.object({name:n.z.string(),transactionHash:n.z.union([t.HashSchema,t.SolSignatureSchema]),timestamp:h,finalized:h.or(n.z.boolean()).nullable()}),destinationChain:n.z.object({name:n.z.string().nullable(),transactionHash:n.z.union([t.HashSchema,t.SolSignatureSchema]).nullable(),timestamp:h.nullable(),finalized:h.nullable()}),progress:n.z.object({committed:n.z.boolean(),commitTimestamp:h.nullable().optional(),executed:n.z.boolean()}),fees:n.z.object({token:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]).nullable(),amount:n.z.coerce.bigint().nonnegative().nullable()}),transferredTokens:n.z.array(n.z.object({token:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),amount:n.z.coerce.bigint().nonnegative()}))}),_=n.z.object({address:t.EvmAddressSchema});exports.CrossChainStatusResponseSchema=g,exports.PartnerInfoResponseSchema=p,exports.QuoteResponseSchema=l,exports.SpenderAddressResponseSchema=_,exports.SupportedChainsResponseSchema=s,exports.SwapResponseSchema=f,exports.TokenListResponseSchema=c;
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../utils/caip.cjs`),t=require(`../service-schemas.cjs`);let n=require(`zod`);const r=n.z.string().refine(t=>e.isCaip2ChainId(t),{message:`Invalid CAIP-2 chain ID`}).transform(e=>e),i=n.z.object({chainId:n.z.union([n.z.number(),n.z.string()]),chainType:n.z.string(),enabled_services:n.z.array(n.z.enum([`cross-chain-swap`,`cross-chain-quote`,`quote`,`swap`,`token-list`])),logo_url:n.z.url(),name:n.z.string(),lanes:n.z.array(n.z.union([n.z.coerce.number().int().nonnegative(),r]))}),a=i.extend({chainId:n.z.coerce.number().int().nonnegative(),chainType:n.z.literal(`evm`),router:t.EvmAddressSchema.optional(),wrapped_token:t.EvmAddressSchema.optional()}),o=i.extend({chainId:n.z.string().refine(t=>e.isCaip2ChainId(t)&&t.startsWith(`solana:`),{error:`Is not a valid Solana CAIP-2 ID`}).transform(e=>e),chainType:n.z.literal(`svm`)}),s=n.z.array(n.z.union([a,o,i.refine(e=>e.chainType!==`evm`&&e.chainType!==`svm`,`Known chain types must match their expected schema`)])),c=n.z.array(n.z.object({address:t.EvmAddressSchema,decimals:n.z.number().int().nonnegative().max(18),logo_url:n.z.url(),name:n.z.string(),symbol:n.z.string()})),l=n.z.union([n.z.object({aggregator:n.z.object({id:n.z.string(),logo_url:n.z.url(),name:n.z.string()}),amountIn:n.z.coerce.bigint().nonnegative(),amountOut:n.z.coerce.bigint().nonnegative(),chainId:n.z.union([n.z.number().int().nonnegative(),r]),expiredAt:n.z.number().int().nonnegative(),fees:n.z.array(n.z.object({type:n.z.enum([`protocol`,`gas`,`bridge`,`slippage`,`swap`,`other`]),name:n.z.string(),amount:n.z.coerce.bigint().nonnegative(),token:n.z.object({chainId:n.z.union([n.z.number().int().nonnegative(),r]),address:n.z.union([t.EvmAddressSchema,t.SolAddressSchema])})})).optional(),gasEstimate:n.z.coerce.bigint().nonnegative().optional(),recommendedSlippage:n.z.number().int().nonnegative(),tokenIn:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),tokenInDecimals:n.z.number().int().nonnegative().max(18),tokenOut:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),tokenOutDecimals:n.z.number().int().nonnegative().max(18),uuid:n.z.uuid()}),n.z.object({done:n.z.literal(!0)})]),u=n.z.object({data:t.HexSchema,to:t.EvmAddressSchema,value:n.z.coerce.bigint().nonnegative()}),d=n.z.object({chainType:n.z.literal(`svm`),swapTransaction:n.z.base64()}),f=n.z.union([u,d]),p=n.z.object({fee:n.z.int().nonnegative(),name:n.z.string()}),m=/[zZ]|[+-]\d{2}:?\d{2}$/,h=n.z.iso.datetime({local:!0}).refine(e=>{let t=m.test(e)?e:e+`Z`;return n.z.iso.datetime().safeParse(t).success},{error:`Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)`}).transform(e=>m.test(e)?e:e+`Z`),g=n.z.object({messageId:n.z.string().nullable(),status:n.z.enum([`pending`,`committed`,`pending_execution`,`completed`,`failed`,`unknown`]),description:n.z.string(),sourceChain:n.z.object({name:n.z.string(),transactionHash:n.z.union([t.HashSchema,t.SolSignatureSchema]),timestamp:h,finalized:h.or(n.z.boolean()).nullable()}),destinationChain:n.z.object({name:n.z.string().nullable(),transactionHash:n.z.union([t.HashSchema,t.SolSignatureSchema]).nullable(),bridgeHash:n.z.union([t.HashSchema,t.SolSignatureSchema]).nullable().optional(),timestamp:h.nullable(),finalized:h.nullable()}),progress:n.z.object({committed:n.z.boolean(),commitTimestamp:h.nullable().optional(),executed:n.z.boolean()}),fees:n.z.object({token:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]).nullable(),amount:n.z.coerce.bigint().nonnegative().nullable()}),transferredTokens:n.z.array(n.z.object({token:n.z.union([t.EvmAddressSchema,t.SolAddressSchema]),amount:n.z.coerce.bigint().nonnegative()})),debug:n.z.looseObject({messageId:n.z.string(),status:n.z.string(),destinationChain:n.z.string(),destinationTxHash:n.z.string(),relayTxHash:n.z.string(),retryCount:n.z.number().int().nonnegative(),lastRetryAt:n.z.iso.datetime(),sourceChain:n.z.string(),sourceTxHash:n.z.string(),createdAt:n.z.iso.datetime()}).nullable().optional()}),_=n.z.object({address:t.EvmAddressSchema});exports.CrossChainStatusResponseSchema=g,exports.PartnerInfoResponseSchema=p,exports.QuoteResponseSchema=l,exports.SpenderAddressResponseSchema=_,exports.SupportedChainsResponseSchema=s,exports.SwapResponseSchema=f,exports.TokenListResponseSchema=c;
|
|
2
2
|
//# sourceMappingURL=_schema.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_schema.cjs","names":["z","isCaip2ChainId","EvmAddressSchema","SolAddressSchema","HexSchema","HashSchema","SolSignatureSchema"],"sources":["../../../src/transfer-service/markr/_schema.ts"],"sourcesContent":["import type { Signature, Address as SolAddress } from '@solana/kit';\nimport { z } from 'zod';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { EvmAddressSchema, HashSchema, HexSchema, SolAddressSchema, SolSignatureSchema } from '../service-schemas';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\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';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\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\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']),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n }),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: z.union([EvmAddressSchema, SolAddressSchema]),\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\nexport type SwapResponse = WrappedSwapTransactionResponse | SolanaSwapTransactionResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\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 /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /** CCIP message ID */\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 /** Destination chain transaction hash (null if not yet executed) */\n transactionHash: 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 };\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\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', '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 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.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n }),\n transferredTokens: z.array(\n z.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]),\n amount: z.coerce.bigint().nonnegative(),\n }),\n ),\n});\n\nexport interface SpenderAddressResponse {\n address: EvmAddress;\n}\n\nexport const SpenderAddressResponseSchema: z.ZodType<SpenderAddressResponse> = z.object({\n address: EvmAddressSchema,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_schema.cjs","names":["z","isCaip2ChainId","EvmAddressSchema","SolAddressSchema","HexSchema","HashSchema","SolSignatureSchema"],"sources":["../../../src/transfer-service/markr/_schema.ts"],"sourcesContent":["import type { Signature, Address as SolAddress } from '@solana/kit';\nimport { z } from 'zod';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { EvmAddressSchema, HashSchema, HexSchema, SolAddressSchema, SolSignatureSchema } from '../service-schemas';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\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';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\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\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']),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n }),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: z.union([EvmAddressSchema, SolAddressSchema]),\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\nexport type SwapResponse = WrappedSwapTransactionResponse | SolanaSwapTransactionResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\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 /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /** CCIP message ID */\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 };\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?: {\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', '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.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n }),\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 .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":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{isCaip2ChainId as e}from"../../utils/caip.js";import{EvmAddressSchema as t,HashSchema as n,HexSchema as r,SolAddressSchema as i,SolSignatureSchema as a}from"../service-schemas.js";import{z as o}from"zod";const s=o.string().refine(t=>e(t),{message:`Invalid CAIP-2 chain ID`}).transform(e=>e),c=o.object({chainId:o.union([o.number(),o.string()]),chainType:o.string(),enabled_services:o.array(o.enum([`cross-chain-swap`,`cross-chain-quote`,`quote`,`swap`,`token-list`])),logo_url:o.url(),name:o.string(),lanes:o.array(o.union([o.coerce.number().int().nonnegative(),s]))}),l=c.extend({chainId:o.coerce.number().int().nonnegative(),chainType:o.literal(`evm`),router:t.optional(),wrapped_token:t.optional()}),u=c.extend({chainId:o.string().refine(t=>e(t)&&t.startsWith(`solana:`),{error:`Is not a valid Solana CAIP-2 ID`}).transform(e=>e),chainType:o.literal(`svm`)}),d=o.array(o.union([l,u,c.refine(e=>e.chainType!==`evm`&&e.chainType!==`svm`,`Known chain types must match their expected schema`)])),f=o.array(o.object({address:t,decimals:o.number().int().nonnegative().max(18),logo_url:o.url(),name:o.string(),symbol:o.string()})),p=o.union([o.object({aggregator:o.object({id:o.string(),logo_url:o.url(),name:o.string()}),amountIn:o.coerce.bigint().nonnegative(),amountOut:o.coerce.bigint().nonnegative(),chainId:o.union([o.number().int().nonnegative(),s]),expiredAt:o.number().int().nonnegative(),fees:o.array(o.object({type:o.enum([`protocol`,`gas`,`bridge`,`slippage`,`swap`,`other`]),name:o.string(),amount:o.coerce.bigint().nonnegative(),token:o.object({chainId:o.union([o.number().int().nonnegative(),s]),address:o.union([t,i])})})).optional(),gasEstimate:o.coerce.bigint().nonnegative().optional(),recommendedSlippage:o.number().int().nonnegative(),tokenIn:o.union([t,i]),tokenInDecimals:o.number().int().nonnegative().max(18),tokenOut:o.union([t,i]),tokenOutDecimals:o.number().int().nonnegative().max(18),uuid:o.uuid()}),o.object({done:o.literal(!0)})]),m=o.object({data:r,to:t,value:o.coerce.bigint().nonnegative()}),h=o.object({chainType:o.literal(`svm`),swapTransaction:o.base64()}),g=o.union([m,h]),_=o.object({fee:o.int().nonnegative(),name:o.string()}),v=/[zZ]|[+-]\d{2}:?\d{2}$/,y=o.iso.datetime({local:!0}).refine(e=>{let t=v.test(e)?e:e+`Z`;return o.iso.datetime().safeParse(t).success},{error:`Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)`}).transform(e=>v.test(e)?e:e+`Z`),b=o.object({messageId:o.string().nullable(),status:o.enum([`pending`,`committed`,`pending_execution`,`completed`,`failed`,`unknown`]),description:o.string(),sourceChain:o.object({name:o.string(),transactionHash:o.union([n,a]),timestamp:y,finalized:y.or(o.boolean()).nullable()}),destinationChain:o.object({name:o.string().nullable(),transactionHash:o.union([n,a]).nullable(),timestamp:y.nullable(),finalized:y.nullable()}),progress:o.object({committed:o.boolean(),commitTimestamp:y.nullable().optional(),executed:o.boolean()}),fees:o.object({token:o.union([t,i]).nullable(),amount:o.coerce.bigint().nonnegative().nullable()}),transferredTokens:o.array(o.object({token:o.union([t,i]),amount:o.coerce.bigint().nonnegative()}))}),x=o.object({address:t});export{b as CrossChainStatusResponseSchema,_ as PartnerInfoResponseSchema,p as QuoteResponseSchema,x as SpenderAddressResponseSchema,d as SupportedChainsResponseSchema,g as SwapResponseSchema,f as TokenListResponseSchema};
|
|
1
|
+
import{isCaip2ChainId as e}from"../../utils/caip.js";import{EvmAddressSchema as t,HashSchema as n,HexSchema as r,SolAddressSchema as i,SolSignatureSchema as a}from"../service-schemas.js";import{z as o}from"zod";const s=o.string().refine(t=>e(t),{message:`Invalid CAIP-2 chain ID`}).transform(e=>e),c=o.object({chainId:o.union([o.number(),o.string()]),chainType:o.string(),enabled_services:o.array(o.enum([`cross-chain-swap`,`cross-chain-quote`,`quote`,`swap`,`token-list`])),logo_url:o.url(),name:o.string(),lanes:o.array(o.union([o.coerce.number().int().nonnegative(),s]))}),l=c.extend({chainId:o.coerce.number().int().nonnegative(),chainType:o.literal(`evm`),router:t.optional(),wrapped_token:t.optional()}),u=c.extend({chainId:o.string().refine(t=>e(t)&&t.startsWith(`solana:`),{error:`Is not a valid Solana CAIP-2 ID`}).transform(e=>e),chainType:o.literal(`svm`)}),d=o.array(o.union([l,u,c.refine(e=>e.chainType!==`evm`&&e.chainType!==`svm`,`Known chain types must match their expected schema`)])),f=o.array(o.object({address:t,decimals:o.number().int().nonnegative().max(18),logo_url:o.url(),name:o.string(),symbol:o.string()})),p=o.union([o.object({aggregator:o.object({id:o.string(),logo_url:o.url(),name:o.string()}),amountIn:o.coerce.bigint().nonnegative(),amountOut:o.coerce.bigint().nonnegative(),chainId:o.union([o.number().int().nonnegative(),s]),expiredAt:o.number().int().nonnegative(),fees:o.array(o.object({type:o.enum([`protocol`,`gas`,`bridge`,`slippage`,`swap`,`other`]),name:o.string(),amount:o.coerce.bigint().nonnegative(),token:o.object({chainId:o.union([o.number().int().nonnegative(),s]),address:o.union([t,i])})})).optional(),gasEstimate:o.coerce.bigint().nonnegative().optional(),recommendedSlippage:o.number().int().nonnegative(),tokenIn:o.union([t,i]),tokenInDecimals:o.number().int().nonnegative().max(18),tokenOut:o.union([t,i]),tokenOutDecimals:o.number().int().nonnegative().max(18),uuid:o.uuid()}),o.object({done:o.literal(!0)})]),m=o.object({data:r,to:t,value:o.coerce.bigint().nonnegative()}),h=o.object({chainType:o.literal(`svm`),swapTransaction:o.base64()}),g=o.union([m,h]),_=o.object({fee:o.int().nonnegative(),name:o.string()}),v=/[zZ]|[+-]\d{2}:?\d{2}$/,y=o.iso.datetime({local:!0}).refine(e=>{let t=v.test(e)?e:e+`Z`;return o.iso.datetime().safeParse(t).success},{error:`Invalid ISO-8601 datetime (must be valid with timezone, or local assumed UTC)`}).transform(e=>v.test(e)?e:e+`Z`),b=o.object({messageId:o.string().nullable(),status:o.enum([`pending`,`committed`,`pending_execution`,`completed`,`failed`,`unknown`]),description:o.string(),sourceChain:o.object({name:o.string(),transactionHash:o.union([n,a]),timestamp:y,finalized:y.or(o.boolean()).nullable()}),destinationChain:o.object({name:o.string().nullable(),transactionHash:o.union([n,a]).nullable(),bridgeHash:o.union([n,a]).nullable().optional(),timestamp:y.nullable(),finalized:y.nullable()}),progress:o.object({committed:o.boolean(),commitTimestamp:y.nullable().optional(),executed:o.boolean()}),fees:o.object({token:o.union([t,i]).nullable(),amount:o.coerce.bigint().nonnegative().nullable()}),transferredTokens:o.array(o.object({token:o.union([t,i]),amount:o.coerce.bigint().nonnegative()})),debug:o.looseObject({messageId:o.string(),status:o.string(),destinationChain:o.string(),destinationTxHash:o.string(),relayTxHash:o.string(),retryCount:o.number().int().nonnegative(),lastRetryAt:o.iso.datetime(),sourceChain:o.string(),sourceTxHash:o.string(),createdAt:o.iso.datetime()}).nullable().optional()}),x=o.object({address:t});export{b as CrossChainStatusResponseSchema,_ as PartnerInfoResponseSchema,p as QuoteResponseSchema,x as SpenderAddressResponseSchema,d as SupportedChainsResponseSchema,g as SwapResponseSchema,f as TokenListResponseSchema};
|
|
2
2
|
//# sourceMappingURL=_schema.js.map
|
|
@@ -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 { z } from 'zod';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { EvmAddressSchema, HashSchema, HexSchema, SolAddressSchema, SolSignatureSchema } from '../service-schemas';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\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';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\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\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']),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n }),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: z.union([EvmAddressSchema, SolAddressSchema]),\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\nexport type SwapResponse = WrappedSwapTransactionResponse | SolanaSwapTransactionResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\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 /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /** CCIP message ID */\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 /** Destination chain transaction hash (null if not yet executed) */\n transactionHash: 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 };\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\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', '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 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.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n }),\n transferredTokens: z.array(\n z.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]),\n amount: z.coerce.bigint().nonnegative(),\n }),\n ),\n});\n\nexport interface SpenderAddressResponse {\n address: EvmAddress;\n}\n\nexport const SpenderAddressResponseSchema: z.ZodType<SpenderAddressResponse> = z.object({\n address: EvmAddressSchema,\n});\n"],"mappings":"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"}
|
|
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 { z } from 'zod';\nimport type { Address as EvmAddress, Hash } from 'viem';\nimport { EvmAddressSchema, HashSchema, HexSchema, SolAddressSchema, SolSignatureSchema } from '../service-schemas';\nimport { isCaip2ChainId } from '../../utils/caip';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Hex } from '../../types/signer';\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';\n /** Human-readable fee name */\n name: string;\n /** Fee amount in token's smallest unit */\n amount: bigint;\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\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']),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n }),\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: z.union([EvmAddressSchema, SolAddressSchema]),\n tokenInDecimals: z.number().int().nonnegative().max(18),\n tokenOut: z.union([EvmAddressSchema, SolAddressSchema]),\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\nexport type SwapResponse = WrappedSwapTransactionResponse | SolanaSwapTransactionResponse;\n\nexport const SwapResponseSchema: z.ZodType<SwapResponse> = z.union([\n WrappedSwapTransactionResponseSchema,\n SolanaSwapTransactionResponseSchema,\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 /** Execution failed */\n | 'failed'\n /** Unknown state */\n | 'unknown';\n\nexport interface CrossChainStatusResponse {\n /** CCIP message ID */\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 };\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?: {\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', '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.object({\n token: z.union([EvmAddressSchema, SolAddressSchema]).nullable(),\n amount: z.coerce.bigint().nonnegative().nullable(),\n }),\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 .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":"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"}
|
|
@@ -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/evm-address.cjs`),i=require(`../../_utils/chain.cjs`),a=require(`./_api.cjs`),o=require(`../../_utils/math.cjs`),s=require(`../../utils/sol-address.cjs`);let c=require(`viem`);async function l(e){let
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../constants.cjs`),t=require(`../../errors.cjs`),n=require(`../../utils/caip.cjs`),r=require(`../../utils/evm-address.cjs`),i=require(`../../_utils/chain.cjs`),a=require(`./_api.cjs`),o=require(`../../_utils/math.cjs`),s=require(`../../utils/sol-address.cjs`);let c=require(`viem`);async function l(e,r=!1){let i=new Map;try{let t=(await a.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 u(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=a.markrGetTokenList(e,i.chainId);n.set(r,t)}catch{}return n}function d(t){return t===e.ERC_ZERO_ADDRESS||t===e.SOL_MINT_ADDRESS}function f(t,n){return t.type===e.TokenType.NATIVE?i.isSolanaNamespace(n)?e.SOL_MINT_ADDRESS:e.ERC_ZERO_ADDRESS:t.address}function p({amountOut:e,assetOut:t,slippageBps:n}){let r=o.calculateMinimumAmountOut({amountOut:e,assetOut:t,slippageBps:n});return e>0n&&r===0n?1n:r}function m(t,n,r){let i=t.amountOut*BigInt(r)/10000n,a=t.amountOut-i,o=[...g(t.fees),{type:`partner`,name:`Core Fee`,amount:i,chainId:n.targetChain.chainId,token:_(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 h(e){try{return(await a.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 g(t){if(!t)return[];let i=[];for(let a of t){let t=typeof a.token.chainId==`number`?n.eip155ChainIdToCaip2(a.token.chainId):a.token.chainId,o;d(a.token.address)?o={type:e.TokenType.NATIVE}:r.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&&i.push({type:a.type,name:a.name,amount:a.amount,chainId:t,token:o})}return i}function _(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 v(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}function y(e){if(e instanceof c.BaseError){let t=e.data;if((0,c.isHex)(t))return t;let n;if(e.walk(e=>{let t=e.data;return!n&&(0,c.isHex)(t)&&(n=t),!1}),n)return n;let r=e.cause?.data;if((0,c.isHex)(r))return r}if(!e||typeof e!=`object`)return;let t=e;if((0,c.isHex)(t.data))return t.data;if((0,c.isHex)(t.error?.data))return t.error.data;if((0,c.isHex)(t.cause?.data))return t.cause.data;if((0,c.isHex)(t.response?.data))return t.response.data;if((0,c.isHex)(t.body?.error?.data))return t.body.error.data}function b(e,t){let n=y(t);if(!n)return null;try{let t=(0,c.decodeErrorResult)({abi:e,data:n}),r=t.args.length>0?`(${t.args.map(String).join(`, `)})`:`()`;return`${t.errorName}${r}`}catch{let t=n.slice(0,10).toLowerCase();for(let n of e)if(n.type===`error`&&(0,c.toFunctionSelector)(`${n.name}(${n.inputs.map(e=>e.type).join(`,`)})`).toLowerCase()===t)return`${n.name}()`}return null}exports.assetToAddressString=f,exports.calculateMarkrMinimumAmountOut=p,exports.decodeMarkrRevertError=b,exports.getMarkrSwapWrapperAbi=v,exports.getPartnerFeeBps=h,exports.getSupportedChains=l,exports.getSupportedTokens=u,exports.isTokenAddressNative=d,exports.quoteFromMarkrQuoteResponseData=m;
|
|
2
2
|
//# sourceMappingURL=_utils.cjs.map
|