@avalabs/fusion-sdk 0.3.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.
Files changed (33) hide show
  1. package/dist/transfer-manager.cjs +1 -1
  2. package/dist/transfer-manager.cjs.map +1 -1
  3. package/dist/transfer-manager.js +1 -1
  4. package/dist/transfer-manager.js.map +1 -1
  5. package/dist/transfer-service/markr/_api.cjs.map +1 -1
  6. package/dist/transfer-service/markr/_api.js.map +1 -1
  7. package/dist/transfer-service/markr/_handlers/analyze-support.cjs +1 -1
  8. package/dist/transfer-service/markr/_handlers/analyze-support.cjs.map +1 -1
  9. package/dist/transfer-service/markr/_handlers/analyze-support.js +1 -1
  10. package/dist/transfer-service/markr/_handlers/analyze-support.js.map +1 -1
  11. package/dist/transfer-service/markr/_handlers/stream-quotes.cjs +1 -1
  12. package/dist/transfer-service/markr/_handlers/stream-quotes.cjs.map +1 -1
  13. package/dist/transfer-service/markr/_handlers/stream-quotes.js +1 -1
  14. package/dist/transfer-service/markr/_handlers/stream-quotes.js.map +1 -1
  15. package/dist/transfer-service/markr/_handlers/track-transfer.cjs +1 -1
  16. package/dist/transfer-service/markr/_handlers/track-transfer.cjs.map +1 -1
  17. package/dist/transfer-service/markr/_handlers/track-transfer.js +1 -1
  18. package/dist/transfer-service/markr/_handlers/track-transfer.js.map +1 -1
  19. package/dist/transfer-service/markr/_schema.cjs +1 -1
  20. package/dist/transfer-service/markr/_schema.cjs.map +1 -1
  21. package/dist/transfer-service/markr/_schema.js +1 -1
  22. package/dist/transfer-service/markr/_schema.js.map +1 -1
  23. package/dist/transfer-service/markr/_utils.cjs +1 -1
  24. package/dist/transfer-service/markr/_utils.cjs.map +1 -1
  25. package/dist/transfer-service/markr/_utils.js +1 -1
  26. package/dist/transfer-service/markr/_utils.js.map +1 -1
  27. package/dist/transfer-service/markr/markr-service.cjs +1 -1
  28. package/dist/transfer-service/markr/markr-service.cjs.map +1 -1
  29. package/dist/transfer-service/markr/markr-service.js +1 -1
  30. package/dist/transfer-service/markr/markr-service.js.map +1 -1
  31. package/dist/types/service.d.cts +1 -0
  32. package/dist/types/service.d.ts +1 -0
  33. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- const e=require(`./constants.cjs`),t=require(`./errors.cjs`),n=require(`./type-guards.cjs`),r=require(`./quoter/quoter.cjs`),i=require(`./utils/caip.cjs`),a=require(`./_utils/merge-assets.cjs`),o=e=>{if(!n.isEnvironment(e))throw new t.ServiceInitializationError(t.ErrorReason.ENVIRONMENT_NOT_SUPPORTED)},s=e=>{if(e.length===0)throw new t.ServiceInitializationError(`No service initializers provided.`);if(e.some(e=>!n.isServiceInitializer(e)))throw new t.ServiceInitializationError(`One or more service initializers are invalid.`);let r=new Set;for(let n of e){if(r.has(n.type))throw new t.ServiceInitializationError(t.ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${n.type}" has been initialized more than once.`);r.add(n.type)}},c=async({environment:n,serviceInitializers:r,fetch:i})=>{let a=new Map,o={},s=(e,n)=>{if(n instanceof t.ServiceInitializationError)return n;let r=n instanceof Error?n.message:String(n);return new t.ServiceInitializationError(t.ErrorReason.UNKNOWN,`Failed to initialize service type "${e}". ${r}`,n)},c=async(e,t)=>{try{let n=await t();a.set(e,n),o[e]={status:`initialized`}}catch(t){o[e]={status:`error`,error:s(e,t)}}};for(let s of r){if(a.has(s.type))throw new t.ServiceInitializationError(t.ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${s.type}" has been initialized more than once.`);switch(s.type){case e.ServiceType.AVALANCHE_EVM:await c(e.ServiceType.AVALANCHE_EVM,async()=>{let{createAvalancheEvmService:e}=await Promise.resolve().then(()=>require(`./transfer-service/avalanche-evm/avalanche-evm-service.cjs`));return await e({environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.LOMBARD_BTCB_TO_BTC:await c(e.ServiceType.LOMBARD_BTCB_TO_BTC,async()=>{let{createBtcbToBtcService:e}=await Promise.resolve().then(()=>require(`./transfer-service/lombard/btcb-to-btc-service.cjs`));return await e({bitcoinFunctions:s.btcFunctions,environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.LOMBARD_BTC_TO_BTCB:await c(e.ServiceType.LOMBARD_BTC_TO_BTCB,async()=>{let{createBtcToBtcbService:e}=await Promise.resolve().then(()=>require(`./transfer-service/lombard/btc-to-btcb-service.cjs`));return await e({bitcoinFunctions:s.btcFunctions,btcSigner:s.btcSigner,environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.MARKR:if(n!==e.Environment.PROD){o[e.ServiceType.MARKR]={status:`unsupported-environment`,message:`Service type "${e.ServiceType.MARKR}" is only supported in production environment.`};break}await c(e.ServiceType.MARKR,async()=>{let{createMarkrService:e}=await Promise.resolve().then(()=>require(`./transfer-service/markr/markr-service.cjs`));return await e({apiBaseUrl:s.markrApiUrl,apiToken:s.markrApiToken,appId:s.markrAppId,fetch:i,environment:n,evmSigner:s.evmSigner,solanaSigner:s.solanaSigner})});break;case e.ServiceType.WRAP_UNWRAP:await c(e.ServiceType.WRAP_UNWRAP,async()=>{let{createWrapUnwrapService:e}=await Promise.resolve().then(()=>require(`./transfer-service/wrap-unwrap/wrap-unwrap-service.cjs`));return await e({environment:n,evmSigner:s.evmSigner,fetch:i})});break;default:break}}return{services:a,status:{environment:n,services:o}}},l=async e=>{let t=[];for(let n of e.values()){let e=await n.getAssets();t.push(e)}return a.mergeChainAssetMaps(t)},u=async({environment:n,fetch:a,serviceInitializers:u})=>{o(n),s(u);let{services:d,status:f}=await c({environment:n,serviceInitializers:u,fetch:a});return{id:crypto.randomUUID(),estimateNativeFee:async(e,n)=>{let r=Math.floor(Date.now()/1e3);if(e.expiresAt<=r){let n=r-e.expiresAt;throw new t.InvalidParamsError(t.ErrorReason.QUOTE_EXPIRED,`Quote expired ${n} seconds ago.`)}let i=d.get(e.serviceType);if(!i)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return await i.estimateNativeFee(e,n)},getAssetBridgeMap:async({sourceAsset:t,sourceChainId:n})=>{let r=await l(d),a=r[n];if(!a)return null;let o=a.find(n=>t.type===e.TokenType.NATIVE?n.type===e.TokenType.NATIVE:n.type===t.type&&n.address===t.address);if(!o||!o.destinations)return null;let s=o.destinations,c={};for(let[t,n]of Object.entries(s)){if(!i.isCaip2ChainId(t))continue;let a=r[t];if(!a)continue;let o=a.find(t=>n.address===e.TokenType.NATIVE?t.type===e.TokenType.NATIVE:t.type!==e.TokenType.NATIVE&&t.address===n.address);if(!o)continue;let{destinations:s,swapProviders:l,...u}=o;c[t]={bridgedAsset:u,bridgeProviders:n.bridgeProviders}}return Object.keys(c).length>0?c:null},getMinimumTransferAmount:async e=>{let t={};for(let n of d.values())if(n.analyzeSupport(e)){let r=await n.getMinimumTransferAmount(e);t[n.type]=r}return Object.keys(t).length>0?t:null},getSupportedChains:async()=>{let e=new Map,t=await Promise.all(Array.from(d.values()).map(e=>e.getSupportedChains()));for(let n of t)for(let[t,r]of n.entries()){let n=e.get(t);n||(n=new Set,e.set(t,n));for(let e of r)n.add(e)}return e},getQuoter:(e,t)=>new r.Quoter(e,Array.from(d.values()),t),status:()=>f,trackTransfer:e=>{let{transfer:n}=e,r=d.get(n.type);if(!r)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return r.trackTransfer(e)},transferAsset:async e=>{let{quote:n}=e,r=d.get(n.serviceType);if(!r)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return await r.transferAsset(e)}}};exports.createTransferManager=u;
1
+ const e=require(`./constants.cjs`),t=require(`./errors.cjs`),n=require(`./type-guards.cjs`),r=require(`./quoter/quoter.cjs`),i=require(`./utils/caip.cjs`),a=require(`./_utils/merge-assets.cjs`),o=e=>{if(!n.isEnvironment(e))throw new t.ServiceInitializationError(t.ErrorReason.ENVIRONMENT_NOT_SUPPORTED)},s=e=>{if(e.length===0)throw new t.ServiceInitializationError(`No service initializers provided.`);if(e.some(e=>!n.isServiceInitializer(e)))throw new t.ServiceInitializationError(`One or more service initializers are invalid.`);let r=new Set;for(let n of e){if(r.has(n.type))throw new t.ServiceInitializationError(t.ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${n.type}" has been initialized more than once.`);r.add(n.type)}},c=async({environment:n,serviceInitializers:r,fetch:i})=>{let a=new Map,o={},s=(e,n)=>{if(n instanceof t.ServiceInitializationError)return n;let r=n instanceof Error?n.message:String(n);return new t.ServiceInitializationError(t.ErrorReason.UNKNOWN,`Failed to initialize service type "${e}". ${r}`,n)},c=async(e,t)=>{try{let n=await t();a.set(e,n),o[e]={status:`initialized`}}catch(t){o[e]={status:`error`,error:s(e,t)}}};for(let s of r){if(a.has(s.type))throw new t.ServiceInitializationError(t.ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${s.type}" has been initialized more than once.`);switch(s.type){case e.ServiceType.AVALANCHE_EVM:await c(e.ServiceType.AVALANCHE_EVM,async()=>{let{createAvalancheEvmService:e}=await Promise.resolve().then(()=>require(`./transfer-service/avalanche-evm/avalanche-evm-service.cjs`));return await e({environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.LOMBARD_BTCB_TO_BTC:await c(e.ServiceType.LOMBARD_BTCB_TO_BTC,async()=>{let{createBtcbToBtcService:e}=await Promise.resolve().then(()=>require(`./transfer-service/lombard/btcb-to-btc-service.cjs`));return await e({bitcoinFunctions:s.btcFunctions,environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.LOMBARD_BTC_TO_BTCB:await c(e.ServiceType.LOMBARD_BTC_TO_BTCB,async()=>{let{createBtcToBtcbService:e}=await Promise.resolve().then(()=>require(`./transfer-service/lombard/btc-to-btcb-service.cjs`));return await e({bitcoinFunctions:s.btcFunctions,btcSigner:s.btcSigner,environment:n,evmSigner:s.evmSigner,fetch:i})});break;case e.ServiceType.MARKR:if(n!==e.Environment.PROD){o[e.ServiceType.MARKR]={status:`unsupported-environment`,message:`Service type "${e.ServiceType.MARKR}" is only supported in production environment.`};break}await c(e.ServiceType.MARKR,async()=>{let{createMarkrService:e}=await Promise.resolve().then(()=>require(`./transfer-service/markr/markr-service.cjs`));return await e({apiBaseUrl:s.markrApiUrl,apiToken:s.markrApiToken,appId:s.markrAppId,disableCrossChainSwaps:s.disableCrossChainSwaps,fetch:i,environment:n,evmSigner:s.evmSigner,solanaSigner:s.solanaSigner})});break;case e.ServiceType.WRAP_UNWRAP:await c(e.ServiceType.WRAP_UNWRAP,async()=>{let{createWrapUnwrapService:e}=await Promise.resolve().then(()=>require(`./transfer-service/wrap-unwrap/wrap-unwrap-service.cjs`));return await e({environment:n,evmSigner:s.evmSigner,fetch:i})});break;default:break}}return{services:a,status:{environment:n,services:o}}},l=async e=>{let t=[];for(let n of e.values()){let e=await n.getAssets();t.push(e)}return a.mergeChainAssetMaps(t)},u=async({environment:n,fetch:a,serviceInitializers:u})=>{o(n),s(u);let{services:d,status:f}=await c({environment:n,serviceInitializers:u,fetch:a});return{id:crypto.randomUUID(),estimateNativeFee:async(e,n)=>{let r=Math.floor(Date.now()/1e3);if(e.expiresAt<=r){let n=r-e.expiresAt;throw new t.InvalidParamsError(t.ErrorReason.QUOTE_EXPIRED,`Quote expired ${n} seconds ago.`)}let i=d.get(e.serviceType);if(!i)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return await i.estimateNativeFee(e,n)},getAssetBridgeMap:async({sourceAsset:t,sourceChainId:n})=>{let r=await l(d),a=r[n];if(!a)return null;let o=a.find(n=>t.type===e.TokenType.NATIVE?n.type===e.TokenType.NATIVE:n.type===t.type&&n.address===t.address);if(!o||!o.destinations)return null;let s=o.destinations,c={};for(let[t,n]of Object.entries(s)){if(!i.isCaip2ChainId(t))continue;let a=r[t];if(!a)continue;let o=a.find(t=>n.address===e.TokenType.NATIVE?t.type===e.TokenType.NATIVE:t.type!==e.TokenType.NATIVE&&t.address===n.address);if(!o)continue;let{destinations:s,swapProviders:l,...u}=o;c[t]={bridgedAsset:u,bridgeProviders:n.bridgeProviders}}return Object.keys(c).length>0?c:null},getMinimumTransferAmount:async e=>{let t={};for(let n of d.values())if(n.analyzeSupport(e)){let r=await n.getMinimumTransferAmount(e);t[n.type]=r}return Object.keys(t).length>0?t:null},getSupportedChains:async()=>{let e=new Map,t=await Promise.all(Array.from(d.values()).map(e=>e.getSupportedChains()));for(let n of t)for(let[t,r]of n.entries()){let n=e.get(t);n||(n=new Set,e.set(t,n));for(let e of r)n.add(e)}return e},getQuoter:(e,t)=>new r.Quoter(e,Array.from(d.values()),t),status:()=>f,trackTransfer:e=>{let{transfer:n}=e,r=d.get(n.type);if(!r)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return r.trackTransfer(e)},transferAsset:async e=>{let{quote:n}=e,r=d.get(n.serviceType);if(!r)throw new t.ServiceUnavailableError(t.ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);return await r.transferAsset(e)}}};exports.createTransferManager=u;
2
2
  //# sourceMappingURL=transfer-manager.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transfer-manager.cjs","names":["isEnvironment","ServiceInitializationError","ErrorReason","isServiceInitializer","ServiceType","Environment","mergeChainAssetMaps","InvalidParamsError","ServiceUnavailableError","TokenType","isCaip2ChainId","Quoter"],"sources":["../src/transfer-manager.ts"],"sourcesContent":["import { Environment, ServiceType, TokenType } from './constants';\nimport { ErrorReason, InvalidParamsError, ServiceInitializationError, ServiceUnavailableError } from './errors';\nimport type { Asset, ChainAssetMap } from './types/asset';\nimport { isEnvironment, isServiceInitializer } from './type-guards';\nimport type { MutableGetSupportedChainsResult, ServiceInitializer, TransferService } from './types/service';\nimport type {\n CreateTransferManagerOptions,\n TransferManager,\n TransferManagerStatus,\n TransferManagerStatusServicesRecord,\n} from './types/transfer-manager';\nimport { Quoter } from './quoter/quoter';\nimport { mergeChainAssetMaps } from './_utils/merge-assets';\nimport { isCaip2ChainId } from './utils/caip';\nimport type { Caip2ChainId } from './types/caip';\nimport type { Fetch } from './types/utility-types';\n\n/**\n * Validates the provided \"environment\" option.\n *\n * @throws {ServiceInitializationError} If the environment is invalid.\n */\nconst validateEnvironment = (environment: Environment): void => {\n if (!isEnvironment(environment)) {\n throw new ServiceInitializationError(ErrorReason.ENVIRONMENT_NOT_SUPPORTED);\n }\n};\n\n/**\n * Validates the provided \"serviceInitializers\" option.\n *\n * Checks for the following:\n * - At least one service initializer is provided.\n * - All service initializers are valid.\n * - No duplicate service types are initialized.\n *\n * @throws {ServiceInitializationError} If the service initializers are invalid.\n */\nconst validateServiceInitializers = (serviceInitializers: readonly ServiceInitializer[]): void => {\n if (serviceInitializers.length === 0) {\n throw new ServiceInitializationError('No service initializers provided.');\n }\n\n if (serviceInitializers.some((serviceInitializer) => !isServiceInitializer(serviceInitializer))) {\n throw new ServiceInitializationError('One or more service initializers are invalid.');\n }\n\n const serviceInitializerTypes = new Set<ServiceType>();\n for (const initializer of serviceInitializers) {\n if (serviceInitializerTypes.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n serviceInitializerTypes.add(initializer.type);\n }\n};\n\nconst initializeServices = async ({\n environment,\n serviceInitializers,\n fetch: customFetch,\n}: {\n environment: Environment;\n serviceInitializers: readonly ServiceInitializer[];\n fetch?: Fetch;\n}): Promise<{\n services: Map<ServiceType, TransferService>;\n status: TransferManagerStatus;\n}> => {\n const initializedServicesMap: Map<ServiceType, TransferService> = new Map();\n const serviceStatuses: TransferManagerStatusServicesRecord = {};\n\n const wrapInitializationError = (serviceType: ServiceType, error: unknown): ServiceInitializationError => {\n if (error instanceof ServiceInitializationError) {\n return error;\n }\n\n const details = error instanceof Error ? error.message : String(error);\n\n return new ServiceInitializationError(\n ErrorReason.UNKNOWN,\n `Failed to initialize service type \"${serviceType}\". ${details}`,\n error,\n );\n };\n\n const initializeService = async (\n serviceType: ServiceType,\n initializer: () => Promise<TransferService>,\n ): Promise<void> => {\n try {\n const service = await initializer();\n initializedServicesMap.set(serviceType, service);\n serviceStatuses[serviceType] = { status: 'initialized' };\n } catch (error) {\n const wrappedError = wrapInitializationError(serviceType, error);\n\n serviceStatuses[serviceType] = {\n status: 'error',\n error: wrappedError,\n };\n }\n };\n\n for (const initializer of serviceInitializers) {\n // Error on duplicate initialization attempts.\n if (initializedServicesMap.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n\n switch (initializer.type) {\n case ServiceType.AVALANCHE_EVM: {\n await initializeService(ServiceType.AVALANCHE_EVM, async () => {\n const { createAvalancheEvmService } = await import('./transfer-service/avalanche-evm/avalanche-evm-service');\n\n return await createAvalancheEvmService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTCB_TO_BTC: {\n await initializeService(ServiceType.LOMBARD_BTCB_TO_BTC, async () => {\n const { createBtcbToBtcService } = await import('./transfer-service/lombard/btcb-to-btc-service');\n\n return await createBtcbToBtcService({\n bitcoinFunctions: initializer.btcFunctions,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTC_TO_BTCB: {\n await initializeService(ServiceType.LOMBARD_BTC_TO_BTCB, async () => {\n const { createBtcToBtcbService } = await import('./transfer-service/lombard/btc-to-btcb-service');\n\n return await createBtcToBtcbService({\n bitcoinFunctions: initializer.btcFunctions,\n btcSigner: initializer.btcSigner,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.MARKR: {\n if (environment !== Environment.PROD) {\n serviceStatuses[ServiceType.MARKR] = {\n status: 'unsupported-environment',\n message: `Service type \"${ServiceType.MARKR}\" is only supported in production environment.`,\n };\n break;\n }\n\n await initializeService(ServiceType.MARKR, async () => {\n const { createMarkrService } = await import('./transfer-service/markr/markr-service');\n\n return await createMarkrService({\n apiBaseUrl: initializer.markrApiUrl,\n apiToken: initializer.markrApiToken,\n appId: initializer.markrAppId,\n fetch: customFetch,\n environment,\n evmSigner: initializer.evmSigner,\n solanaSigner: initializer.solanaSigner,\n });\n });\n\n break;\n }\n\n case ServiceType.WRAP_UNWRAP: {\n await initializeService(ServiceType.WRAP_UNWRAP, async () => {\n const { createWrapUnwrapService } = await import('./transfer-service/wrap-unwrap/wrap-unwrap-service');\n\n return await createWrapUnwrapService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n default: {\n break;\n }\n }\n }\n\n return {\n services: initializedServicesMap,\n status: {\n environment,\n services: serviceStatuses,\n },\n };\n};\n\nconst _getAssets = async (services: Map<ServiceType, TransferService>): Promise<ChainAssetMap> => {\n const assetMaps: ChainAssetMap[] = [];\n\n for (const service of services.values()) {\n const serviceAssets = await service.getAssets();\n assetMaps.push(serviceAssets);\n }\n\n return mergeChainAssetMaps(assetMaps);\n};\n\n/**\n * Creates a TransferManager instance.\n *\n * @returns {Promise<TransferManager>} The TransferManager instance.\n * @throws {ServiceInitializationError} If the provided options are invalid.\n */\nexport const createTransferManager = async ({\n environment,\n fetch: customFetch,\n serviceInitializers,\n}: CreateTransferManagerOptions): Promise<TransferManager> => {\n // Validate environment.\n validateEnvironment(environment);\n validateServiceInitializers(serviceInitializers);\n\n const { services, status } = await initializeServices({ environment, serviceInitializers, fetch: customFetch });\n\n return {\n id: crypto.randomUUID(),\n estimateNativeFee: async (quote, options) => {\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n const expiredSecondsAgo = now - quote.expiresAt;\n\n throw new InvalidParamsError(ErrorReason.QUOTE_EXPIRED, `Quote expired ${expiredSecondsAgo} seconds ago.`);\n }\n\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.estimateNativeFee(quote, options);\n },\n getAssetBridgeMap: async ({ sourceAsset, sourceChainId }) => {\n const assets = await _getAssets(services);\n\n const chainAssets = assets[sourceChainId];\n\n if (!chainAssets) {\n return null;\n }\n\n const chainAsset = chainAssets.find((asset) => {\n if (sourceAsset.type === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n } else {\n return asset.type === sourceAsset.type && asset.address === sourceAsset.address;\n }\n });\n\n if (!chainAsset || !chainAsset.destinations) {\n return null;\n }\n\n const destinations = chainAsset.destinations;\n\n // map destinations to the required format, lookup bridged asset from assets map\n const result: {\n [chainId: string]: {\n bridgedAsset: Asset;\n bridgeProviders: readonly ServiceType[];\n };\n } = {};\n\n for (const [destChainId, destInfo] of Object.entries(destinations)) {\n if (!isCaip2ChainId(destChainId)) {\n continue;\n }\n\n const destChainAssets = assets[destChainId];\n\n if (!destChainAssets) {\n continue;\n }\n\n // bridgedAsset is the asset from the assets map that matches the destInfo address\n const bridgedAsset = destChainAssets.find((asset) => {\n if (destInfo.address === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n }\n\n return asset.type !== TokenType.NATIVE && asset.address === destInfo.address;\n });\n\n if (!bridgedAsset) {\n continue;\n }\n\n // Convert the TransferableAsset to Asset by omitting the 'destinations' field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { destinations: _omit, swapProviders: _omitSwapProviders, ...convertedBridgedAsset } = bridgedAsset;\n\n result[destChainId] = {\n bridgedAsset: convertedBridgedAsset,\n bridgeProviders: destInfo.bridgeProviders,\n };\n }\n\n return Object.keys(result).length > 0 ? result : null;\n },\n getMinimumTransferAmount: async (props) => {\n const serviceMinimums: { [key in ServiceType]?: bigint } = {};\n\n for (const service of services.values()) {\n if (service.analyzeSupport(props)) {\n const serviceMinAmount = await service.getMinimumTransferAmount(props);\n serviceMinimums[service.type] = serviceMinAmount;\n }\n }\n\n return Object.keys(serviceMinimums).length > 0 ? serviceMinimums : null;\n },\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n // Fetch supported chains from all configured services in parallel.\n const serviceResults = await Promise.all(\n Array.from(services.values()).map((service) => service.getSupportedChains()),\n );\n\n // Merge results: union destination sets for identical source chain IDs.\n for (const result of serviceResults) {\n for (const [sourceChainId, targetChainIds] of result.entries()) {\n let mergedTargets = supportedChainsMap.get(sourceChainId);\n if (!mergedTargets) {\n mergedTargets = new Set<Caip2ChainId>();\n supportedChainsMap.set(sourceChainId, mergedTargets);\n }\n\n for (const targetChainId of targetChainIds) {\n mergedTargets.add(targetChainId);\n }\n }\n }\n\n return supportedChainsMap;\n },\n getQuoter: (props, options) => {\n return new Quoter(props, Array.from(services.values()), options);\n },\n status: () => status,\n trackTransfer: (props) => {\n const { transfer } = props;\n const service = services.get(transfer.type);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return service.trackTransfer(props);\n },\n transferAsset: async (props) => {\n const { quote } = props;\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.transferAsset(props);\n },\n } satisfies TransferManager;\n};\n"],"mappings":"kMAsBM,EAAuB,GAAmC,CAC9D,GAAI,CAACA,EAAAA,cAAc,EAAY,CAC7B,MAAM,IAAIC,EAAAA,2BAA2BC,EAAAA,YAAY,0BAA0B,EAczE,EAA+B,GAA6D,CAChG,GAAI,EAAoB,SAAW,EACjC,MAAM,IAAID,EAAAA,2BAA2B,oCAAoC,CAG3E,GAAI,EAAoB,KAAM,GAAuB,CAACE,EAAAA,qBAAqB,EAAmB,CAAC,CAC7F,MAAM,IAAIF,EAAAA,2BAA2B,gDAAgD,CAGvF,IAAM,EAA0B,IAAI,IACpC,IAAK,IAAM,KAAe,EAAqB,CAC7C,GAAI,EAAwB,IAAI,EAAY,KAAK,CAC/C,MAAM,IAAIA,EAAAA,2BACRC,EAAAA,YAAY,iCACZ,iBAAiB,EAAY,KAAK,wCACnC,CAEH,EAAwB,IAAI,EAAY,KAAK,GAI3C,EAAqB,MAAO,CAChC,cACA,sBACA,MAAO,KAQH,CACJ,IAAM,EAA4D,IAAI,IAChE,EAAuD,EAAE,CAEzD,GAA2B,EAA0B,IAA+C,CACxG,GAAI,aAAiBD,EAAAA,2BACnB,OAAO,EAGT,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAEtE,OAAO,IAAIA,EAAAA,2BACTC,EAAAA,YAAY,QACZ,sCAAsC,EAAY,KAAK,IACvD,EACD,EAGG,EAAoB,MACxB,EACA,IACkB,CAClB,GAAI,CACF,IAAM,EAAU,MAAM,GAAa,CACnC,EAAuB,IAAI,EAAa,EAAQ,CAChD,EAAgB,GAAe,CAAE,OAAQ,cAAe,OACjD,EAAO,CAGd,EAAgB,GAAe,CAC7B,OAAQ,QACR,MAJmB,EAAwB,EAAa,EAAM,CAK/D,GAIL,IAAK,IAAM,KAAe,EAAqB,CAE7C,GAAI,EAAuB,IAAI,EAAY,KAAK,CAC9C,MAAM,IAAID,EAAAA,2BACRC,EAAAA,YAAY,iCACZ,iBAAiB,EAAY,KAAK,wCACnC,CAGH,OAAQ,EAAY,KAApB,CACE,KAAKE,EAAAA,YAAY,cACf,MAAM,EAAkBA,EAAAA,YAAY,cAAe,SAAY,CAC7D,GAAM,CAAE,6BAA8B,MAAA,QAAA,SAAA,CAAA,SAAA,QAAM,6DAAA,CAAA,CAE5C,OAAO,MAAM,EAA0B,CACrC,cACA,UAAW,EAAY,UACvB,MAAO,EACR,CAAC,EACF,CAEF,MAGF,KAAKA,EAAAA,YAAY,oBACf,MAAM,EAAkBA,EAAAA,YAAY,oBAAqB,SAAY,CACnE,GAAM,CAAE,0BAA2B,MAAA,QAAA,SAAA,CAAA,SAAA,QAAM,qDAAA,CAAA,CAEzC,OAAO,MAAM,EAAuB,CAClC,iBAAkB,EAAY,aAC9B,cACA,UAAW,EAAY,UACvB,MAAO,EACR,CAAC,EACF,CAEF,MAGF,KAAKA,EAAAA,YAAY,oBACf,MAAM,EAAkBA,EAAAA,YAAY,oBAAqB,SAAY,CACnE,GAAM,CAAE,0BAA2B,MAAA,QAAA,SAAA,CAAA,SAAA,QAAM,qDAAA,CAAA,CAEzC,OAAO,MAAM,EAAuB,CAClC,iBAAkB,EAAY,aAC9B,UAAW,EAAY,UACvB,cACA,UAAW,EAAY,UACvB,MAAO,EACR,CAAC,EACF,CAEF,MAGF,KAAKA,EAAAA,YAAY,MACf,GAAI,IAAgBC,EAAAA,YAAY,KAAM,CACpC,EAAgBD,EAAAA,YAAY,OAAS,CACnC,OAAQ,0BACR,QAAS,iBAAiBA,EAAAA,YAAY,MAAM,gDAC7C,CACD,MAGF,MAAM,EAAkBA,EAAAA,YAAY,MAAO,SAAY,CACrD,GAAM,CAAE,sBAAuB,MAAA,QAAA,SAAA,CAAA,SAAA,QAAM,6CAAA,CAAA,CAErC,OAAO,MAAM,EAAmB,CAC9B,WAAY,EAAY,YACxB,SAAU,EAAY,cACtB,MAAO,EAAY,WACnB,MAAO,EACP,cACA,UAAW,EAAY,UACvB,aAAc,EAAY,aAC3B,CAAC,EACF,CAEF,MAGF,KAAKA,EAAAA,YAAY,YACf,MAAM,EAAkBA,EAAAA,YAAY,YAAa,SAAY,CAC3D,GAAM,CAAE,2BAA4B,MAAA,QAAA,SAAA,CAAA,SAAA,QAAM,yDAAA,CAAA,CAE1C,OAAO,MAAM,EAAwB,CACnC,cACA,UAAW,EAAY,UACvB,MAAO,EACR,CAAC,EACF,CAEF,MAGF,QACE,OAKN,MAAO,CACL,SAAU,EACV,OAAQ,CACN,cACA,SAAU,EACX,CACF,EAGG,EAAa,KAAO,IAAwE,CAChG,IAAM,EAA6B,EAAE,CAErC,IAAK,IAAM,KAAW,EAAS,QAAQ,CAAE,CACvC,IAAM,EAAgB,MAAM,EAAQ,WAAW,CAC/C,EAAU,KAAK,EAAc,CAG/B,OAAOE,EAAAA,oBAAoB,EAAU,EAS1B,EAAwB,MAAO,CAC1C,cACA,MAAO,EACP,yBAC4D,CAE5D,EAAoB,EAAY,CAChC,EAA4B,EAAoB,CAEhD,GAAM,CAAE,WAAU,UAAW,MAAM,EAAmB,CAAE,cAAa,sBAAqB,MAAO,EAAa,CAAC,CAE/G,MAAO,CACL,GAAI,OAAO,YAAY,CACvB,kBAAmB,MAAO,EAAO,IAAY,CAC3C,IAAM,EAAM,KAAK,MAAM,KAAK,KAAK,CAAG,IAAM,CAE1C,GAAI,EAAM,WAAa,EAAK,CAC1B,IAAM,EAAoB,EAAM,EAAM,UAEtC,MAAM,IAAIC,EAAAA,mBAAmBL,EAAAA,YAAY,cAAe,iBAAiB,EAAkB,eAAe,CAG5G,IAAM,EAAU,EAAS,IAAI,EAAM,YAAY,CAE/C,GAAI,CAAC,EACH,MAAM,IAAIM,EAAAA,wBAAwBN,EAAAA,YAAY,4BAA4B,CAG5E,OAAO,MAAM,EAAQ,kBAAkB,EAAO,EAAQ,EAExD,kBAAmB,MAAO,CAAE,cAAa,mBAAoB,CAC3D,IAAM,EAAS,MAAM,EAAW,EAAS,CAEnC,EAAc,EAAO,GAE3B,GAAI,CAAC,EACH,OAAO,KAGT,IAAM,EAAa,EAAY,KAAM,GAC/B,EAAY,OAASO,EAAAA,UAAU,OAC1B,EAAM,OAASA,EAAAA,UAAU,OAEzB,EAAM,OAAS,EAAY,MAAQ,EAAM,UAAY,EAAY,QAE1E,CAEF,GAAI,CAAC,GAAc,CAAC,EAAW,aAC7B,OAAO,KAGT,IAAM,EAAe,EAAW,aAG1B,EAKF,EAAE,CAEN,IAAK,GAAM,CAAC,EAAa,KAAa,OAAO,QAAQ,EAAa,CAAE,CAClE,GAAI,CAACC,EAAAA,eAAe,EAAY,CAC9B,SAGF,IAAM,EAAkB,EAAO,GAE/B,GAAI,CAAC,EACH,SAIF,IAAM,EAAe,EAAgB,KAAM,GACrC,EAAS,UAAYD,EAAAA,UAAU,OAC1B,EAAM,OAASA,EAAAA,UAAU,OAG3B,EAAM,OAASA,EAAAA,UAAU,QAAU,EAAM,UAAY,EAAS,QACrE,CAEF,GAAI,CAAC,EACH,SAKF,GAAM,CAAE,aAAc,EAAO,cAAe,EAAoB,GAAG,GAA0B,EAE7F,EAAO,GAAe,CACpB,aAAc,EACd,gBAAiB,EAAS,gBAC3B,CAGH,OAAO,OAAO,KAAK,EAAO,CAAC,OAAS,EAAI,EAAS,MAEnD,yBAA0B,KAAO,IAAU,CACzC,IAAM,EAAqD,EAAE,CAE7D,IAAK,IAAM,KAAW,EAAS,QAAQ,CACrC,GAAI,EAAQ,eAAe,EAAM,CAAE,CACjC,IAAM,EAAmB,MAAM,EAAQ,yBAAyB,EAAM,CACtE,EAAgB,EAAQ,MAAQ,EAIpC,OAAO,OAAO,KAAK,EAAgB,CAAC,OAAS,EAAI,EAAkB,MAErE,mBAAoB,SAAY,CAC9B,IAAM,EAAsD,IAAI,IAG1D,EAAiB,MAAM,QAAQ,IACnC,MAAM,KAAK,EAAS,QAAQ,CAAC,CAAC,IAAK,GAAY,EAAQ,oBAAoB,CAAC,CAC7E,CAGD,IAAK,IAAM,KAAU,EACnB,IAAK,GAAM,CAAC,EAAe,KAAmB,EAAO,SAAS,CAAE,CAC9D,IAAI,EAAgB,EAAmB,IAAI,EAAc,CACpD,IACH,EAAgB,IAAI,IACpB,EAAmB,IAAI,EAAe,EAAc,EAGtD,IAAK,IAAM,KAAiB,EAC1B,EAAc,IAAI,EAAc,CAKtC,OAAO,GAET,WAAY,EAAO,IACV,IAAIE,EAAAA,OAAO,EAAO,MAAM,KAAK,EAAS,QAAQ,CAAC,CAAE,EAAQ,CAElE,WAAc,EACd,cAAgB,GAAU,CACxB,GAAM,CAAE,YAAa,EACf,EAAU,EAAS,IAAI,EAAS,KAAK,CAE3C,GAAI,CAAC,EACH,MAAM,IAAIH,EAAAA,wBAAwBN,EAAAA,YAAY,4BAA4B,CAG5E,OAAO,EAAQ,cAAc,EAAM,EAErC,cAAe,KAAO,IAAU,CAC9B,GAAM,CAAE,SAAU,EACZ,EAAU,EAAS,IAAI,EAAM,YAAY,CAE/C,GAAI,CAAC,EACH,MAAM,IAAIM,EAAAA,wBAAwBN,EAAAA,YAAY,4BAA4B,CAG5E,OAAO,MAAM,EAAQ,cAAc,EAAM,EAE5C"}
1
+ {"version":3,"file":"transfer-manager.cjs","names":["isEnvironment","ServiceInitializationError","ErrorReason","isServiceInitializer","ServiceType","Environment","mergeChainAssetMaps","InvalidParamsError","ServiceUnavailableError","TokenType","isCaip2ChainId","Quoter"],"sources":["../src/transfer-manager.ts"],"sourcesContent":["import { Environment, ServiceType, TokenType } from './constants';\nimport { ErrorReason, InvalidParamsError, ServiceInitializationError, ServiceUnavailableError } from './errors';\nimport type { Asset, ChainAssetMap } from './types/asset';\nimport { isEnvironment, isServiceInitializer } from './type-guards';\nimport type { MutableGetSupportedChainsResult, ServiceInitializer, TransferService } from './types/service';\nimport type {\n CreateTransferManagerOptions,\n TransferManager,\n TransferManagerStatus,\n TransferManagerStatusServicesRecord,\n} from './types/transfer-manager';\nimport { Quoter } from './quoter/quoter';\nimport { mergeChainAssetMaps } from './_utils/merge-assets';\nimport { isCaip2ChainId } from './utils/caip';\nimport type { Caip2ChainId } from './types/caip';\nimport type { Fetch } from './types/utility-types';\n\n/**\n * Validates the provided \"environment\" option.\n *\n * @throws {ServiceInitializationError} If the environment is invalid.\n */\nconst validateEnvironment = (environment: Environment): void => {\n if (!isEnvironment(environment)) {\n throw new ServiceInitializationError(ErrorReason.ENVIRONMENT_NOT_SUPPORTED);\n }\n};\n\n/**\n * Validates the provided \"serviceInitializers\" option.\n *\n * Checks for the following:\n * - At least one service initializer is provided.\n * - All service initializers are valid.\n * - No duplicate service types are initialized.\n *\n * @throws {ServiceInitializationError} If the service initializers are invalid.\n */\nconst validateServiceInitializers = (serviceInitializers: readonly ServiceInitializer[]): void => {\n if (serviceInitializers.length === 0) {\n throw new ServiceInitializationError('No service initializers provided.');\n }\n\n if (serviceInitializers.some((serviceInitializer) => !isServiceInitializer(serviceInitializer))) {\n throw new ServiceInitializationError('One or more service initializers are invalid.');\n }\n\n const serviceInitializerTypes = new Set<ServiceType>();\n for (const initializer of serviceInitializers) {\n if (serviceInitializerTypes.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n serviceInitializerTypes.add(initializer.type);\n }\n};\n\nconst initializeServices = async ({\n environment,\n serviceInitializers,\n fetch: customFetch,\n}: {\n environment: Environment;\n serviceInitializers: readonly ServiceInitializer[];\n fetch?: Fetch;\n}): Promise<{\n services: Map<ServiceType, TransferService>;\n status: TransferManagerStatus;\n}> => {\n const initializedServicesMap: Map<ServiceType, TransferService> = new Map();\n const serviceStatuses: TransferManagerStatusServicesRecord = {};\n\n const wrapInitializationError = (serviceType: ServiceType, error: unknown): ServiceInitializationError => {\n if (error instanceof ServiceInitializationError) {\n return error;\n }\n\n const details = error instanceof Error ? error.message : String(error);\n\n return new ServiceInitializationError(\n ErrorReason.UNKNOWN,\n `Failed to initialize service type \"${serviceType}\". ${details}`,\n error,\n );\n };\n\n const initializeService = async (\n serviceType: ServiceType,\n initializer: () => Promise<TransferService>,\n ): Promise<void> => {\n try {\n const service = await initializer();\n initializedServicesMap.set(serviceType, service);\n serviceStatuses[serviceType] = { status: 'initialized' };\n } catch (error) {\n const wrappedError = wrapInitializationError(serviceType, error);\n\n serviceStatuses[serviceType] = {\n status: 'error',\n error: wrappedError,\n };\n }\n };\n\n for (const initializer of serviceInitializers) {\n // Error on duplicate initialization attempts.\n if (initializedServicesMap.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n\n switch (initializer.type) {\n case ServiceType.AVALANCHE_EVM: {\n await initializeService(ServiceType.AVALANCHE_EVM, async () => {\n const { createAvalancheEvmService } = await import('./transfer-service/avalanche-evm/avalanche-evm-service');\n\n return await createAvalancheEvmService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTCB_TO_BTC: {\n await initializeService(ServiceType.LOMBARD_BTCB_TO_BTC, async () => {\n const { createBtcbToBtcService } = await import('./transfer-service/lombard/btcb-to-btc-service');\n\n return await createBtcbToBtcService({\n bitcoinFunctions: initializer.btcFunctions,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTC_TO_BTCB: {\n await initializeService(ServiceType.LOMBARD_BTC_TO_BTCB, async () => {\n const { createBtcToBtcbService } = await import('./transfer-service/lombard/btc-to-btcb-service');\n\n return await createBtcToBtcbService({\n bitcoinFunctions: initializer.btcFunctions,\n btcSigner: initializer.btcSigner,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.MARKR: {\n if (environment !== Environment.PROD) {\n serviceStatuses[ServiceType.MARKR] = {\n status: 'unsupported-environment',\n message: `Service type \"${ServiceType.MARKR}\" is only supported in production environment.`,\n };\n break;\n }\n\n await initializeService(ServiceType.MARKR, async () => {\n const { createMarkrService } = await import('./transfer-service/markr/markr-service');\n\n return await createMarkrService({\n apiBaseUrl: initializer.markrApiUrl,\n apiToken: initializer.markrApiToken,\n appId: initializer.markrAppId,\n disableCrossChainSwaps: initializer.disableCrossChainSwaps,\n fetch: customFetch,\n environment,\n evmSigner: initializer.evmSigner,\n solanaSigner: initializer.solanaSigner,\n });\n });\n\n break;\n }\n\n case ServiceType.WRAP_UNWRAP: {\n await initializeService(ServiceType.WRAP_UNWRAP, async () => {\n const { createWrapUnwrapService } = await import('./transfer-service/wrap-unwrap/wrap-unwrap-service');\n\n return await createWrapUnwrapService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n default: {\n break;\n }\n }\n }\n\n return {\n services: initializedServicesMap,\n status: {\n environment,\n services: serviceStatuses,\n },\n };\n};\n\nconst _getAssets = async (services: Map<ServiceType, TransferService>): Promise<ChainAssetMap> => {\n const assetMaps: ChainAssetMap[] = [];\n\n for (const service of services.values()) {\n const serviceAssets = await service.getAssets();\n assetMaps.push(serviceAssets);\n }\n\n return mergeChainAssetMaps(assetMaps);\n};\n\n/**\n * Creates a TransferManager instance.\n *\n * @returns {Promise<TransferManager>} The TransferManager instance.\n * @throws {ServiceInitializationError} If the provided options are invalid.\n */\nexport const createTransferManager = async ({\n environment,\n fetch: customFetch,\n serviceInitializers,\n}: CreateTransferManagerOptions): Promise<TransferManager> => {\n // Validate environment.\n validateEnvironment(environment);\n validateServiceInitializers(serviceInitializers);\n\n const { services, status } = await initializeServices({ environment, serviceInitializers, fetch: customFetch });\n\n return {\n id: crypto.randomUUID(),\n estimateNativeFee: async (quote, options) => {\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n const expiredSecondsAgo = now - quote.expiresAt;\n\n throw new InvalidParamsError(ErrorReason.QUOTE_EXPIRED, `Quote expired ${expiredSecondsAgo} seconds ago.`);\n }\n\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.estimateNativeFee(quote, options);\n },\n getAssetBridgeMap: async ({ sourceAsset, sourceChainId }) => {\n const assets = await _getAssets(services);\n\n const chainAssets = assets[sourceChainId];\n\n if (!chainAssets) {\n return null;\n }\n\n const chainAsset = chainAssets.find((asset) => {\n if (sourceAsset.type === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n } else {\n return asset.type === sourceAsset.type && asset.address === sourceAsset.address;\n }\n });\n\n if (!chainAsset || !chainAsset.destinations) {\n return null;\n }\n\n const destinations = chainAsset.destinations;\n\n // map destinations to the required format, lookup bridged asset from assets map\n const result: {\n [chainId: string]: {\n bridgedAsset: Asset;\n bridgeProviders: readonly ServiceType[];\n };\n } = {};\n\n for (const [destChainId, destInfo] of Object.entries(destinations)) {\n if (!isCaip2ChainId(destChainId)) {\n continue;\n }\n\n const destChainAssets = assets[destChainId];\n\n if (!destChainAssets) {\n continue;\n }\n\n // bridgedAsset is the asset from the assets map that matches the destInfo address\n const bridgedAsset = destChainAssets.find((asset) => {\n if (destInfo.address === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n }\n\n return asset.type !== TokenType.NATIVE && asset.address === destInfo.address;\n });\n\n if (!bridgedAsset) {\n continue;\n }\n\n // Convert the TransferableAsset to Asset by omitting the 'destinations' field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { destinations: _omit, swapProviders: _omitSwapProviders, ...convertedBridgedAsset } = bridgedAsset;\n\n result[destChainId] = {\n bridgedAsset: convertedBridgedAsset,\n bridgeProviders: destInfo.bridgeProviders,\n };\n }\n\n return Object.keys(result).length > 0 ? result : null;\n },\n getMinimumTransferAmount: async (props) => {\n const serviceMinimums: { [key in ServiceType]?: bigint } = {};\n\n for (const service of services.values()) {\n if (service.analyzeSupport(props)) {\n const serviceMinAmount = await service.getMinimumTransferAmount(props);\n serviceMinimums[service.type] = serviceMinAmount;\n }\n }\n\n return Object.keys(serviceMinimums).length > 0 ? serviceMinimums : null;\n },\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n // Fetch supported chains from all configured services in parallel.\n const serviceResults = await Promise.all(\n Array.from(services.values()).map((service) => service.getSupportedChains()),\n );\n\n // Merge results: union destination sets for identical source chain IDs.\n for (const result of serviceResults) {\n for (const [sourceChainId, targetChainIds] of result.entries()) {\n let mergedTargets = supportedChainsMap.get(sourceChainId);\n if (!mergedTargets) {\n mergedTargets = new Set<Caip2ChainId>();\n supportedChainsMap.set(sourceChainId, mergedTargets);\n }\n\n for (const targetChainId of targetChainIds) {\n mergedTargets.add(targetChainId);\n }\n }\n }\n\n return supportedChainsMap;\n },\n getQuoter: (props, options) => {\n return new Quoter(props, Array.from(services.values()), options);\n },\n status: () => status,\n trackTransfer: (props) => {\n const { transfer } = props;\n const service = services.get(transfer.type);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return service.trackTransfer(props);\n },\n transferAsset: async (props) => {\n const { quote } = props;\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.transferAsset(props);\n },\n } satisfies TransferManager;\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{Environment as e,ServiceType as t,TokenType as n}from"./constants.js";import{ErrorReason as r,InvalidParamsError as i,ServiceInitializationError as a,ServiceUnavailableError as o}from"./errors.js";import{isEnvironment as s,isServiceInitializer as c}from"./type-guards.js";import{Quoter as l}from"./quoter/quoter.js";import{isCaip2ChainId as u}from"./utils/caip.js";import{mergeChainAssetMaps as d}from"./_utils/merge-assets.js";const f=e=>{if(!s(e))throw new a(r.ENVIRONMENT_NOT_SUPPORTED)},p=e=>{if(e.length===0)throw new a(`No service initializers provided.`);if(e.some(e=>!c(e)))throw new a(`One or more service initializers are invalid.`);let t=new Set;for(let n of e){if(t.has(n.type))throw new a(r.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${n.type}" has been initialized more than once.`);t.add(n.type)}},m=async({environment:n,serviceInitializers:i,fetch:o})=>{let s=new Map,c={},l=(e,t)=>{if(t instanceof a)return t;let n=t instanceof Error?t.message:String(t);return new a(r.UNKNOWN,`Failed to initialize service type "${e}". ${n}`,t)},u=async(e,t)=>{try{let n=await t();s.set(e,n),c[e]={status:`initialized`}}catch(t){c[e]={status:`error`,error:l(e,t)}}};for(let l of i){if(s.has(l.type))throw new a(r.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${l.type}" has been initialized more than once.`);switch(l.type){case t.AVALANCHE_EVM:await u(t.AVALANCHE_EVM,async()=>{let{createAvalancheEvmService:e}=await import(`./transfer-service/avalanche-evm/avalanche-evm-service.js`);return await e({environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.LOMBARD_BTCB_TO_BTC:await u(t.LOMBARD_BTCB_TO_BTC,async()=>{let{createBtcbToBtcService:e}=await import(`./transfer-service/lombard/btcb-to-btc-service.js`);return await e({bitcoinFunctions:l.btcFunctions,environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.LOMBARD_BTC_TO_BTCB:await u(t.LOMBARD_BTC_TO_BTCB,async()=>{let{createBtcToBtcbService:e}=await import(`./transfer-service/lombard/btc-to-btcb-service.js`);return await e({bitcoinFunctions:l.btcFunctions,btcSigner:l.btcSigner,environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.MARKR:if(n!==e.PROD){c[t.MARKR]={status:`unsupported-environment`,message:`Service type "${t.MARKR}" is only supported in production environment.`};break}await u(t.MARKR,async()=>{let{createMarkrService:e}=await import(`./transfer-service/markr/markr-service.js`);return await e({apiBaseUrl:l.markrApiUrl,apiToken:l.markrApiToken,appId:l.markrAppId,fetch:o,environment:n,evmSigner:l.evmSigner,solanaSigner:l.solanaSigner})});break;case t.WRAP_UNWRAP:await u(t.WRAP_UNWRAP,async()=>{let{createWrapUnwrapService:e}=await import(`./transfer-service/wrap-unwrap/wrap-unwrap-service.js`);return await e({environment:n,evmSigner:l.evmSigner,fetch:o})});break;default:break}}return{services:s,status:{environment:n,services:c}}},h=async e=>{let t=[];for(let n of e.values()){let e=await n.getAssets();t.push(e)}return d(t)},g=async({environment:e,fetch:t,serviceInitializers:a})=>{f(e),p(a);let{services:s,status:c}=await m({environment:e,serviceInitializers:a,fetch:t});return{id:crypto.randomUUID(),estimateNativeFee:async(e,t)=>{let n=Math.floor(Date.now()/1e3);if(e.expiresAt<=n){let t=n-e.expiresAt;throw new i(r.QUOTE_EXPIRED,`Quote expired ${t} seconds ago.`)}let a=s.get(e.serviceType);if(!a)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return await a.estimateNativeFee(e,t)},getAssetBridgeMap:async({sourceAsset:e,sourceChainId:t})=>{let r=await h(s),i=r[t];if(!i)return null;let a=i.find(t=>e.type===n.NATIVE?t.type===n.NATIVE:t.type===e.type&&t.address===e.address);if(!a||!a.destinations)return null;let o=a.destinations,c={};for(let[e,t]of Object.entries(o)){if(!u(e))continue;let i=r[e];if(!i)continue;let a=i.find(e=>t.address===n.NATIVE?e.type===n.NATIVE:e.type!==n.NATIVE&&e.address===t.address);if(!a)continue;let{destinations:o,swapProviders:s,...l}=a;c[e]={bridgedAsset:l,bridgeProviders:t.bridgeProviders}}return Object.keys(c).length>0?c:null},getMinimumTransferAmount:async e=>{let t={};for(let n of s.values())if(n.analyzeSupport(e)){let r=await n.getMinimumTransferAmount(e);t[n.type]=r}return Object.keys(t).length>0?t:null},getSupportedChains:async()=>{let e=new Map,t=await Promise.all(Array.from(s.values()).map(e=>e.getSupportedChains()));for(let n of t)for(let[t,r]of n.entries()){let n=e.get(t);n||(n=new Set,e.set(t,n));for(let e of r)n.add(e)}return e},getQuoter:(e,t)=>new l(e,Array.from(s.values()),t),status:()=>c,trackTransfer:e=>{let{transfer:t}=e,n=s.get(t.type);if(!n)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return n.trackTransfer(e)},transferAsset:async e=>{let{quote:t}=e,n=s.get(t.serviceType);if(!n)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return await n.transferAsset(e)}}};export{g as createTransferManager};
1
+ import{Environment as e,ServiceType as t,TokenType as n}from"./constants.js";import{ErrorReason as r,InvalidParamsError as i,ServiceInitializationError as a,ServiceUnavailableError as o}from"./errors.js";import{isEnvironment as s,isServiceInitializer as c}from"./type-guards.js";import{Quoter as l}from"./quoter/quoter.js";import{isCaip2ChainId as u}from"./utils/caip.js";import{mergeChainAssetMaps as d}from"./_utils/merge-assets.js";const f=e=>{if(!s(e))throw new a(r.ENVIRONMENT_NOT_SUPPORTED)},p=e=>{if(e.length===0)throw new a(`No service initializers provided.`);if(e.some(e=>!c(e)))throw new a(`One or more service initializers are invalid.`);let t=new Set;for(let n of e){if(t.has(n.type))throw new a(r.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${n.type}" has been initialized more than once.`);t.add(n.type)}},m=async({environment:n,serviceInitializers:i,fetch:o})=>{let s=new Map,c={},l=(e,t)=>{if(t instanceof a)return t;let n=t instanceof Error?t.message:String(t);return new a(r.UNKNOWN,`Failed to initialize service type "${e}". ${n}`,t)},u=async(e,t)=>{try{let n=await t();s.set(e,n),c[e]={status:`initialized`}}catch(t){c[e]={status:`error`,error:l(e,t)}}};for(let l of i){if(s.has(l.type))throw new a(r.DUPLICATE_SERVICE_INITIALIZATION,`Service type "${l.type}" has been initialized more than once.`);switch(l.type){case t.AVALANCHE_EVM:await u(t.AVALANCHE_EVM,async()=>{let{createAvalancheEvmService:e}=await import(`./transfer-service/avalanche-evm/avalanche-evm-service.js`);return await e({environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.LOMBARD_BTCB_TO_BTC:await u(t.LOMBARD_BTCB_TO_BTC,async()=>{let{createBtcbToBtcService:e}=await import(`./transfer-service/lombard/btcb-to-btc-service.js`);return await e({bitcoinFunctions:l.btcFunctions,environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.LOMBARD_BTC_TO_BTCB:await u(t.LOMBARD_BTC_TO_BTCB,async()=>{let{createBtcToBtcbService:e}=await import(`./transfer-service/lombard/btc-to-btcb-service.js`);return await e({bitcoinFunctions:l.btcFunctions,btcSigner:l.btcSigner,environment:n,evmSigner:l.evmSigner,fetch:o})});break;case t.MARKR:if(n!==e.PROD){c[t.MARKR]={status:`unsupported-environment`,message:`Service type "${t.MARKR}" is only supported in production environment.`};break}await u(t.MARKR,async()=>{let{createMarkrService:e}=await import(`./transfer-service/markr/markr-service.js`);return await e({apiBaseUrl:l.markrApiUrl,apiToken:l.markrApiToken,appId:l.markrAppId,disableCrossChainSwaps:l.disableCrossChainSwaps,fetch:o,environment:n,evmSigner:l.evmSigner,solanaSigner:l.solanaSigner})});break;case t.WRAP_UNWRAP:await u(t.WRAP_UNWRAP,async()=>{let{createWrapUnwrapService:e}=await import(`./transfer-service/wrap-unwrap/wrap-unwrap-service.js`);return await e({environment:n,evmSigner:l.evmSigner,fetch:o})});break;default:break}}return{services:s,status:{environment:n,services:c}}},h=async e=>{let t=[];for(let n of e.values()){let e=await n.getAssets();t.push(e)}return d(t)},g=async({environment:e,fetch:t,serviceInitializers:a})=>{f(e),p(a);let{services:s,status:c}=await m({environment:e,serviceInitializers:a,fetch:t});return{id:crypto.randomUUID(),estimateNativeFee:async(e,t)=>{let n=Math.floor(Date.now()/1e3);if(e.expiresAt<=n){let t=n-e.expiresAt;throw new i(r.QUOTE_EXPIRED,`Quote expired ${t} seconds ago.`)}let a=s.get(e.serviceType);if(!a)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return await a.estimateNativeFee(e,t)},getAssetBridgeMap:async({sourceAsset:e,sourceChainId:t})=>{let r=await h(s),i=r[t];if(!i)return null;let a=i.find(t=>e.type===n.NATIVE?t.type===n.NATIVE:t.type===e.type&&t.address===e.address);if(!a||!a.destinations)return null;let o=a.destinations,c={};for(let[e,t]of Object.entries(o)){if(!u(e))continue;let i=r[e];if(!i)continue;let a=i.find(e=>t.address===n.NATIVE?e.type===n.NATIVE:e.type!==n.NATIVE&&e.address===t.address);if(!a)continue;let{destinations:o,swapProviders:s,...l}=a;c[e]={bridgedAsset:l,bridgeProviders:t.bridgeProviders}}return Object.keys(c).length>0?c:null},getMinimumTransferAmount:async e=>{let t={};for(let n of s.values())if(n.analyzeSupport(e)){let r=await n.getMinimumTransferAmount(e);t[n.type]=r}return Object.keys(t).length>0?t:null},getSupportedChains:async()=>{let e=new Map,t=await Promise.all(Array.from(s.values()).map(e=>e.getSupportedChains()));for(let n of t)for(let[t,r]of n.entries()){let n=e.get(t);n||(n=new Set,e.set(t,n));for(let e of r)n.add(e)}return e},getQuoter:(e,t)=>new l(e,Array.from(s.values()),t),status:()=>c,trackTransfer:e=>{let{transfer:t}=e,n=s.get(t.type);if(!n)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return n.trackTransfer(e)},transferAsset:async e=>{let{quote:t}=e,n=s.get(t.serviceType);if(!n)throw new o(r.SERVICE_TYPE_NOT_CONFIGURED);return await n.transferAsset(e)}}};export{g as createTransferManager};
2
2
  //# sourceMappingURL=transfer-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transfer-manager.js","names":[],"sources":["../src/transfer-manager.ts"],"sourcesContent":["import { Environment, ServiceType, TokenType } from './constants';\nimport { ErrorReason, InvalidParamsError, ServiceInitializationError, ServiceUnavailableError } from './errors';\nimport type { Asset, ChainAssetMap } from './types/asset';\nimport { isEnvironment, isServiceInitializer } from './type-guards';\nimport type { MutableGetSupportedChainsResult, ServiceInitializer, TransferService } from './types/service';\nimport type {\n CreateTransferManagerOptions,\n TransferManager,\n TransferManagerStatus,\n TransferManagerStatusServicesRecord,\n} from './types/transfer-manager';\nimport { Quoter } from './quoter/quoter';\nimport { mergeChainAssetMaps } from './_utils/merge-assets';\nimport { isCaip2ChainId } from './utils/caip';\nimport type { Caip2ChainId } from './types/caip';\nimport type { Fetch } from './types/utility-types';\n\n/**\n * Validates the provided \"environment\" option.\n *\n * @throws {ServiceInitializationError} If the environment is invalid.\n */\nconst validateEnvironment = (environment: Environment): void => {\n if (!isEnvironment(environment)) {\n throw new ServiceInitializationError(ErrorReason.ENVIRONMENT_NOT_SUPPORTED);\n }\n};\n\n/**\n * Validates the provided \"serviceInitializers\" option.\n *\n * Checks for the following:\n * - At least one service initializer is provided.\n * - All service initializers are valid.\n * - No duplicate service types are initialized.\n *\n * @throws {ServiceInitializationError} If the service initializers are invalid.\n */\nconst validateServiceInitializers = (serviceInitializers: readonly ServiceInitializer[]): void => {\n if (serviceInitializers.length === 0) {\n throw new ServiceInitializationError('No service initializers provided.');\n }\n\n if (serviceInitializers.some((serviceInitializer) => !isServiceInitializer(serviceInitializer))) {\n throw new ServiceInitializationError('One or more service initializers are invalid.');\n }\n\n const serviceInitializerTypes = new Set<ServiceType>();\n for (const initializer of serviceInitializers) {\n if (serviceInitializerTypes.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n serviceInitializerTypes.add(initializer.type);\n }\n};\n\nconst initializeServices = async ({\n environment,\n serviceInitializers,\n fetch: customFetch,\n}: {\n environment: Environment;\n serviceInitializers: readonly ServiceInitializer[];\n fetch?: Fetch;\n}): Promise<{\n services: Map<ServiceType, TransferService>;\n status: TransferManagerStatus;\n}> => {\n const initializedServicesMap: Map<ServiceType, TransferService> = new Map();\n const serviceStatuses: TransferManagerStatusServicesRecord = {};\n\n const wrapInitializationError = (serviceType: ServiceType, error: unknown): ServiceInitializationError => {\n if (error instanceof ServiceInitializationError) {\n return error;\n }\n\n const details = error instanceof Error ? error.message : String(error);\n\n return new ServiceInitializationError(\n ErrorReason.UNKNOWN,\n `Failed to initialize service type \"${serviceType}\". ${details}`,\n error,\n );\n };\n\n const initializeService = async (\n serviceType: ServiceType,\n initializer: () => Promise<TransferService>,\n ): Promise<void> => {\n try {\n const service = await initializer();\n initializedServicesMap.set(serviceType, service);\n serviceStatuses[serviceType] = { status: 'initialized' };\n } catch (error) {\n const wrappedError = wrapInitializationError(serviceType, error);\n\n serviceStatuses[serviceType] = {\n status: 'error',\n error: wrappedError,\n };\n }\n };\n\n for (const initializer of serviceInitializers) {\n // Error on duplicate initialization attempts.\n if (initializedServicesMap.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n\n switch (initializer.type) {\n case ServiceType.AVALANCHE_EVM: {\n await initializeService(ServiceType.AVALANCHE_EVM, async () => {\n const { createAvalancheEvmService } = await import('./transfer-service/avalanche-evm/avalanche-evm-service');\n\n return await createAvalancheEvmService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTCB_TO_BTC: {\n await initializeService(ServiceType.LOMBARD_BTCB_TO_BTC, async () => {\n const { createBtcbToBtcService } = await import('./transfer-service/lombard/btcb-to-btc-service');\n\n return await createBtcbToBtcService({\n bitcoinFunctions: initializer.btcFunctions,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTC_TO_BTCB: {\n await initializeService(ServiceType.LOMBARD_BTC_TO_BTCB, async () => {\n const { createBtcToBtcbService } = await import('./transfer-service/lombard/btc-to-btcb-service');\n\n return await createBtcToBtcbService({\n bitcoinFunctions: initializer.btcFunctions,\n btcSigner: initializer.btcSigner,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.MARKR: {\n if (environment !== Environment.PROD) {\n serviceStatuses[ServiceType.MARKR] = {\n status: 'unsupported-environment',\n message: `Service type \"${ServiceType.MARKR}\" is only supported in production environment.`,\n };\n break;\n }\n\n await initializeService(ServiceType.MARKR, async () => {\n const { createMarkrService } = await import('./transfer-service/markr/markr-service');\n\n return await createMarkrService({\n apiBaseUrl: initializer.markrApiUrl,\n apiToken: initializer.markrApiToken,\n appId: initializer.markrAppId,\n fetch: customFetch,\n environment,\n evmSigner: initializer.evmSigner,\n solanaSigner: initializer.solanaSigner,\n });\n });\n\n break;\n }\n\n case ServiceType.WRAP_UNWRAP: {\n await initializeService(ServiceType.WRAP_UNWRAP, async () => {\n const { createWrapUnwrapService } = await import('./transfer-service/wrap-unwrap/wrap-unwrap-service');\n\n return await createWrapUnwrapService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n default: {\n break;\n }\n }\n }\n\n return {\n services: initializedServicesMap,\n status: {\n environment,\n services: serviceStatuses,\n },\n };\n};\n\nconst _getAssets = async (services: Map<ServiceType, TransferService>): Promise<ChainAssetMap> => {\n const assetMaps: ChainAssetMap[] = [];\n\n for (const service of services.values()) {\n const serviceAssets = await service.getAssets();\n assetMaps.push(serviceAssets);\n }\n\n return mergeChainAssetMaps(assetMaps);\n};\n\n/**\n * Creates a TransferManager instance.\n *\n * @returns {Promise<TransferManager>} The TransferManager instance.\n * @throws {ServiceInitializationError} If the provided options are invalid.\n */\nexport const createTransferManager = async ({\n environment,\n fetch: customFetch,\n serviceInitializers,\n}: CreateTransferManagerOptions): Promise<TransferManager> => {\n // Validate environment.\n validateEnvironment(environment);\n validateServiceInitializers(serviceInitializers);\n\n const { services, status } = await initializeServices({ environment, serviceInitializers, fetch: customFetch });\n\n return {\n id: crypto.randomUUID(),\n estimateNativeFee: async (quote, options) => {\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n const expiredSecondsAgo = now - quote.expiresAt;\n\n throw new InvalidParamsError(ErrorReason.QUOTE_EXPIRED, `Quote expired ${expiredSecondsAgo} seconds ago.`);\n }\n\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.estimateNativeFee(quote, options);\n },\n getAssetBridgeMap: async ({ sourceAsset, sourceChainId }) => {\n const assets = await _getAssets(services);\n\n const chainAssets = assets[sourceChainId];\n\n if (!chainAssets) {\n return null;\n }\n\n const chainAsset = chainAssets.find((asset) => {\n if (sourceAsset.type === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n } else {\n return asset.type === sourceAsset.type && asset.address === sourceAsset.address;\n }\n });\n\n if (!chainAsset || !chainAsset.destinations) {\n return null;\n }\n\n const destinations = chainAsset.destinations;\n\n // map destinations to the required format, lookup bridged asset from assets map\n const result: {\n [chainId: string]: {\n bridgedAsset: Asset;\n bridgeProviders: readonly ServiceType[];\n };\n } = {};\n\n for (const [destChainId, destInfo] of Object.entries(destinations)) {\n if (!isCaip2ChainId(destChainId)) {\n continue;\n }\n\n const destChainAssets = assets[destChainId];\n\n if (!destChainAssets) {\n continue;\n }\n\n // bridgedAsset is the asset from the assets map that matches the destInfo address\n const bridgedAsset = destChainAssets.find((asset) => {\n if (destInfo.address === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n }\n\n return asset.type !== TokenType.NATIVE && asset.address === destInfo.address;\n });\n\n if (!bridgedAsset) {\n continue;\n }\n\n // Convert the TransferableAsset to Asset by omitting the 'destinations' field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { destinations: _omit, swapProviders: _omitSwapProviders, ...convertedBridgedAsset } = bridgedAsset;\n\n result[destChainId] = {\n bridgedAsset: convertedBridgedAsset,\n bridgeProviders: destInfo.bridgeProviders,\n };\n }\n\n return Object.keys(result).length > 0 ? result : null;\n },\n getMinimumTransferAmount: async (props) => {\n const serviceMinimums: { [key in ServiceType]?: bigint } = {};\n\n for (const service of services.values()) {\n if (service.analyzeSupport(props)) {\n const serviceMinAmount = await service.getMinimumTransferAmount(props);\n serviceMinimums[service.type] = serviceMinAmount;\n }\n }\n\n return Object.keys(serviceMinimums).length > 0 ? serviceMinimums : null;\n },\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n // Fetch supported chains from all configured services in parallel.\n const serviceResults = await Promise.all(\n Array.from(services.values()).map((service) => service.getSupportedChains()),\n );\n\n // Merge results: union destination sets for identical source chain IDs.\n for (const result of serviceResults) {\n for (const [sourceChainId, targetChainIds] of result.entries()) {\n let mergedTargets = supportedChainsMap.get(sourceChainId);\n if (!mergedTargets) {\n mergedTargets = new Set<Caip2ChainId>();\n supportedChainsMap.set(sourceChainId, mergedTargets);\n }\n\n for (const targetChainId of targetChainIds) {\n mergedTargets.add(targetChainId);\n }\n }\n }\n\n return supportedChainsMap;\n },\n getQuoter: (props, options) => {\n return new Quoter(props, Array.from(services.values()), options);\n },\n status: () => status,\n trackTransfer: (props) => {\n const { transfer } = props;\n const service = services.get(transfer.type);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return service.trackTransfer(props);\n },\n transferAsset: async (props) => {\n const { quote } = props;\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.transferAsset(props);\n },\n } satisfies TransferManager;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transfer-manager.js","names":[],"sources":["../src/transfer-manager.ts"],"sourcesContent":["import { Environment, ServiceType, TokenType } from './constants';\nimport { ErrorReason, InvalidParamsError, ServiceInitializationError, ServiceUnavailableError } from './errors';\nimport type { Asset, ChainAssetMap } from './types/asset';\nimport { isEnvironment, isServiceInitializer } from './type-guards';\nimport type { MutableGetSupportedChainsResult, ServiceInitializer, TransferService } from './types/service';\nimport type {\n CreateTransferManagerOptions,\n TransferManager,\n TransferManagerStatus,\n TransferManagerStatusServicesRecord,\n} from './types/transfer-manager';\nimport { Quoter } from './quoter/quoter';\nimport { mergeChainAssetMaps } from './_utils/merge-assets';\nimport { isCaip2ChainId } from './utils/caip';\nimport type { Caip2ChainId } from './types/caip';\nimport type { Fetch } from './types/utility-types';\n\n/**\n * Validates the provided \"environment\" option.\n *\n * @throws {ServiceInitializationError} If the environment is invalid.\n */\nconst validateEnvironment = (environment: Environment): void => {\n if (!isEnvironment(environment)) {\n throw new ServiceInitializationError(ErrorReason.ENVIRONMENT_NOT_SUPPORTED);\n }\n};\n\n/**\n * Validates the provided \"serviceInitializers\" option.\n *\n * Checks for the following:\n * - At least one service initializer is provided.\n * - All service initializers are valid.\n * - No duplicate service types are initialized.\n *\n * @throws {ServiceInitializationError} If the service initializers are invalid.\n */\nconst validateServiceInitializers = (serviceInitializers: readonly ServiceInitializer[]): void => {\n if (serviceInitializers.length === 0) {\n throw new ServiceInitializationError('No service initializers provided.');\n }\n\n if (serviceInitializers.some((serviceInitializer) => !isServiceInitializer(serviceInitializer))) {\n throw new ServiceInitializationError('One or more service initializers are invalid.');\n }\n\n const serviceInitializerTypes = new Set<ServiceType>();\n for (const initializer of serviceInitializers) {\n if (serviceInitializerTypes.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n serviceInitializerTypes.add(initializer.type);\n }\n};\n\nconst initializeServices = async ({\n environment,\n serviceInitializers,\n fetch: customFetch,\n}: {\n environment: Environment;\n serviceInitializers: readonly ServiceInitializer[];\n fetch?: Fetch;\n}): Promise<{\n services: Map<ServiceType, TransferService>;\n status: TransferManagerStatus;\n}> => {\n const initializedServicesMap: Map<ServiceType, TransferService> = new Map();\n const serviceStatuses: TransferManagerStatusServicesRecord = {};\n\n const wrapInitializationError = (serviceType: ServiceType, error: unknown): ServiceInitializationError => {\n if (error instanceof ServiceInitializationError) {\n return error;\n }\n\n const details = error instanceof Error ? error.message : String(error);\n\n return new ServiceInitializationError(\n ErrorReason.UNKNOWN,\n `Failed to initialize service type \"${serviceType}\". ${details}`,\n error,\n );\n };\n\n const initializeService = async (\n serviceType: ServiceType,\n initializer: () => Promise<TransferService>,\n ): Promise<void> => {\n try {\n const service = await initializer();\n initializedServicesMap.set(serviceType, service);\n serviceStatuses[serviceType] = { status: 'initialized' };\n } catch (error) {\n const wrappedError = wrapInitializationError(serviceType, error);\n\n serviceStatuses[serviceType] = {\n status: 'error',\n error: wrappedError,\n };\n }\n };\n\n for (const initializer of serviceInitializers) {\n // Error on duplicate initialization attempts.\n if (initializedServicesMap.has(initializer.type)) {\n throw new ServiceInitializationError(\n ErrorReason.DUPLICATE_SERVICE_INITIALIZATION,\n `Service type \"${initializer.type}\" has been initialized more than once.`,\n );\n }\n\n switch (initializer.type) {\n case ServiceType.AVALANCHE_EVM: {\n await initializeService(ServiceType.AVALANCHE_EVM, async () => {\n const { createAvalancheEvmService } = await import('./transfer-service/avalanche-evm/avalanche-evm-service');\n\n return await createAvalancheEvmService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTCB_TO_BTC: {\n await initializeService(ServiceType.LOMBARD_BTCB_TO_BTC, async () => {\n const { createBtcbToBtcService } = await import('./transfer-service/lombard/btcb-to-btc-service');\n\n return await createBtcbToBtcService({\n bitcoinFunctions: initializer.btcFunctions,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.LOMBARD_BTC_TO_BTCB: {\n await initializeService(ServiceType.LOMBARD_BTC_TO_BTCB, async () => {\n const { createBtcToBtcbService } = await import('./transfer-service/lombard/btc-to-btcb-service');\n\n return await createBtcToBtcbService({\n bitcoinFunctions: initializer.btcFunctions,\n btcSigner: initializer.btcSigner,\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n case ServiceType.MARKR: {\n if (environment !== Environment.PROD) {\n serviceStatuses[ServiceType.MARKR] = {\n status: 'unsupported-environment',\n message: `Service type \"${ServiceType.MARKR}\" is only supported in production environment.`,\n };\n break;\n }\n\n await initializeService(ServiceType.MARKR, async () => {\n const { createMarkrService } = await import('./transfer-service/markr/markr-service');\n\n return await createMarkrService({\n apiBaseUrl: initializer.markrApiUrl,\n apiToken: initializer.markrApiToken,\n appId: initializer.markrAppId,\n disableCrossChainSwaps: initializer.disableCrossChainSwaps,\n fetch: customFetch,\n environment,\n evmSigner: initializer.evmSigner,\n solanaSigner: initializer.solanaSigner,\n });\n });\n\n break;\n }\n\n case ServiceType.WRAP_UNWRAP: {\n await initializeService(ServiceType.WRAP_UNWRAP, async () => {\n const { createWrapUnwrapService } = await import('./transfer-service/wrap-unwrap/wrap-unwrap-service');\n\n return await createWrapUnwrapService({\n environment,\n evmSigner: initializer.evmSigner,\n fetch: customFetch,\n });\n });\n\n break;\n }\n\n default: {\n break;\n }\n }\n }\n\n return {\n services: initializedServicesMap,\n status: {\n environment,\n services: serviceStatuses,\n },\n };\n};\n\nconst _getAssets = async (services: Map<ServiceType, TransferService>): Promise<ChainAssetMap> => {\n const assetMaps: ChainAssetMap[] = [];\n\n for (const service of services.values()) {\n const serviceAssets = await service.getAssets();\n assetMaps.push(serviceAssets);\n }\n\n return mergeChainAssetMaps(assetMaps);\n};\n\n/**\n * Creates a TransferManager instance.\n *\n * @returns {Promise<TransferManager>} The TransferManager instance.\n * @throws {ServiceInitializationError} If the provided options are invalid.\n */\nexport const createTransferManager = async ({\n environment,\n fetch: customFetch,\n serviceInitializers,\n}: CreateTransferManagerOptions): Promise<TransferManager> => {\n // Validate environment.\n validateEnvironment(environment);\n validateServiceInitializers(serviceInitializers);\n\n const { services, status } = await initializeServices({ environment, serviceInitializers, fetch: customFetch });\n\n return {\n id: crypto.randomUUID(),\n estimateNativeFee: async (quote, options) => {\n const now = Math.floor(Date.now() / 1_000);\n\n if (quote.expiresAt <= now) {\n const expiredSecondsAgo = now - quote.expiresAt;\n\n throw new InvalidParamsError(ErrorReason.QUOTE_EXPIRED, `Quote expired ${expiredSecondsAgo} seconds ago.`);\n }\n\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.estimateNativeFee(quote, options);\n },\n getAssetBridgeMap: async ({ sourceAsset, sourceChainId }) => {\n const assets = await _getAssets(services);\n\n const chainAssets = assets[sourceChainId];\n\n if (!chainAssets) {\n return null;\n }\n\n const chainAsset = chainAssets.find((asset) => {\n if (sourceAsset.type === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n } else {\n return asset.type === sourceAsset.type && asset.address === sourceAsset.address;\n }\n });\n\n if (!chainAsset || !chainAsset.destinations) {\n return null;\n }\n\n const destinations = chainAsset.destinations;\n\n // map destinations to the required format, lookup bridged asset from assets map\n const result: {\n [chainId: string]: {\n bridgedAsset: Asset;\n bridgeProviders: readonly ServiceType[];\n };\n } = {};\n\n for (const [destChainId, destInfo] of Object.entries(destinations)) {\n if (!isCaip2ChainId(destChainId)) {\n continue;\n }\n\n const destChainAssets = assets[destChainId];\n\n if (!destChainAssets) {\n continue;\n }\n\n // bridgedAsset is the asset from the assets map that matches the destInfo address\n const bridgedAsset = destChainAssets.find((asset) => {\n if (destInfo.address === TokenType.NATIVE) {\n return asset.type === TokenType.NATIVE;\n }\n\n return asset.type !== TokenType.NATIVE && asset.address === destInfo.address;\n });\n\n if (!bridgedAsset) {\n continue;\n }\n\n // Convert the TransferableAsset to Asset by omitting the 'destinations' field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { destinations: _omit, swapProviders: _omitSwapProviders, ...convertedBridgedAsset } = bridgedAsset;\n\n result[destChainId] = {\n bridgedAsset: convertedBridgedAsset,\n bridgeProviders: destInfo.bridgeProviders,\n };\n }\n\n return Object.keys(result).length > 0 ? result : null;\n },\n getMinimumTransferAmount: async (props) => {\n const serviceMinimums: { [key in ServiceType]?: bigint } = {};\n\n for (const service of services.values()) {\n if (service.analyzeSupport(props)) {\n const serviceMinAmount = await service.getMinimumTransferAmount(props);\n serviceMinimums[service.type] = serviceMinAmount;\n }\n }\n\n return Object.keys(serviceMinimums).length > 0 ? serviceMinimums : null;\n },\n getSupportedChains: async () => {\n const supportedChainsMap: MutableGetSupportedChainsResult = new Map();\n\n // Fetch supported chains from all configured services in parallel.\n const serviceResults = await Promise.all(\n Array.from(services.values()).map((service) => service.getSupportedChains()),\n );\n\n // Merge results: union destination sets for identical source chain IDs.\n for (const result of serviceResults) {\n for (const [sourceChainId, targetChainIds] of result.entries()) {\n let mergedTargets = supportedChainsMap.get(sourceChainId);\n if (!mergedTargets) {\n mergedTargets = new Set<Caip2ChainId>();\n supportedChainsMap.set(sourceChainId, mergedTargets);\n }\n\n for (const targetChainId of targetChainIds) {\n mergedTargets.add(targetChainId);\n }\n }\n }\n\n return supportedChainsMap;\n },\n getQuoter: (props, options) => {\n return new Quoter(props, Array.from(services.values()), options);\n },\n status: () => status,\n trackTransfer: (props) => {\n const { transfer } = props;\n const service = services.get(transfer.type);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return service.trackTransfer(props);\n },\n transferAsset: async (props) => {\n const { quote } = props;\n const service = services.get(quote.serviceType);\n\n if (!service) {\n throw new ServiceUnavailableError(ErrorReason.SERVICE_TYPE_NOT_CONFIGURED);\n }\n\n return await service.transferAsset(props);\n },\n } satisfies TransferManager;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"_api.cjs","names":["fetchJson","combineUrlPathnames","SupportedChainsResponseSchema","ResponseValidationError","TokenListResponseSchema","fetchEventStream","QuoteResponseSchema","SwapResponseSchema","PartnerInfoResponseSchema","AbortedError","CrossChainStatusResponseSchema","SpenderAddressResponseSchema"],"sources":["../../../src/transfer-service/markr/_api.ts"],"sourcesContent":["import type { Address as SolanaAddress } from '@solana/kit';\nimport type { Address as EvmAddress } from 'viem';\nimport { AbortedError, ResponseValidationError } from '../../errors';\nimport { combineUrlPathnames, fetchEventStream, fetchJson } from '../fetch-utilities';\nimport {\n CrossChainStatusResponseSchema,\n PartnerInfoResponseSchema,\n QuoteResponseSchema,\n SpenderAddressResponseSchema,\n SupportedChainsResponseSchema,\n SwapResponseSchema,\n TokenListResponseSchema,\n type CrossChainStatusResponse,\n type PartnerInfoResponse,\n type QuoteResponseData,\n type SpenderAddressResponse,\n type SupportedChainsResponse,\n type SwapResponse,\n type TokenListResponse,\n} from './_schema';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface ApiOptions {\n apiBaseUrl: URL;\n apiToken?: string;\n fetch?: Fetch;\n}\n\nfunction getAuthHeaders(apiToken?: string): Record<string, string> | undefined {\n if (!apiToken) {\n return undefined;\n }\n\n return { Authorization: `Bearer ${apiToken}` };\n}\n\nexport async function markrGetInfoChains({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<SupportedChainsResponse> {\n const endpoint = '/info/chains';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SupportedChainsResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetTokenList(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n): Promise<TokenListResponse> {\n const endpoint = `/tokens/${chainId}/list`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = TokenListResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport interface MarkrStreamQuoteParams {\n amount: string;\n appId: string;\n chainId: number | Caip2ChainId;\n destinationChainId?: number;\n slippage?: number;\n tokenIn: string;\n tokenInDecimals: number;\n tokenOut: string;\n tokenOutDecimals: number;\n /**\n * Required ONLY for cross-chain swaps involving EVM.\n *\n * EVM -> EVM (different chains)\n * EVM -> Solana\n * Solana -> EVM\n */\n userEvmAddress?: EvmAddress;\n /**\n * Required ONLY for cross-chain swaps involving Solana.\n *\n * Solana -> EVM\n * EVM -> Solana\n * Solana -> Solana\n */\n userSolanaAddress?: SolanaAddress;\n}\n\nexport interface MarkrStreamQuoteOptions {\n onDone: () => void;\n onError: (error: Error) => void;\n onQuote: (data: QuoteResponseData) => void;\n signal?: AbortSignal;\n}\n\nexport async function markrStreamQuote(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrStreamQuoteParams,\n { onDone, onError, onQuote, signal }: MarkrStreamQuoteOptions,\n): Promise<ReadonlyArray<QuoteResponseData>> {\n const endpoint = '/quote';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const quotes: QuoteResponseData[] = [];\n\n try {\n for await (const event of fetchEventStream(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n signal,\n })) {\n const parsedData = QuoteResponseSchema.safeParse(JSON.parse(event.data));\n\n if (!parsedData.success) {\n onError(\n new ResponseValidationError(\n `Invalid quote data received from Markr \"${endpoint}\" endpoint.`,\n parsedData.error.issues,\n ),\n );\n continue;\n }\n\n if (!('done' in parsedData.data)) {\n onQuote(parsedData.data);\n quotes.push(parsedData.data);\n } else {\n onDone();\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n onError(error);\n } else {\n onError(new Error('An unknown error occurred during the quote stream.', { cause: error }));\n }\n\n onDone();\n }\n\n return quotes;\n}\n\nexport interface MarkrGetSwapParams {\n appId: string;\n /** Input amount in token's smallest unit */\n amountIn: string;\n /** Return raw transaction data alongside wrapped data */\n debug?: boolean;\n /** Minimum expected output amount */\n minAmountOut: string;\n /** Input token contract address */\n tokenIn: string;\n /** Output token contract address */\n tokenOut: string;\n /** Solana wallet public key (required for Solana swaps) */\n userPublicKey?: string;\n /** Quote UUID from previous quote request */\n uuid: string;\n}\n\nexport async function markrSwap(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrGetSwapParams,\n): Promise<SwapResponse> {\n const endpoint = '/swap';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n method: 'POST',\n });\n\n const parsed = SwapResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetPartnerInfo({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<PartnerInfoResponse> {\n const endpoint = '/info/partner';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = PartnerInfoResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetCrossChainStatus(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n sourceTxHash: string,\n { signal }: { signal?: AbortSignal } = {},\n): Promise<CrossChainStatusResponse> {\n const endpoint = `/cross-chain/status/${sourceTxHash}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n headers: getAuthHeaders(apiToken),\n fetch: customFetch,\n retries: 10,\n retryOn(ctx) {\n const method = (ctx.init.method ?? 'GET').toUpperCase();\n\n if (!['GET', 'HEAD', 'OPTIONS', 'TRACE'].includes(method)) {\n return false;\n }\n\n if (ctx.error) {\n if (ctx.error instanceof AbortedError) {\n return false;\n }\n\n return true;\n }\n\n const status = ctx.response?.status ?? 0;\n\n // Retry on 404 requests since the endpoint may not return a result immediately after the source transaction is executed.\n if (status === 404 || status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599)) {\n return true;\n }\n\n return false;\n },\n signal,\n });\n\n const parsed = CrossChainStatusResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(\n `Invalid response from Markr \"${endpoint}\" endpoint.`,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n}\n\n/**\n * Returns the spender address (wrapped contract) that needs to be approved\n * for token swaps on the specified chain.\n *\n * Not applicable for Solana.\n */\nexport async function markrGetSpenderAddress(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n crossChainSwap?: boolean,\n): Promise<SpenderAddressResponse> {\n const endpoint = `/spender-address?chainId=${chainId}&cross=${crossChainSwap ? 'true' : 'false'}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SpenderAddressResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_api.cjs","names":["fetchJson","combineUrlPathnames","SupportedChainsResponseSchema","ResponseValidationError","TokenListResponseSchema","fetchEventStream","QuoteResponseSchema","SwapResponseSchema","PartnerInfoResponseSchema","AbortedError","CrossChainStatusResponseSchema","SpenderAddressResponseSchema"],"sources":["../../../src/transfer-service/markr/_api.ts"],"sourcesContent":["import type { Address as SolanaAddress } from '@solana/kit';\nimport type { Address as EvmAddress } from 'viem';\nimport { AbortedError, ResponseValidationError } from '../../errors';\nimport { combineUrlPathnames, fetchEventStream, fetchJson } from '../fetch-utilities';\nimport {\n CrossChainStatusResponseSchema,\n PartnerInfoResponseSchema,\n QuoteResponseSchema,\n SpenderAddressResponseSchema,\n SupportedChainsResponseSchema,\n SwapResponseSchema,\n TokenListResponseSchema,\n type CrossChainStatusResponse,\n type PartnerInfoResponse,\n type QuoteResponseData,\n type SpenderAddressResponse,\n type SupportedChainsResponse,\n type SwapResponse,\n type TokenListResponse,\n} from './_schema';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface ApiOptions {\n apiBaseUrl: URL;\n apiToken?: string;\n fetch?: Fetch;\n}\n\nfunction getAuthHeaders(apiToken?: string): Record<string, string> | undefined {\n if (!apiToken) {\n return undefined;\n }\n\n return { Authorization: `Bearer ${apiToken}` };\n}\n\nexport async function markrGetInfoChains({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<SupportedChainsResponse> {\n const endpoint = '/info/chains';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SupportedChainsResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetTokenList(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n): Promise<TokenListResponse> {\n const endpoint = `/tokens/${chainId}/list`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = TokenListResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport interface MarkrStreamQuoteParams {\n amount: string;\n appId: string;\n chainId: number | Caip2ChainId;\n destinationChainId?: number | Caip2ChainId;\n slippage?: number;\n tokenIn: string;\n tokenInDecimals: number;\n tokenOut: string;\n tokenOutDecimals: number;\n /**\n * Required ONLY for cross-chain swaps involving EVM.\n *\n * EVM -> EVM (different chains)\n * EVM -> Solana\n * Solana -> EVM\n */\n userEvmAddress?: EvmAddress;\n /**\n * Required ONLY for cross-chain swaps involving Solana.\n *\n * Solana -> EVM\n * EVM -> Solana\n * Solana -> Solana\n */\n userSolanaAddress?: SolanaAddress;\n}\n\nexport interface MarkrStreamQuoteOptions {\n onDone: () => void;\n onError: (error: Error) => void;\n onQuote: (data: QuoteResponseData) => void;\n signal?: AbortSignal;\n}\n\nexport async function markrStreamQuote(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrStreamQuoteParams,\n { onDone, onError, onQuote, signal }: MarkrStreamQuoteOptions,\n): Promise<ReadonlyArray<QuoteResponseData>> {\n const endpoint = '/quote';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const quotes: QuoteResponseData[] = [];\n\n try {\n for await (const event of fetchEventStream(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n signal,\n })) {\n const parsedData = QuoteResponseSchema.safeParse(JSON.parse(event.data));\n\n if (!parsedData.success) {\n onError(\n new ResponseValidationError(\n `Invalid quote data received from Markr \"${endpoint}\" endpoint.`,\n parsedData.error.issues,\n ),\n );\n continue;\n }\n\n if (!('done' in parsedData.data)) {\n onQuote(parsedData.data);\n quotes.push(parsedData.data);\n } else {\n onDone();\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n onError(error);\n } else {\n onError(new Error('An unknown error occurred during the quote stream.', { cause: error }));\n }\n\n onDone();\n }\n\n return quotes;\n}\n\nexport interface MarkrGetSwapParams {\n appId: string;\n /** Input amount in token's smallest unit */\n amountIn: string;\n /** Return raw transaction data alongside wrapped data */\n debug?: boolean;\n /** Minimum expected output amount */\n minAmountOut: string;\n /** Input token contract address */\n tokenIn: string;\n /** Output token contract address */\n tokenOut: string;\n /** Solana wallet public key (required for Solana swaps) */\n userPublicKey?: string;\n /** Quote UUID from previous quote request */\n uuid: string;\n}\n\nexport async function markrSwap(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrGetSwapParams,\n): Promise<SwapResponse> {\n const endpoint = '/swap';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n method: 'POST',\n });\n\n const parsed = SwapResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetPartnerInfo({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<PartnerInfoResponse> {\n const endpoint = '/info/partner';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = PartnerInfoResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetCrossChainStatus(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n sourceTxHash: string,\n { signal }: { signal?: AbortSignal } = {},\n): Promise<CrossChainStatusResponse> {\n const endpoint = `/cross-chain/status/${sourceTxHash}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n headers: getAuthHeaders(apiToken),\n fetch: customFetch,\n retries: 10,\n retryOn(ctx) {\n const method = (ctx.init.method ?? 'GET').toUpperCase();\n\n if (!['GET', 'HEAD', 'OPTIONS', 'TRACE'].includes(method)) {\n return false;\n }\n\n if (ctx.error) {\n if (ctx.error instanceof AbortedError) {\n return false;\n }\n\n return true;\n }\n\n const status = ctx.response?.status ?? 0;\n\n // Retry on 404 requests since the endpoint may not return a result immediately after the source transaction is executed.\n if (status === 404 || status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599)) {\n return true;\n }\n\n return false;\n },\n signal,\n });\n\n const parsed = CrossChainStatusResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(\n `Invalid response from Markr \"${endpoint}\" endpoint.`,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n}\n\n/**\n * Returns the spender address (wrapped contract) that needs to be approved\n * for token swaps on the specified chain.\n *\n * Not applicable for Solana.\n */\nexport async function markrGetSpenderAddress(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n crossChainSwap?: boolean,\n): Promise<SpenderAddressResponse> {\n const endpoint = `/spender-address?chainId=${chainId}&cross=${crossChainSwap ? 'true' : 'false'}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SpenderAddressResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"_api.js","names":[],"sources":["../../../src/transfer-service/markr/_api.ts"],"sourcesContent":["import type { Address as SolanaAddress } from '@solana/kit';\nimport type { Address as EvmAddress } from 'viem';\nimport { AbortedError, ResponseValidationError } from '../../errors';\nimport { combineUrlPathnames, fetchEventStream, fetchJson } from '../fetch-utilities';\nimport {\n CrossChainStatusResponseSchema,\n PartnerInfoResponseSchema,\n QuoteResponseSchema,\n SpenderAddressResponseSchema,\n SupportedChainsResponseSchema,\n SwapResponseSchema,\n TokenListResponseSchema,\n type CrossChainStatusResponse,\n type PartnerInfoResponse,\n type QuoteResponseData,\n type SpenderAddressResponse,\n type SupportedChainsResponse,\n type SwapResponse,\n type TokenListResponse,\n} from './_schema';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface ApiOptions {\n apiBaseUrl: URL;\n apiToken?: string;\n fetch?: Fetch;\n}\n\nfunction getAuthHeaders(apiToken?: string): Record<string, string> | undefined {\n if (!apiToken) {\n return undefined;\n }\n\n return { Authorization: `Bearer ${apiToken}` };\n}\n\nexport async function markrGetInfoChains({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<SupportedChainsResponse> {\n const endpoint = '/info/chains';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SupportedChainsResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetTokenList(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n): Promise<TokenListResponse> {\n const endpoint = `/tokens/${chainId}/list`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = TokenListResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport interface MarkrStreamQuoteParams {\n amount: string;\n appId: string;\n chainId: number | Caip2ChainId;\n destinationChainId?: number;\n slippage?: number;\n tokenIn: string;\n tokenInDecimals: number;\n tokenOut: string;\n tokenOutDecimals: number;\n /**\n * Required ONLY for cross-chain swaps involving EVM.\n *\n * EVM -> EVM (different chains)\n * EVM -> Solana\n * Solana -> EVM\n */\n userEvmAddress?: EvmAddress;\n /**\n * Required ONLY for cross-chain swaps involving Solana.\n *\n * Solana -> EVM\n * EVM -> Solana\n * Solana -> Solana\n */\n userSolanaAddress?: SolanaAddress;\n}\n\nexport interface MarkrStreamQuoteOptions {\n onDone: () => void;\n onError: (error: Error) => void;\n onQuote: (data: QuoteResponseData) => void;\n signal?: AbortSignal;\n}\n\nexport async function markrStreamQuote(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrStreamQuoteParams,\n { onDone, onError, onQuote, signal }: MarkrStreamQuoteOptions,\n): Promise<ReadonlyArray<QuoteResponseData>> {\n const endpoint = '/quote';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const quotes: QuoteResponseData[] = [];\n\n try {\n for await (const event of fetchEventStream(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n signal,\n })) {\n const parsedData = QuoteResponseSchema.safeParse(JSON.parse(event.data));\n\n if (!parsedData.success) {\n onError(\n new ResponseValidationError(\n `Invalid quote data received from Markr \"${endpoint}\" endpoint.`,\n parsedData.error.issues,\n ),\n );\n continue;\n }\n\n if (!('done' in parsedData.data)) {\n onQuote(parsedData.data);\n quotes.push(parsedData.data);\n } else {\n onDone();\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n onError(error);\n } else {\n onError(new Error('An unknown error occurred during the quote stream.', { cause: error }));\n }\n\n onDone();\n }\n\n return quotes;\n}\n\nexport interface MarkrGetSwapParams {\n appId: string;\n /** Input amount in token's smallest unit */\n amountIn: string;\n /** Return raw transaction data alongside wrapped data */\n debug?: boolean;\n /** Minimum expected output amount */\n minAmountOut: string;\n /** Input token contract address */\n tokenIn: string;\n /** Output token contract address */\n tokenOut: string;\n /** Solana wallet public key (required for Solana swaps) */\n userPublicKey?: string;\n /** Quote UUID from previous quote request */\n uuid: string;\n}\n\nexport async function markrSwap(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrGetSwapParams,\n): Promise<SwapResponse> {\n const endpoint = '/swap';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n method: 'POST',\n });\n\n const parsed = SwapResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetPartnerInfo({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<PartnerInfoResponse> {\n const endpoint = '/info/partner';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = PartnerInfoResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetCrossChainStatus(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n sourceTxHash: string,\n { signal }: { signal?: AbortSignal } = {},\n): Promise<CrossChainStatusResponse> {\n const endpoint = `/cross-chain/status/${sourceTxHash}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n headers: getAuthHeaders(apiToken),\n fetch: customFetch,\n retries: 10,\n retryOn(ctx) {\n const method = (ctx.init.method ?? 'GET').toUpperCase();\n\n if (!['GET', 'HEAD', 'OPTIONS', 'TRACE'].includes(method)) {\n return false;\n }\n\n if (ctx.error) {\n if (ctx.error instanceof AbortedError) {\n return false;\n }\n\n return true;\n }\n\n const status = ctx.response?.status ?? 0;\n\n // Retry on 404 requests since the endpoint may not return a result immediately after the source transaction is executed.\n if (status === 404 || status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599)) {\n return true;\n }\n\n return false;\n },\n signal,\n });\n\n const parsed = CrossChainStatusResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(\n `Invalid response from Markr \"${endpoint}\" endpoint.`,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n}\n\n/**\n * Returns the spender address (wrapped contract) that needs to be approved\n * for token swaps on the specified chain.\n *\n * Not applicable for Solana.\n */\nexport async function markrGetSpenderAddress(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n crossChainSwap?: boolean,\n): Promise<SpenderAddressResponse> {\n const endpoint = `/spender-address?chainId=${chainId}&cross=${crossChainSwap ? 'true' : 'false'}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SpenderAddressResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_api.js","names":[],"sources":["../../../src/transfer-service/markr/_api.ts"],"sourcesContent":["import type { Address as SolanaAddress } from '@solana/kit';\nimport type { Address as EvmAddress } from 'viem';\nimport { AbortedError, ResponseValidationError } from '../../errors';\nimport { combineUrlPathnames, fetchEventStream, fetchJson } from '../fetch-utilities';\nimport {\n CrossChainStatusResponseSchema,\n PartnerInfoResponseSchema,\n QuoteResponseSchema,\n SpenderAddressResponseSchema,\n SupportedChainsResponseSchema,\n SwapResponseSchema,\n TokenListResponseSchema,\n type CrossChainStatusResponse,\n type PartnerInfoResponse,\n type QuoteResponseData,\n type SpenderAddressResponse,\n type SupportedChainsResponse,\n type SwapResponse,\n type TokenListResponse,\n} from './_schema';\nimport type { Caip2ChainId } from '../../types/caip';\nimport type { Fetch } from '../../types/utility-types';\n\nexport interface ApiOptions {\n apiBaseUrl: URL;\n apiToken?: string;\n fetch?: Fetch;\n}\n\nfunction getAuthHeaders(apiToken?: string): Record<string, string> | undefined {\n if (!apiToken) {\n return undefined;\n }\n\n return { Authorization: `Bearer ${apiToken}` };\n}\n\nexport async function markrGetInfoChains({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<SupportedChainsResponse> {\n const endpoint = '/info/chains';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SupportedChainsResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetTokenList(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n): Promise<TokenListResponse> {\n const endpoint = `/tokens/${chainId}/list`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = TokenListResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport interface MarkrStreamQuoteParams {\n amount: string;\n appId: string;\n chainId: number | Caip2ChainId;\n destinationChainId?: number | Caip2ChainId;\n slippage?: number;\n tokenIn: string;\n tokenInDecimals: number;\n tokenOut: string;\n tokenOutDecimals: number;\n /**\n * Required ONLY for cross-chain swaps involving EVM.\n *\n * EVM -> EVM (different chains)\n * EVM -> Solana\n * Solana -> EVM\n */\n userEvmAddress?: EvmAddress;\n /**\n * Required ONLY for cross-chain swaps involving Solana.\n *\n * Solana -> EVM\n * EVM -> Solana\n * Solana -> Solana\n */\n userSolanaAddress?: SolanaAddress;\n}\n\nexport interface MarkrStreamQuoteOptions {\n onDone: () => void;\n onError: (error: Error) => void;\n onQuote: (data: QuoteResponseData) => void;\n signal?: AbortSignal;\n}\n\nexport async function markrStreamQuote(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrStreamQuoteParams,\n { onDone, onError, onQuote, signal }: MarkrStreamQuoteOptions,\n): Promise<ReadonlyArray<QuoteResponseData>> {\n const endpoint = '/quote';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const quotes: QuoteResponseData[] = [];\n\n try {\n for await (const event of fetchEventStream(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n signal,\n })) {\n const parsedData = QuoteResponseSchema.safeParse(JSON.parse(event.data));\n\n if (!parsedData.success) {\n onError(\n new ResponseValidationError(\n `Invalid quote data received from Markr \"${endpoint}\" endpoint.`,\n parsedData.error.issues,\n ),\n );\n continue;\n }\n\n if (!('done' in parsedData.data)) {\n onQuote(parsedData.data);\n quotes.push(parsedData.data);\n } else {\n onDone();\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n onError(error);\n } else {\n onError(new Error('An unknown error occurred during the quote stream.', { cause: error }));\n }\n\n onDone();\n }\n\n return quotes;\n}\n\nexport interface MarkrGetSwapParams {\n appId: string;\n /** Input amount in token's smallest unit */\n amountIn: string;\n /** Return raw transaction data alongside wrapped data */\n debug?: boolean;\n /** Minimum expected output amount */\n minAmountOut: string;\n /** Input token contract address */\n tokenIn: string;\n /** Output token contract address */\n tokenOut: string;\n /** Solana wallet public key (required for Solana swaps) */\n userPublicKey?: string;\n /** Quote UUID from previous quote request */\n uuid: string;\n}\n\nexport async function markrSwap(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n params: MarkrGetSwapParams,\n): Promise<SwapResponse> {\n const endpoint = '/swap';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n body: JSON.stringify(params),\n fetch: customFetch,\n headers: getAuthHeaders(apiToken),\n method: 'POST',\n });\n\n const parsed = SwapResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetPartnerInfo({\n apiBaseUrl,\n apiToken,\n fetch: customFetch,\n}: ApiOptions): Promise<PartnerInfoResponse> {\n const endpoint = '/info/partner';\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = PartnerInfoResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n\nexport async function markrGetCrossChainStatus(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n sourceTxHash: string,\n { signal }: { signal?: AbortSignal } = {},\n): Promise<CrossChainStatusResponse> {\n const endpoint = `/cross-chain/status/${sourceTxHash}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, {\n headers: getAuthHeaders(apiToken),\n fetch: customFetch,\n retries: 10,\n retryOn(ctx) {\n const method = (ctx.init.method ?? 'GET').toUpperCase();\n\n if (!['GET', 'HEAD', 'OPTIONS', 'TRACE'].includes(method)) {\n return false;\n }\n\n if (ctx.error) {\n if (ctx.error instanceof AbortedError) {\n return false;\n }\n\n return true;\n }\n\n const status = ctx.response?.status ?? 0;\n\n // Retry on 404 requests since the endpoint may not return a result immediately after the source transaction is executed.\n if (status === 404 || status === 408 || status === 425 || status === 429 || (status >= 500 && status <= 599)) {\n return true;\n }\n\n return false;\n },\n signal,\n });\n\n const parsed = CrossChainStatusResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(\n `Invalid response from Markr \"${endpoint}\" endpoint.`,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n}\n\n/**\n * Returns the spender address (wrapped contract) that needs to be approved\n * for token swaps on the specified chain.\n *\n * Not applicable for Solana.\n */\nexport async function markrGetSpenderAddress(\n { apiBaseUrl, apiToken, fetch: customFetch }: ApiOptions,\n chainId: number,\n crossChainSwap?: boolean,\n): Promise<SpenderAddressResponse> {\n const endpoint = `/spender-address?chainId=${chainId}&cross=${crossChainSwap ? 'true' : 'false'}`;\n const url = combineUrlPathnames(apiBaseUrl, endpoint);\n\n const rawJson = await fetchJson(url, { headers: getAuthHeaders(apiToken), fetch: customFetch });\n\n const parsed = SpenderAddressResponseSchema.safeParse(rawJson);\n\n if (!parsed.success) {\n throw new ResponseValidationError(`Invalid response from Markr \"${endpoint}\" endpoint.`, parsed.error.issues);\n }\n\n return parsed.data;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../constants.cjs`);function t({hasSolanaSigner:t,supportedChains:n}){return({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o})=>{let s=r.type===e.TokenType.NATIVE||r.type===e.TokenType.ERC20||r.type===e.TokenType.SPL&&t,c=a.type===e.TokenType.NATIVE||a.type===e.TokenType.ERC20||a.type===e.TokenType.SPL&&t;if(!s||!c)return!1;let l=n.get(i),u=n.get(o);return!l||!u?!1:i===o?l.swapEnabled:l.crossChainSwapEnabled&&u.crossChainSwapEnabled}}exports.analyzeSupportFactory=t;
1
+ const e=require(`../../../constants.cjs`);function t({hasSolanaSigner:t,supportedChains:n}){return({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o})=>{let s=r.type===e.TokenType.NATIVE||r.type===e.TokenType.ERC20||r.type===e.TokenType.SPL&&t,c=a.type===e.TokenType.NATIVE||a.type===e.TokenType.ERC20||a.type===e.TokenType.SPL&&t;if(!s||!c)return!1;let l=n.get(i),u=n.get(o);return!l||!u?!1:i===o?l.swapEnabled:l.crossChainSwapEnabled&&l.crossChainTargetChainIds.has(o)}}exports.analyzeSupportFactory=t;
2
2
  //# sourceMappingURL=analyze-support.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-support.cjs","names":["TokenType"],"sources":["../../../../src/transfer-service/markr/_handlers/analyze-support.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport type { TransferService } from '../../../types/service';\nimport type { SupportedChainsMap } from '../_utils';\n\nexport interface AnalyzeSupportFactoryConfig {\n hasSolanaSigner: boolean;\n supportedChains: SupportedChainsMap;\n}\n\nexport function analyzeSupportFactory({\n hasSolanaSigner,\n supportedChains,\n}: AnalyzeSupportFactoryConfig): TransferService['analyzeSupport'] {\n return ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n const validSourceAssetType =\n sourceAsset.type === TokenType.NATIVE ||\n sourceAsset.type === TokenType.ERC20 ||\n (sourceAsset.type === TokenType.SPL && hasSolanaSigner);\n const validTargetAssetType =\n targetAsset.type === TokenType.NATIVE ||\n targetAsset.type === TokenType.ERC20 ||\n (targetAsset.type === TokenType.SPL && hasSolanaSigner);\n\n if (!validSourceAssetType || !validTargetAssetType) {\n return false;\n }\n\n const supportedSourceChain = supportedChains.get(sourceChainId);\n const supportedTargetChain = supportedChains.get(targetChainId);\n\n // Validate chains are supported.\n if (!supportedSourceChain || !supportedTargetChain) {\n return false;\n }\n\n // Validate same-chain swaps are supported if source and target chains are the same.\n if (sourceChainId === targetChainId) {\n return supportedSourceChain.swapEnabled;\n }\n\n // Validate cross-chain swaps are supported if source and target chains are different.\n return supportedSourceChain.crossChainSwapEnabled && supportedTargetChain.crossChainSwapEnabled;\n };\n}\n"],"mappings":"0CASA,SAAgB,EAAsB,CACpC,kBACA,mBACiE,CACjE,OAAQ,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CACrE,IAAM,EACJ,EAAY,OAASA,EAAAA,UAAU,QAC/B,EAAY,OAASA,EAAAA,UAAU,OAC9B,EAAY,OAASA,EAAAA,UAAU,KAAO,EACnC,EACJ,EAAY,OAASA,EAAAA,UAAU,QAC/B,EAAY,OAASA,EAAAA,UAAU,OAC9B,EAAY,OAASA,EAAAA,UAAU,KAAO,EAEzC,GAAI,CAAC,GAAwB,CAAC,EAC5B,MAAO,GAGT,IAAM,EAAuB,EAAgB,IAAI,EAAc,CACzD,EAAuB,EAAgB,IAAI,EAAc,CAa/D,MAVI,CAAC,GAAwB,CAAC,EACrB,GAIL,IAAkB,EACb,EAAqB,YAIvB,EAAqB,uBAAyB,EAAqB"}
1
+ {"version":3,"file":"analyze-support.cjs","names":["TokenType"],"sources":["../../../../src/transfer-service/markr/_handlers/analyze-support.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport type { TransferService } from '../../../types/service';\nimport type { SupportedChainsMap } from '../_utils';\n\nexport interface AnalyzeSupportFactoryConfig {\n hasSolanaSigner: boolean;\n supportedChains: SupportedChainsMap;\n}\n\nexport function analyzeSupportFactory({\n hasSolanaSigner,\n supportedChains,\n}: AnalyzeSupportFactoryConfig): TransferService['analyzeSupport'] {\n return ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n const validSourceAssetType =\n sourceAsset.type === TokenType.NATIVE ||\n sourceAsset.type === TokenType.ERC20 ||\n (sourceAsset.type === TokenType.SPL && hasSolanaSigner);\n const validTargetAssetType =\n targetAsset.type === TokenType.NATIVE ||\n targetAsset.type === TokenType.ERC20 ||\n (targetAsset.type === TokenType.SPL && hasSolanaSigner);\n\n if (!validSourceAssetType || !validTargetAssetType) {\n return false;\n }\n\n const supportedSourceChain = supportedChains.get(sourceChainId);\n const supportedTargetChain = supportedChains.get(targetChainId);\n\n // Validate chains are supported.\n if (!supportedSourceChain || !supportedTargetChain) {\n return false;\n }\n\n // Validate same-chain swaps are supported if source and target chains are the same.\n if (sourceChainId === targetChainId) {\n return supportedSourceChain.swapEnabled;\n }\n\n // Validate cross-chain swaps are supported for the explicit source -> target route.\n return (\n supportedSourceChain.crossChainSwapEnabled && supportedSourceChain.crossChainTargetChainIds.has(targetChainId)\n );\n };\n}\n"],"mappings":"0CASA,SAAgB,EAAsB,CACpC,kBACA,mBACiE,CACjE,OAAQ,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CACrE,IAAM,EACJ,EAAY,OAASA,EAAAA,UAAU,QAC/B,EAAY,OAASA,EAAAA,UAAU,OAC9B,EAAY,OAASA,EAAAA,UAAU,KAAO,EACnC,EACJ,EAAY,OAASA,EAAAA,UAAU,QAC/B,EAAY,OAASA,EAAAA,UAAU,OAC9B,EAAY,OAASA,EAAAA,UAAU,KAAO,EAEzC,GAAI,CAAC,GAAwB,CAAC,EAC5B,MAAO,GAGT,IAAM,EAAuB,EAAgB,IAAI,EAAc,CACzD,EAAuB,EAAgB,IAAI,EAAc,CAa/D,MAVI,CAAC,GAAwB,CAAC,EACrB,GAIL,IAAkB,EACb,EAAqB,YAK5B,EAAqB,uBAAyB,EAAqB,yBAAyB,IAAI,EAAc"}
@@ -1,2 +1,2 @@
1
- import{TokenType as e}from"../../../constants.js";function t({hasSolanaSigner:t,supportedChains:n}){return({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o})=>{let s=r.type===e.NATIVE||r.type===e.ERC20||r.type===e.SPL&&t,c=a.type===e.NATIVE||a.type===e.ERC20||a.type===e.SPL&&t;if(!s||!c)return!1;let l=n.get(i),u=n.get(o);return!l||!u?!1:i===o?l.swapEnabled:l.crossChainSwapEnabled&&u.crossChainSwapEnabled}}export{t as analyzeSupportFactory};
1
+ import{TokenType as e}from"../../../constants.js";function t({hasSolanaSigner:t,supportedChains:n}){return({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o})=>{let s=r.type===e.NATIVE||r.type===e.ERC20||r.type===e.SPL&&t,c=a.type===e.NATIVE||a.type===e.ERC20||a.type===e.SPL&&t;if(!s||!c)return!1;let l=n.get(i),u=n.get(o);return!l||!u?!1:i===o?l.swapEnabled:l.crossChainSwapEnabled&&l.crossChainTargetChainIds.has(o)}}export{t as analyzeSupportFactory};
2
2
  //# sourceMappingURL=analyze-support.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-support.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/analyze-support.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport type { TransferService } from '../../../types/service';\nimport type { SupportedChainsMap } from '../_utils';\n\nexport interface AnalyzeSupportFactoryConfig {\n hasSolanaSigner: boolean;\n supportedChains: SupportedChainsMap;\n}\n\nexport function analyzeSupportFactory({\n hasSolanaSigner,\n supportedChains,\n}: AnalyzeSupportFactoryConfig): TransferService['analyzeSupport'] {\n return ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n const validSourceAssetType =\n sourceAsset.type === TokenType.NATIVE ||\n sourceAsset.type === TokenType.ERC20 ||\n (sourceAsset.type === TokenType.SPL && hasSolanaSigner);\n const validTargetAssetType =\n targetAsset.type === TokenType.NATIVE ||\n targetAsset.type === TokenType.ERC20 ||\n (targetAsset.type === TokenType.SPL && hasSolanaSigner);\n\n if (!validSourceAssetType || !validTargetAssetType) {\n return false;\n }\n\n const supportedSourceChain = supportedChains.get(sourceChainId);\n const supportedTargetChain = supportedChains.get(targetChainId);\n\n // Validate chains are supported.\n if (!supportedSourceChain || !supportedTargetChain) {\n return false;\n }\n\n // Validate same-chain swaps are supported if source and target chains are the same.\n if (sourceChainId === targetChainId) {\n return supportedSourceChain.swapEnabled;\n }\n\n // Validate cross-chain swaps are supported if source and target chains are different.\n return supportedSourceChain.crossChainSwapEnabled && supportedTargetChain.crossChainSwapEnabled;\n };\n}\n"],"mappings":"kDASA,SAAgB,EAAsB,CACpC,kBACA,mBACiE,CACjE,OAAQ,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CACrE,IAAM,EACJ,EAAY,OAAS,EAAU,QAC/B,EAAY,OAAS,EAAU,OAC9B,EAAY,OAAS,EAAU,KAAO,EACnC,EACJ,EAAY,OAAS,EAAU,QAC/B,EAAY,OAAS,EAAU,OAC9B,EAAY,OAAS,EAAU,KAAO,EAEzC,GAAI,CAAC,GAAwB,CAAC,EAC5B,MAAO,GAGT,IAAM,EAAuB,EAAgB,IAAI,EAAc,CACzD,EAAuB,EAAgB,IAAI,EAAc,CAa/D,MAVI,CAAC,GAAwB,CAAC,EACrB,GAIL,IAAkB,EACb,EAAqB,YAIvB,EAAqB,uBAAyB,EAAqB"}
1
+ {"version":3,"file":"analyze-support.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/analyze-support.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport type { TransferService } from '../../../types/service';\nimport type { SupportedChainsMap } from '../_utils';\n\nexport interface AnalyzeSupportFactoryConfig {\n hasSolanaSigner: boolean;\n supportedChains: SupportedChainsMap;\n}\n\nexport function analyzeSupportFactory({\n hasSolanaSigner,\n supportedChains,\n}: AnalyzeSupportFactoryConfig): TransferService['analyzeSupport'] {\n return ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n const validSourceAssetType =\n sourceAsset.type === TokenType.NATIVE ||\n sourceAsset.type === TokenType.ERC20 ||\n (sourceAsset.type === TokenType.SPL && hasSolanaSigner);\n const validTargetAssetType =\n targetAsset.type === TokenType.NATIVE ||\n targetAsset.type === TokenType.ERC20 ||\n (targetAsset.type === TokenType.SPL && hasSolanaSigner);\n\n if (!validSourceAssetType || !validTargetAssetType) {\n return false;\n }\n\n const supportedSourceChain = supportedChains.get(sourceChainId);\n const supportedTargetChain = supportedChains.get(targetChainId);\n\n // Validate chains are supported.\n if (!supportedSourceChain || !supportedTargetChain) {\n return false;\n }\n\n // Validate same-chain swaps are supported if source and target chains are the same.\n if (sourceChainId === targetChainId) {\n return supportedSourceChain.swapEnabled;\n }\n\n // Validate cross-chain swaps are supported for the explicit source -> target route.\n return (\n supportedSourceChain.crossChainSwapEnabled && supportedSourceChain.crossChainTargetChainIds.has(targetChainId)\n );\n };\n}\n"],"mappings":"kDASA,SAAgB,EAAsB,CACpC,kBACA,mBACiE,CACjE,OAAQ,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CACrE,IAAM,EACJ,EAAY,OAAS,EAAU,QAC/B,EAAY,OAAS,EAAU,OAC9B,EAAY,OAAS,EAAU,KAAO,EACnC,EACJ,EAAY,OAAS,EAAU,QAC/B,EAAY,OAAS,EAAU,OAC9B,EAAY,OAAS,EAAU,KAAO,EAEzC,GAAI,CAAC,GAAwB,CAAC,EAC5B,MAAO,GAGT,IAAM,EAAuB,EAAgB,IAAI,EAAc,CACzD,EAAuB,EAAgB,IAAI,EAAc,CAa/D,MAVI,CAAC,GAAwB,CAAC,EACrB,GAIL,IAAkB,EACb,EAAqB,YAK5B,EAAqB,uBAAyB,EAAqB,yBAAyB,IAAI,EAAc"}
@@ -1,2 +1,2 @@
1
- const e=require(`../../../errors.cjs`),t=require(`../../../utils/caip.cjs`),n=require(`../../../utils/evm-address.cjs`),r=require(`../../../_utils/chain.cjs`),i=require(`../_api.cjs`),a=require(`../../../utils/sol-address.cjs`),o=require(`../_utils.cjs`);function s({apiOptions:e,appId:n,partnerFeeBps:a}){return(s,l)=>{let u=new AbortController,{userEvmAddress:d,userSolanaAddress:f,validationError:p}=c(s);return p?(l(`error`,p),l(`done`),{cancel:()=>{}}):(i.markrStreamQuote(e,{amount:s.amount.toString(),appId:n,chainId:r.isEvmNamespace(s.sourceChain.chainId)?t.caip2ToEip155ChainId(s.sourceChain.chainId):s.sourceChain.chainId,destinationChainId:s.sourceChain.chainId!==s.targetChain.chainId&&r.isEvmNamespace(s.targetChain.chainId)?t.caip2ToEip155ChainId(s.targetChain.chainId):void 0,slippage:s.slippageBps,tokenIn:o.assetToAddressString(s.sourceAsset,s.sourceChain.chainId),tokenInDecimals:s.sourceAsset.decimals,tokenOut:o.assetToAddressString(s.targetAsset,s.targetChain.chainId),tokenOutDecimals:s.targetAsset.decimals,userEvmAddress:d,userSolanaAddress:f},{onDone:()=>{u.signal.aborted||l(`done`)},onError:e=>{u.signal.aborted||(l(`error`,e),l(`done`))},onQuote:e=>{u.signal.aborted||l(`quote`,o.quoteFromMarkrQuoteResponseData(e,s,a))},signal:u.signal}),{cancel:()=>{u.abort()}})}}function c(t){let i=t.sourceChain.chainId!==t.targetChain.chainId,o=r.isEvmNamespace(t.sourceChain.chainId),s=r.isEvmNamespace(t.targetChain.chainId),c=r.isSolanaNamespace(t.sourceChain.chainId),l=r.isSolanaNamespace(t.targetChain.chainId);return o&&!n.isEvmAddress(t.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid fromAddress for EVM source chain.`)}:s&&!n.isEvmAddress(t.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid toAddress for EVM target chain.`)}:c&&!a.isSolAddress(t.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid fromAddress for Solana source chain.`)}:l&&!a.isSolAddress(t.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid toAddress for Solana target chain.`)}:i&&(o&&s||c&&l)&&t.fromAddress!==t.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`fromAddress and toAddress must match for same-namespace cross-chain swaps.`)}:i?{userEvmAddress:o&&n.isEvmAddress(t.fromAddress)?t.fromAddress:s&&n.isEvmAddress(t.toAddress)?t.toAddress:void 0,userSolanaAddress:c&&a.isSolAddress(t.fromAddress)?t.fromAddress:l&&a.isSolAddress(t.toAddress)?t.toAddress:void 0}:t.fromAddress===t.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0}:{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`fromAddress and toAddress must match for same-chain swaps.`)}}exports.streamQuotesFactory=s;
1
+ const e=require(`../../../errors.cjs`),t=require(`../../../utils/caip.cjs`),n=require(`../../../utils/evm-address.cjs`),r=require(`../../../_utils/chain.cjs`),i=require(`../_api.cjs`),a=require(`../../../utils/sol-address.cjs`),o=require(`../_utils.cjs`);function s({apiOptions:e,appId:n,partnerFeeBps:a}){return(s,l)=>{let u=new AbortController,{userEvmAddress:d,userSolanaAddress:f,validationError:p}=c(s);return p?(l(`error`,p),l(`done`),{cancel:()=>{}}):(i.markrStreamQuote(e,{amount:s.amount.toString(),appId:n,chainId:r.isEvmNamespace(s.sourceChain.chainId)?t.caip2ToEip155ChainId(s.sourceChain.chainId):s.sourceChain.chainId,destinationChainId:s.sourceChain.chainId===s.targetChain.chainId?void 0:r.isEvmNamespace(s.targetChain.chainId)?t.caip2ToEip155ChainId(s.targetChain.chainId):s.targetChain.chainId,slippage:s.slippageBps,tokenIn:o.assetToAddressString(s.sourceAsset,s.sourceChain.chainId),tokenInDecimals:s.sourceAsset.decimals,tokenOut:o.assetToAddressString(s.targetAsset,s.targetChain.chainId),tokenOutDecimals:s.targetAsset.decimals,userEvmAddress:d,userSolanaAddress:f},{onDone:()=>{u.signal.aborted||l(`done`)},onError:e=>{u.signal.aborted||(l(`error`,e),l(`done`))},onQuote:e=>{u.signal.aborted||l(`quote`,o.quoteFromMarkrQuoteResponseData(e,s,a))},signal:u.signal}),{cancel:()=>{u.abort()}})}}function c(t){let i=t.sourceChain.chainId!==t.targetChain.chainId,o=r.isEvmNamespace(t.sourceChain.chainId),s=r.isEvmNamespace(t.targetChain.chainId),c=r.isSolanaNamespace(t.sourceChain.chainId),l=r.isSolanaNamespace(t.targetChain.chainId);return o&&!n.isEvmAddress(t.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid fromAddress for EVM source chain.`)}:s&&!n.isEvmAddress(t.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid toAddress for EVM target chain.`)}:c&&!a.isSolAddress(t.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid fromAddress for Solana source chain.`)}:l&&!a.isSolAddress(t.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`Invalid toAddress for Solana target chain.`)}:i&&(o&&s||c&&l)&&t.fromAddress!==t.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`fromAddress and toAddress must match for same-namespace cross-chain swaps.`)}:i?{userEvmAddress:o&&n.isEvmAddress(t.fromAddress)?t.fromAddress:s&&n.isEvmAddress(t.toAddress)?t.toAddress:void 0,userSolanaAddress:c&&a.isSolAddress(t.fromAddress)?t.fromAddress:l&&a.isSolAddress(t.toAddress)?t.toAddress:void 0}:t.fromAddress===t.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0}:{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new e.InvalidParamsError(e.ErrorReason.INVALID_PARAMS,`fromAddress and toAddress must match for same-chain swaps.`)}}exports.streamQuotesFactory=s;
2
2
  //# sourceMappingURL=stream-quotes.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-quotes.cjs","names":["markrStreamQuote","isEvmNamespace","caip2ToEip155ChainId","assetToAddressString","quoteFromMarkrQuoteResponseData","isSolanaNamespace","isEvmAddress","InvalidParamsError","ErrorReason","isSolAddress"],"sources":["../../../../src/transfer-service/markr/_handlers/stream-quotes.ts"],"sourcesContent":["import { caip2ToEip155ChainId } from '../../../utils/caip';\nimport type { TransferService } from '../../../types/service';\nimport { markrStreamQuote, type ApiOptions, type MarkrStreamQuoteParams } from '../_api';\nimport { assetToAddressString, quoteFromMarkrQuoteResponseData } from '../_utils';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { isEvmAddress } from '../../../utils/evm-address';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport { ErrorReason, InvalidParamsError } from '../../../errors';\n\nexport interface StreamQuotesFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n partnerFeeBps: number;\n}\n\nexport function streamQuotesFactory({\n apiOptions,\n appId,\n partnerFeeBps,\n}: StreamQuotesFactoryConfig): TransferService['streamQuotes'] {\n return (props, handler) => {\n const ac = new AbortController();\n const { userEvmAddress, userSolanaAddress, validationError } = _validateAndGetUserAddresses(props);\n\n if (validationError) {\n handler('error', validationError);\n handler('done');\n\n return {\n cancel: () => {},\n };\n }\n\n void markrStreamQuote(\n apiOptions,\n {\n amount: props.amount.toString(),\n appId,\n chainId: isEvmNamespace(props.sourceChain.chainId)\n ? caip2ToEip155ChainId(props.sourceChain.chainId)\n : props.sourceChain.chainId,\n // Destination chain ID currently only supports EVM chains.\n destinationChainId:\n props.sourceChain.chainId !== props.targetChain.chainId && isEvmNamespace(props.targetChain.chainId)\n ? caip2ToEip155ChainId(props.targetChain.chainId)\n : undefined,\n slippage: props.slippageBps,\n tokenIn: assetToAddressString(props.sourceAsset, props.sourceChain.chainId),\n tokenInDecimals: props.sourceAsset.decimals,\n tokenOut: assetToAddressString(props.targetAsset, props.targetChain.chainId),\n tokenOutDecimals: props.targetAsset.decimals,\n userEvmAddress,\n userSolanaAddress,\n },\n {\n onDone: () => {\n if (!ac.signal.aborted) {\n handler('done');\n }\n },\n onError: (error) => {\n if (!ac.signal.aborted) {\n handler('error', error);\n handler('done');\n }\n },\n onQuote: (data) => {\n if (!ac.signal.aborted) {\n handler('quote', quoteFromMarkrQuoteResponseData(data, props, partnerFeeBps));\n }\n },\n signal: ac.signal,\n },\n );\n\n return {\n cancel: () => {\n ac.abort();\n },\n };\n };\n}\n\nexport function _validateAndGetUserAddresses(\n props: Parameters<TransferService['streamQuotes']>[0],\n): Pick<MarkrStreamQuoteParams, 'userEvmAddress' | 'userSolanaAddress'> & { validationError?: InvalidParamsError } {\n const isCrossChainSwap = props.sourceChain.chainId !== props.targetChain.chainId;\n const sourceIsEvm = isEvmNamespace(props.sourceChain.chainId);\n const targetIsEvm = isEvmNamespace(props.targetChain.chainId);\n const sourceIsSolana = isSolanaNamespace(props.sourceChain.chainId);\n const targetIsSolana = isSolanaNamespace(props.targetChain.chainId);\n\n if (sourceIsEvm && !isEvmAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid fromAddress for EVM source chain.'),\n };\n }\n\n if (targetIsEvm && !isEvmAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for EVM target chain.'),\n };\n }\n\n if (sourceIsSolana && !isSolAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'Invalid fromAddress for Solana source chain.',\n ),\n };\n }\n\n if (targetIsSolana && !isSolAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for Solana target chain.'),\n };\n }\n\n if (isCrossChainSwap && ((sourceIsEvm && targetIsEvm) || (sourceIsSolana && targetIsSolana))) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-namespace cross-chain swaps.',\n ),\n };\n }\n }\n\n if (!isCrossChainSwap) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-chain swaps.',\n ),\n };\n }\n\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n };\n }\n\n const userEvmAddress =\n sourceIsEvm && isEvmAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsEvm && isEvmAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n const userSolanaAddress =\n sourceIsSolana && isSolAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsSolana && isSolAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n return {\n userEvmAddress,\n userSolanaAddress,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stream-quotes.cjs","names":["markrStreamQuote","isEvmNamespace","caip2ToEip155ChainId","assetToAddressString","quoteFromMarkrQuoteResponseData","isSolanaNamespace","isEvmAddress","InvalidParamsError","ErrorReason","isSolAddress"],"sources":["../../../../src/transfer-service/markr/_handlers/stream-quotes.ts"],"sourcesContent":["import { caip2ToEip155ChainId } from '../../../utils/caip';\nimport type { TransferService } from '../../../types/service';\nimport { markrStreamQuote, type ApiOptions, type MarkrStreamQuoteParams } from '../_api';\nimport { assetToAddressString, quoteFromMarkrQuoteResponseData } from '../_utils';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { isEvmAddress } from '../../../utils/evm-address';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport { ErrorReason, InvalidParamsError } from '../../../errors';\n\nexport interface StreamQuotesFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n partnerFeeBps: number;\n}\n\nexport function streamQuotesFactory({\n apiOptions,\n appId,\n partnerFeeBps,\n}: StreamQuotesFactoryConfig): TransferService['streamQuotes'] {\n return (props, handler) => {\n const ac = new AbortController();\n const { userEvmAddress, userSolanaAddress, validationError } = _validateAndGetUserAddresses(props);\n\n if (validationError) {\n handler('error', validationError);\n handler('done');\n\n return {\n cancel: () => {},\n };\n }\n\n void markrStreamQuote(\n apiOptions,\n {\n amount: props.amount.toString(),\n appId,\n chainId: isEvmNamespace(props.sourceChain.chainId)\n ? caip2ToEip155ChainId(props.sourceChain.chainId)\n : props.sourceChain.chainId,\n // For cross-chain requests, destinationChainId is required.\n // Use EVM numeric chain IDs for EVM targets and CAIP-2 IDs for non-EVM targets.\n destinationChainId:\n props.sourceChain.chainId !== props.targetChain.chainId\n ? isEvmNamespace(props.targetChain.chainId)\n ? caip2ToEip155ChainId(props.targetChain.chainId)\n : props.targetChain.chainId\n : undefined,\n slippage: props.slippageBps,\n tokenIn: assetToAddressString(props.sourceAsset, props.sourceChain.chainId),\n tokenInDecimals: props.sourceAsset.decimals,\n tokenOut: assetToAddressString(props.targetAsset, props.targetChain.chainId),\n tokenOutDecimals: props.targetAsset.decimals,\n userEvmAddress,\n userSolanaAddress,\n },\n {\n onDone: () => {\n if (!ac.signal.aborted) {\n handler('done');\n }\n },\n onError: (error) => {\n if (!ac.signal.aborted) {\n handler('error', error);\n handler('done');\n }\n },\n onQuote: (data) => {\n if (!ac.signal.aborted) {\n handler('quote', quoteFromMarkrQuoteResponseData(data, props, partnerFeeBps));\n }\n },\n signal: ac.signal,\n },\n );\n\n return {\n cancel: () => {\n ac.abort();\n },\n };\n };\n}\n\nexport function _validateAndGetUserAddresses(\n props: Parameters<TransferService['streamQuotes']>[0],\n): Pick<MarkrStreamQuoteParams, 'userEvmAddress' | 'userSolanaAddress'> & { validationError?: InvalidParamsError } {\n const isCrossChainSwap = props.sourceChain.chainId !== props.targetChain.chainId;\n const sourceIsEvm = isEvmNamespace(props.sourceChain.chainId);\n const targetIsEvm = isEvmNamespace(props.targetChain.chainId);\n const sourceIsSolana = isSolanaNamespace(props.sourceChain.chainId);\n const targetIsSolana = isSolanaNamespace(props.targetChain.chainId);\n\n if (sourceIsEvm && !isEvmAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid fromAddress for EVM source chain.'),\n };\n }\n\n if (targetIsEvm && !isEvmAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for EVM target chain.'),\n };\n }\n\n if (sourceIsSolana && !isSolAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'Invalid fromAddress for Solana source chain.',\n ),\n };\n }\n\n if (targetIsSolana && !isSolAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for Solana target chain.'),\n };\n }\n\n if (isCrossChainSwap && ((sourceIsEvm && targetIsEvm) || (sourceIsSolana && targetIsSolana))) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-namespace cross-chain swaps.',\n ),\n };\n }\n }\n\n if (!isCrossChainSwap) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-chain swaps.',\n ),\n };\n }\n\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n };\n }\n\n const userEvmAddress =\n sourceIsEvm && isEvmAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsEvm && isEvmAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n const userSolanaAddress =\n sourceIsSolana && isSolAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsSolana && isSolAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n return {\n userEvmAddress,\n userSolanaAddress,\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{ErrorReason as e,InvalidParamsError as t}from"../../../errors.js";import{caip2ToEip155ChainId as n}from"../../../utils/caip.js";import{isEvmAddress as r}from"../../../utils/evm-address.js";import{isEvmNamespace as i,isSolanaNamespace as a}from"../../../_utils/chain.js";import{markrStreamQuote as o}from"../_api.js";import{isSolAddress as s}from"../../../utils/sol-address.js";import{assetToAddressString as c,quoteFromMarkrQuoteResponseData as l}from"../_utils.js";function u({apiOptions:e,appId:t,partnerFeeBps:r}){return(a,s)=>{let u=new AbortController,{userEvmAddress:f,userSolanaAddress:p,validationError:m}=d(a);return m?(s(`error`,m),s(`done`),{cancel:()=>{}}):(o(e,{amount:a.amount.toString(),appId:t,chainId:i(a.sourceChain.chainId)?n(a.sourceChain.chainId):a.sourceChain.chainId,destinationChainId:a.sourceChain.chainId!==a.targetChain.chainId&&i(a.targetChain.chainId)?n(a.targetChain.chainId):void 0,slippage:a.slippageBps,tokenIn:c(a.sourceAsset,a.sourceChain.chainId),tokenInDecimals:a.sourceAsset.decimals,tokenOut:c(a.targetAsset,a.targetChain.chainId),tokenOutDecimals:a.targetAsset.decimals,userEvmAddress:f,userSolanaAddress:p},{onDone:()=>{u.signal.aborted||s(`done`)},onError:e=>{u.signal.aborted||(s(`error`,e),s(`done`))},onQuote:e=>{u.signal.aborted||s(`quote`,l(e,a,r))},signal:u.signal}),{cancel:()=>{u.abort()}})}}function d(n){let o=n.sourceChain.chainId!==n.targetChain.chainId,c=i(n.sourceChain.chainId),l=i(n.targetChain.chainId),u=a(n.sourceChain.chainId),d=a(n.targetChain.chainId);return c&&!r(n.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid fromAddress for EVM source chain.`)}:l&&!r(n.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid toAddress for EVM target chain.`)}:u&&!s(n.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid fromAddress for Solana source chain.`)}:d&&!s(n.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid toAddress for Solana target chain.`)}:o&&(c&&l||u&&d)&&n.fromAddress!==n.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`fromAddress and toAddress must match for same-namespace cross-chain swaps.`)}:o?{userEvmAddress:c&&r(n.fromAddress)?n.fromAddress:l&&r(n.toAddress)?n.toAddress:void 0,userSolanaAddress:u&&s(n.fromAddress)?n.fromAddress:d&&s(n.toAddress)?n.toAddress:void 0}:n.fromAddress===n.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0}:{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`fromAddress and toAddress must match for same-chain swaps.`)}}export{u as streamQuotesFactory};
1
+ import{ErrorReason as e,InvalidParamsError as t}from"../../../errors.js";import{caip2ToEip155ChainId as n}from"../../../utils/caip.js";import{isEvmAddress as r}from"../../../utils/evm-address.js";import{isEvmNamespace as i,isSolanaNamespace as a}from"../../../_utils/chain.js";import{markrStreamQuote as o}from"../_api.js";import{isSolAddress as s}from"../../../utils/sol-address.js";import{assetToAddressString as c,quoteFromMarkrQuoteResponseData as l}from"../_utils.js";function u({apiOptions:e,appId:t,partnerFeeBps:r}){return(a,s)=>{let u=new AbortController,{userEvmAddress:f,userSolanaAddress:p,validationError:m}=d(a);return m?(s(`error`,m),s(`done`),{cancel:()=>{}}):(o(e,{amount:a.amount.toString(),appId:t,chainId:i(a.sourceChain.chainId)?n(a.sourceChain.chainId):a.sourceChain.chainId,destinationChainId:a.sourceChain.chainId===a.targetChain.chainId?void 0:i(a.targetChain.chainId)?n(a.targetChain.chainId):a.targetChain.chainId,slippage:a.slippageBps,tokenIn:c(a.sourceAsset,a.sourceChain.chainId),tokenInDecimals:a.sourceAsset.decimals,tokenOut:c(a.targetAsset,a.targetChain.chainId),tokenOutDecimals:a.targetAsset.decimals,userEvmAddress:f,userSolanaAddress:p},{onDone:()=>{u.signal.aborted||s(`done`)},onError:e=>{u.signal.aborted||(s(`error`,e),s(`done`))},onQuote:e=>{u.signal.aborted||s(`quote`,l(e,a,r))},signal:u.signal}),{cancel:()=>{u.abort()}})}}function d(n){let o=n.sourceChain.chainId!==n.targetChain.chainId,c=i(n.sourceChain.chainId),l=i(n.targetChain.chainId),u=a(n.sourceChain.chainId),d=a(n.targetChain.chainId);return c&&!r(n.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid fromAddress for EVM source chain.`)}:l&&!r(n.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid toAddress for EVM target chain.`)}:u&&!s(n.fromAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid fromAddress for Solana source chain.`)}:d&&!s(n.toAddress)?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`Invalid toAddress for Solana target chain.`)}:o&&(c&&l||u&&d)&&n.fromAddress!==n.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`fromAddress and toAddress must match for same-namespace cross-chain swaps.`)}:o?{userEvmAddress:c&&r(n.fromAddress)?n.fromAddress:l&&r(n.toAddress)?n.toAddress:void 0,userSolanaAddress:u&&s(n.fromAddress)?n.fromAddress:d&&s(n.toAddress)?n.toAddress:void 0}:n.fromAddress===n.toAddress?{userEvmAddress:void 0,userSolanaAddress:void 0}:{userEvmAddress:void 0,userSolanaAddress:void 0,validationError:new t(e.INVALID_PARAMS,`fromAddress and toAddress must match for same-chain swaps.`)}}export{u as streamQuotesFactory};
2
2
  //# sourceMappingURL=stream-quotes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-quotes.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/stream-quotes.ts"],"sourcesContent":["import { caip2ToEip155ChainId } from '../../../utils/caip';\nimport type { TransferService } from '../../../types/service';\nimport { markrStreamQuote, type ApiOptions, type MarkrStreamQuoteParams } from '../_api';\nimport { assetToAddressString, quoteFromMarkrQuoteResponseData } from '../_utils';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { isEvmAddress } from '../../../utils/evm-address';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport { ErrorReason, InvalidParamsError } from '../../../errors';\n\nexport interface StreamQuotesFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n partnerFeeBps: number;\n}\n\nexport function streamQuotesFactory({\n apiOptions,\n appId,\n partnerFeeBps,\n}: StreamQuotesFactoryConfig): TransferService['streamQuotes'] {\n return (props, handler) => {\n const ac = new AbortController();\n const { userEvmAddress, userSolanaAddress, validationError } = _validateAndGetUserAddresses(props);\n\n if (validationError) {\n handler('error', validationError);\n handler('done');\n\n return {\n cancel: () => {},\n };\n }\n\n void markrStreamQuote(\n apiOptions,\n {\n amount: props.amount.toString(),\n appId,\n chainId: isEvmNamespace(props.sourceChain.chainId)\n ? caip2ToEip155ChainId(props.sourceChain.chainId)\n : props.sourceChain.chainId,\n // Destination chain ID currently only supports EVM chains.\n destinationChainId:\n props.sourceChain.chainId !== props.targetChain.chainId && isEvmNamespace(props.targetChain.chainId)\n ? caip2ToEip155ChainId(props.targetChain.chainId)\n : undefined,\n slippage: props.slippageBps,\n tokenIn: assetToAddressString(props.sourceAsset, props.sourceChain.chainId),\n tokenInDecimals: props.sourceAsset.decimals,\n tokenOut: assetToAddressString(props.targetAsset, props.targetChain.chainId),\n tokenOutDecimals: props.targetAsset.decimals,\n userEvmAddress,\n userSolanaAddress,\n },\n {\n onDone: () => {\n if (!ac.signal.aborted) {\n handler('done');\n }\n },\n onError: (error) => {\n if (!ac.signal.aborted) {\n handler('error', error);\n handler('done');\n }\n },\n onQuote: (data) => {\n if (!ac.signal.aborted) {\n handler('quote', quoteFromMarkrQuoteResponseData(data, props, partnerFeeBps));\n }\n },\n signal: ac.signal,\n },\n );\n\n return {\n cancel: () => {\n ac.abort();\n },\n };\n };\n}\n\nexport function _validateAndGetUserAddresses(\n props: Parameters<TransferService['streamQuotes']>[0],\n): Pick<MarkrStreamQuoteParams, 'userEvmAddress' | 'userSolanaAddress'> & { validationError?: InvalidParamsError } {\n const isCrossChainSwap = props.sourceChain.chainId !== props.targetChain.chainId;\n const sourceIsEvm = isEvmNamespace(props.sourceChain.chainId);\n const targetIsEvm = isEvmNamespace(props.targetChain.chainId);\n const sourceIsSolana = isSolanaNamespace(props.sourceChain.chainId);\n const targetIsSolana = isSolanaNamespace(props.targetChain.chainId);\n\n if (sourceIsEvm && !isEvmAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid fromAddress for EVM source chain.'),\n };\n }\n\n if (targetIsEvm && !isEvmAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for EVM target chain.'),\n };\n }\n\n if (sourceIsSolana && !isSolAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'Invalid fromAddress for Solana source chain.',\n ),\n };\n }\n\n if (targetIsSolana && !isSolAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for Solana target chain.'),\n };\n }\n\n if (isCrossChainSwap && ((sourceIsEvm && targetIsEvm) || (sourceIsSolana && targetIsSolana))) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-namespace cross-chain swaps.',\n ),\n };\n }\n }\n\n if (!isCrossChainSwap) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-chain swaps.',\n ),\n };\n }\n\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n };\n }\n\n const userEvmAddress =\n sourceIsEvm && isEvmAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsEvm && isEvmAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n const userSolanaAddress =\n sourceIsSolana && isSolAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsSolana && isSolAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n return {\n userEvmAddress,\n userSolanaAddress,\n };\n}\n"],"mappings":"ydAeA,SAAgB,EAAoB,CAClC,aACA,QACA,iBAC6D,CAC7D,OAAQ,EAAO,IAAY,CACzB,IAAM,EAAK,IAAI,gBACT,CAAE,iBAAgB,oBAAmB,mBAAoB,EAA6B,EAAM,CAqDlG,OAnDI,GACF,EAAQ,QAAS,EAAgB,CACjC,EAAQ,OAAO,CAER,CACL,WAAc,GACf,GAGE,EACH,EACA,CACE,OAAQ,EAAM,OAAO,UAAU,CAC/B,QACA,QAAS,EAAe,EAAM,YAAY,QAAQ,CAC9C,EAAqB,EAAM,YAAY,QAAQ,CAC/C,EAAM,YAAY,QAEtB,mBACE,EAAM,YAAY,UAAY,EAAM,YAAY,SAAW,EAAe,EAAM,YAAY,QAAQ,CAChG,EAAqB,EAAM,YAAY,QAAQ,CAC/C,IAAA,GACN,SAAU,EAAM,YAChB,QAAS,EAAqB,EAAM,YAAa,EAAM,YAAY,QAAQ,CAC3E,gBAAiB,EAAM,YAAY,SACnC,SAAU,EAAqB,EAAM,YAAa,EAAM,YAAY,QAAQ,CAC5E,iBAAkB,EAAM,YAAY,SACpC,iBACA,oBACD,CACD,CACE,WAAc,CACP,EAAG,OAAO,SACb,EAAQ,OAAO,EAGnB,QAAU,GAAU,CACb,EAAG,OAAO,UACb,EAAQ,QAAS,EAAM,CACvB,EAAQ,OAAO,GAGnB,QAAU,GAAS,CACZ,EAAG,OAAO,SACb,EAAQ,QAAS,EAAgC,EAAM,EAAO,EAAc,CAAC,EAGjF,OAAQ,EAAG,OACZ,CACF,CAEM,CACL,WAAc,CACZ,EAAG,OAAO,EAEb,GAIL,SAAgB,EACd,EACiH,CACjH,IAAM,EAAmB,EAAM,YAAY,UAAY,EAAM,YAAY,QACnE,EAAc,EAAe,EAAM,YAAY,QAAQ,CACvD,EAAc,EAAe,EAAM,YAAY,QAAQ,CACvD,EAAiB,EAAkB,EAAM,YAAY,QAAQ,CAC7D,EAAiB,EAAkB,EAAM,YAAY,QAAQ,CAkFnE,OAhFI,GAAe,CAAC,EAAa,EAAM,YAAY,CAC1C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,4CAA4C,CACjH,CAGC,GAAe,CAAC,EAAa,EAAM,UAAU,CACxC,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,0CAA0C,CAC/G,CAGC,GAAkB,CAAC,EAAa,EAAM,YAAY,CAC7C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,+CACD,CACF,CAGC,GAAkB,CAAC,EAAa,EAAM,UAAU,CAC3C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,6CAA6C,CAClH,CAGC,IAAsB,GAAe,GAAiB,GAAkB,IACtE,EAAM,cAAgB,EAAM,UACvB,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,6EACD,CACF,CAIA,EAgCE,CACL,eAdA,GAAe,EAAa,EAAM,YAAY,CAC1C,EAAM,YACN,GAAe,EAAa,EAAM,UAAU,CAC5C,EAAM,UACN,IAAA,GAWJ,kBARA,GAAkB,EAAa,EAAM,YAAY,CAC7C,EAAM,YACN,GAAkB,EAAa,EAAM,UAAU,CAC/C,EAAM,UACN,IAAA,GAKL,CAlCK,EAAM,cAAgB,EAAM,UAWzB,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACpB,CAbQ,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,6DACD,CACF"}
1
+ {"version":3,"file":"stream-quotes.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/stream-quotes.ts"],"sourcesContent":["import { caip2ToEip155ChainId } from '../../../utils/caip';\nimport type { TransferService } from '../../../types/service';\nimport { markrStreamQuote, type ApiOptions, type MarkrStreamQuoteParams } from '../_api';\nimport { assetToAddressString, quoteFromMarkrQuoteResponseData } from '../_utils';\nimport { isEvmNamespace, isSolanaNamespace } from '../../../_utils/chain';\nimport { isEvmAddress } from '../../../utils/evm-address';\nimport { isSolAddress } from '../../../utils/sol-address';\nimport { ErrorReason, InvalidParamsError } from '../../../errors';\n\nexport interface StreamQuotesFactoryConfig {\n apiOptions: ApiOptions;\n appId: string;\n partnerFeeBps: number;\n}\n\nexport function streamQuotesFactory({\n apiOptions,\n appId,\n partnerFeeBps,\n}: StreamQuotesFactoryConfig): TransferService['streamQuotes'] {\n return (props, handler) => {\n const ac = new AbortController();\n const { userEvmAddress, userSolanaAddress, validationError } = _validateAndGetUserAddresses(props);\n\n if (validationError) {\n handler('error', validationError);\n handler('done');\n\n return {\n cancel: () => {},\n };\n }\n\n void markrStreamQuote(\n apiOptions,\n {\n amount: props.amount.toString(),\n appId,\n chainId: isEvmNamespace(props.sourceChain.chainId)\n ? caip2ToEip155ChainId(props.sourceChain.chainId)\n : props.sourceChain.chainId,\n // For cross-chain requests, destinationChainId is required.\n // Use EVM numeric chain IDs for EVM targets and CAIP-2 IDs for non-EVM targets.\n destinationChainId:\n props.sourceChain.chainId !== props.targetChain.chainId\n ? isEvmNamespace(props.targetChain.chainId)\n ? caip2ToEip155ChainId(props.targetChain.chainId)\n : props.targetChain.chainId\n : undefined,\n slippage: props.slippageBps,\n tokenIn: assetToAddressString(props.sourceAsset, props.sourceChain.chainId),\n tokenInDecimals: props.sourceAsset.decimals,\n tokenOut: assetToAddressString(props.targetAsset, props.targetChain.chainId),\n tokenOutDecimals: props.targetAsset.decimals,\n userEvmAddress,\n userSolanaAddress,\n },\n {\n onDone: () => {\n if (!ac.signal.aborted) {\n handler('done');\n }\n },\n onError: (error) => {\n if (!ac.signal.aborted) {\n handler('error', error);\n handler('done');\n }\n },\n onQuote: (data) => {\n if (!ac.signal.aborted) {\n handler('quote', quoteFromMarkrQuoteResponseData(data, props, partnerFeeBps));\n }\n },\n signal: ac.signal,\n },\n );\n\n return {\n cancel: () => {\n ac.abort();\n },\n };\n };\n}\n\nexport function _validateAndGetUserAddresses(\n props: Parameters<TransferService['streamQuotes']>[0],\n): Pick<MarkrStreamQuoteParams, 'userEvmAddress' | 'userSolanaAddress'> & { validationError?: InvalidParamsError } {\n const isCrossChainSwap = props.sourceChain.chainId !== props.targetChain.chainId;\n const sourceIsEvm = isEvmNamespace(props.sourceChain.chainId);\n const targetIsEvm = isEvmNamespace(props.targetChain.chainId);\n const sourceIsSolana = isSolanaNamespace(props.sourceChain.chainId);\n const targetIsSolana = isSolanaNamespace(props.targetChain.chainId);\n\n if (sourceIsEvm && !isEvmAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid fromAddress for EVM source chain.'),\n };\n }\n\n if (targetIsEvm && !isEvmAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for EVM target chain.'),\n };\n }\n\n if (sourceIsSolana && !isSolAddress(props.fromAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'Invalid fromAddress for Solana source chain.',\n ),\n };\n }\n\n if (targetIsSolana && !isSolAddress(props.toAddress)) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid toAddress for Solana target chain.'),\n };\n }\n\n if (isCrossChainSwap && ((sourceIsEvm && targetIsEvm) || (sourceIsSolana && targetIsSolana))) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-namespace cross-chain swaps.',\n ),\n };\n }\n }\n\n if (!isCrossChainSwap) {\n if (props.fromAddress !== props.toAddress) {\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n validationError: new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n 'fromAddress and toAddress must match for same-chain swaps.',\n ),\n };\n }\n\n return {\n userEvmAddress: undefined,\n userSolanaAddress: undefined,\n };\n }\n\n const userEvmAddress =\n sourceIsEvm && isEvmAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsEvm && isEvmAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n const userSolanaAddress =\n sourceIsSolana && isSolAddress(props.fromAddress)\n ? props.fromAddress\n : targetIsSolana && isSolAddress(props.toAddress)\n ? props.toAddress\n : undefined;\n\n return {\n userEvmAddress,\n userSolanaAddress,\n };\n}\n"],"mappings":"ydAeA,SAAgB,EAAoB,CAClC,aACA,QACA,iBAC6D,CAC7D,OAAQ,EAAO,IAAY,CACzB,IAAM,EAAK,IAAI,gBACT,CAAE,iBAAgB,oBAAmB,mBAAoB,EAA6B,EAAM,CAwDlG,OAtDI,GACF,EAAQ,QAAS,EAAgB,CACjC,EAAQ,OAAO,CAER,CACL,WAAc,GACf,GAGE,EACH,EACA,CACE,OAAQ,EAAM,OAAO,UAAU,CAC/B,QACA,QAAS,EAAe,EAAM,YAAY,QAAQ,CAC9C,EAAqB,EAAM,YAAY,QAAQ,CAC/C,EAAM,YAAY,QAGtB,mBACE,EAAM,YAAY,UAAY,EAAM,YAAY,QAI5C,IAAA,GAHA,EAAe,EAAM,YAAY,QAAQ,CACvC,EAAqB,EAAM,YAAY,QAAQ,CAC/C,EAAM,YAAY,QAE1B,SAAU,EAAM,YAChB,QAAS,EAAqB,EAAM,YAAa,EAAM,YAAY,QAAQ,CAC3E,gBAAiB,EAAM,YAAY,SACnC,SAAU,EAAqB,EAAM,YAAa,EAAM,YAAY,QAAQ,CAC5E,iBAAkB,EAAM,YAAY,SACpC,iBACA,oBACD,CACD,CACE,WAAc,CACP,EAAG,OAAO,SACb,EAAQ,OAAO,EAGnB,QAAU,GAAU,CACb,EAAG,OAAO,UACb,EAAQ,QAAS,EAAM,CACvB,EAAQ,OAAO,GAGnB,QAAU,GAAS,CACZ,EAAG,OAAO,SACb,EAAQ,QAAS,EAAgC,EAAM,EAAO,EAAc,CAAC,EAGjF,OAAQ,EAAG,OACZ,CACF,CAEM,CACL,WAAc,CACZ,EAAG,OAAO,EAEb,GAIL,SAAgB,EACd,EACiH,CACjH,IAAM,EAAmB,EAAM,YAAY,UAAY,EAAM,YAAY,QACnE,EAAc,EAAe,EAAM,YAAY,QAAQ,CACvD,EAAc,EAAe,EAAM,YAAY,QAAQ,CACvD,EAAiB,EAAkB,EAAM,YAAY,QAAQ,CAC7D,EAAiB,EAAkB,EAAM,YAAY,QAAQ,CAkFnE,OAhFI,GAAe,CAAC,EAAa,EAAM,YAAY,CAC1C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,4CAA4C,CACjH,CAGC,GAAe,CAAC,EAAa,EAAM,UAAU,CACxC,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,0CAA0C,CAC/G,CAGC,GAAkB,CAAC,EAAa,EAAM,YAAY,CAC7C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,+CACD,CACF,CAGC,GAAkB,CAAC,EAAa,EAAM,UAAU,CAC3C,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EAAmB,EAAY,eAAgB,6CAA6C,CAClH,CAGC,IAAsB,GAAe,GAAiB,GAAkB,IACtE,EAAM,cAAgB,EAAM,UACvB,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,6EACD,CACF,CAIA,EAgCE,CACL,eAdA,GAAe,EAAa,EAAM,YAAY,CAC1C,EAAM,YACN,GAAe,EAAa,EAAM,UAAU,CAC5C,EAAM,UACN,IAAA,GAWJ,kBARA,GAAkB,EAAa,EAAM,YAAY,CAC7C,EAAM,YACN,GAAkB,EAAa,EAAM,UAAU,CAC/C,EAAM,UACN,IAAA,GAKL,CAlCK,EAAM,cAAgB,EAAM,UAWzB,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACpB,CAbQ,CACL,eAAgB,IAAA,GAChB,kBAAmB,IAAA,GACnB,gBAAiB,IAAI,EACnB,EAAY,eACZ,6DACD,CACF"}
@@ -1,2 +1,2 @@
1
- require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../errors.cjs`),t=require(`../../../_utils/chain.cjs`),n=require(`../../_utils.cjs`),r=require(`../_api.cjs`),i=require(`../../_tracking-utilities.cjs`),a=require(`../constants.cjs`);let o=require(`viem`),s=require(`@solana/kit`);const c=3e3;function l({apiOptions:e}){return({transfer:n,updateListener:r})=>n.sourceChain.chainId===n.targetChain.chainId?t.isSolanaNamespace(n.sourceChain.chainId)?u({transfer:n,updateListener:r}):i.trackSameChainEvmTransfer({transfer:n,updateListener:r}):f({transfer:n,updateListener:r},e)}function u({transfer:e,updateListener:t}){let n=new AbortController,r=()=>n.abort();return e.status===`source-pending`?{cancel:r,result:d(e,t,n.signal)}:{cancel:r,result:Promise.resolve(e)}}async function d(t,r,i){let{txHash:o}=t.source;try{(0,s.assertIsSignature)(o)}catch{let n={...t,errorCode:e.ErrorCode.INVALID_PARAMS,failedAtMs:Date.now(),status:`failed`};return r(n),n}let c=n.getSolanaRpcForChain({chain:t.sourceChain}),l=Date.now();for(;!i.aborted;){if(Date.now()-l>a.SOLANA_TX_TIMEOUT_MS){let n={...t,errorCode:e.ErrorCode.TIMEOUT,failedAtMs:Date.now(),status:`failed`};return r(n),n}try{let{value:s}=await c.getSignatureStatuses([o],{searchTransactionHistory:!0}).send(),l=s[0];if(!l){await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i});continue}if(l.err!==null){let n={...t,errorCode:e.ErrorCode.TRANSACTION_REVERTED,failedAtMs:Date.now(),status:`failed`};return r(n),n}if(l.confirmationStatus===`finalized`){let e={...t,completedAtMs:Date.now(),source:{...t.source,confirmationCount:t.source.requiredConfirmationCount},status:`completed`,target:null};return r(e),e}let u=Number(l.confirmations??0),d=Math.min(u,t.source.requiredConfirmationCount-1);d!==t.source.confirmationCount&&(t={...t,source:{...t.source,confirmationCount:d}},r(t)),await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i})}catch(e){let i={...t,errorCode:n.getErrorCodeForSolanaRpcError(e),failedAtMs:Date.now(),status:`failed`};return r(i),i}}return t}function f({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 p(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,c);r.signal.addEventListener(`abort`,()=>clearTimeout(t),{once:!0})})}return i})()}}async function p(i,a,c){if(i.status===`completed`||i.status===`failed`)return i;if(!g(i.source.txHash,i.sourceChain.chainId))return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};if(i.status===`source-pending`){if(t.isEvmNamespace(i.sourceChain.chainId)){let t=i.source.txHash;if(!(0,o.isHash)(t))return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};let r=n.getEvmClientForChain({chain:i.sourceChain});try{let a=await n.awaitOrAbort(r.waitForTransactionReceipt({hash:t}),c);if(a.status===`aborted`)return i;let o=a.value;return o.status===`reverted`?{...i,errorCode:e.ErrorCode.TRANSACTION_REVERTED,errorReason:`Source transaction was reverted`,failedAtMs:Date.now(),status:`failed`}:(await m(r,o.blockNumber,c)).status===`aborted`?i:v(i)}catch(e){return{...i,errorCode:n.getErrorCodeForViemError(e),errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}}}if(t.isSolanaNamespace(i.sourceChain.chainId)){let t=i.source.txHash;try{(0,s.assertIsSignature)(t)}catch{return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`}}let n=await h(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`}:v(i)}}try{let t=await r.markrGetCrossChainStatus(a,i.source.txHash,{signal:c});switch(t.status){case`failed`:return{...i,errorCode:e.ErrorCode.TRANSACTION_REVERTED,errorReason:`Transaction execution failed.`,failedAtMs:S(t),status:`failed`};case`pending`:return _(t.sourceChain.finalized)?v(i):i;case`committed`:case`pending_execution`:return y(i,t);case`completed`:return b(i,t);default:return x(i,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.ErrorCode.UNKNOWN,errorReason:`Failed to fetch cross-chain tx status`,failedAtMs:Date.now(),status:`failed`}}}async function m(e,t,r){for(;!r.aborted;){let i=await n.awaitOrAbort(e.getBlock({blockTag:`finalized`}),r);if(i.status===`aborted`)return{status:`aborted`};if(i.value.number>=t)return{status:`ok`};await n.waitForTimeoutOrAbort({timeoutMs:c,signal:r})}return{status:`aborted`}}async function h(t,r,i){let o=n.getSolanaRpcForChain({chain:t}),s=Date.now();for(;!i.aborted;){if(Date.now()-s>a.SOLANA_TX_TIMEOUT_MS)return{status:`failed`,errorCode:e.ErrorCode.TIMEOUT};try{let{value:t}=await o.getSignatureStatuses([r],{searchTransactionHistory:!0}).send(),s=t[0];if(!s){await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i});continue}if(s.err!==null)return{status:`failed`,errorCode:e.ErrorCode.TRANSACTION_REVERTED};if(s.confirmationStatus===`finalized`)return{status:`ok`};await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i})}catch(e){return{status:`failed`,errorCode:n.getErrorCodeForSolanaRpcError(e)}}}return{status:`aborted`}}function g(e,n){if(t.isEvmNamespace(n))return(0,o.isHash)(e);if(t.isSolanaNamespace(n))try{return(0,s.assertIsSignature)(e),!0}catch{return!1}return!1}function _(e){return e===!0||typeof e==`string`}function v(e){return{...e,source:{...e.source,confirmationCount:2,requiredConfirmationCount:2},status:`source-completed`}}function y(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 b(e,t){let{timestamp:n,transactionHash:r}=t.destinationChain;return{...e,completedAtMs:S(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 x(e,t){return t.progress.executed===!0?b(e,t):t.progress.committed===!0?y(e,t):_(t.sourceChain.finalized)?v(e):{...e,source:{...e.source,confirmationCount:0,requiredConfirmationCount:2},status:`source-pending`}}function S(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()}exports.trackTransferFactory=l;
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../../errors.cjs`),t=require(`../../../_utils/chain.cjs`),n=require(`../../_utils.cjs`),r=require(`../_api.cjs`),i=require(`../../_tracking-utilities.cjs`),a=require(`../constants.cjs`);let o=require(`viem`),s=require(`@solana/kit`);const c=3e3;function l({apiOptions:e}){return({transfer:n,updateListener:r})=>n.sourceChain.chainId===n.targetChain.chainId?t.isSolanaNamespace(n.sourceChain.chainId)?u({transfer:n,updateListener:r}):i.trackSameChainEvmTransfer({transfer:n,updateListener:r}):f({transfer:n,updateListener:r},e)}function u({transfer:e,updateListener:t}){let n=new AbortController,r=()=>n.abort();return e.status===`source-pending`?{cancel:r,result:d(e,t,n.signal)}:{cancel:r,result:Promise.resolve(e)}}async function d(t,r,i){let{txHash:o}=t.source;try{(0,s.assertIsSignature)(o)}catch{let n={...t,errorCode:e.ErrorCode.INVALID_PARAMS,failedAtMs:Date.now(),status:`failed`};return r(n),n}let c=n.getSolanaRpcForChain({chain:t.sourceChain}),l=Date.now();for(;!i.aborted;){if(Date.now()-l>a.SOLANA_TX_TIMEOUT_MS){let n={...t,errorCode:e.ErrorCode.TIMEOUT,failedAtMs:Date.now(),status:`failed`};return r(n),n}try{let{value:s}=await c.getSignatureStatuses([o],{searchTransactionHistory:!0}).send(),l=s[0];if(!l){await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i});continue}if(l.err!==null){let n={...t,errorCode:e.ErrorCode.TRANSACTION_REVERTED,failedAtMs:Date.now(),status:`failed`};return r(n),n}if(l.confirmationStatus===`finalized`){let e={...t,completedAtMs:Date.now(),source:{...t.source,confirmationCount:t.source.requiredConfirmationCount},status:`completed`,target:null};return r(e),e}let u=Number(l.confirmations??0),d=Math.min(u,t.source.requiredConfirmationCount-1);d!==t.source.confirmationCount&&(t={...t,source:{...t.source,confirmationCount:d}},r(t)),await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i})}catch(e){let i={...t,errorCode:n.getErrorCodeForSolanaRpcError(e),failedAtMs:Date.now(),status:`failed`};return r(i),i}}return t}function f({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 p(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,c);r.signal.addEventListener(`abort`,()=>clearTimeout(t),{once:!0})})}return i})()}}async function p(i,a,c){if(i.status===`completed`||i.status===`failed`)return i;if(!g(i.source.txHash,i.sourceChain.chainId))return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};if(i.status===`source-pending`){if(t.isEvmNamespace(i.sourceChain.chainId)){let t=i.source.txHash;if(!(0,o.isHash)(t))return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`};let r=n.getEvmClientForChain({chain:i.sourceChain});try{let a=await n.awaitOrAbort(r.waitForTransactionReceipt({hash:t}),c);if(a.status===`aborted`)return i;let o=a.value;return o.status===`reverted`?{...i,errorCode:e.ErrorCode.TRANSACTION_REVERTED,errorReason:`Source transaction was reverted`,failedAtMs:Date.now(),status:`failed`}:(await m(r,o.blockNumber,c)).status===`aborted`?i:v(i)}catch(e){return{...i,errorCode:n.getErrorCodeForViemError(e),errorReason:`Failed to confirm source transaction finality`,failedAtMs:Date.now(),status:`failed`}}}if(t.isSolanaNamespace(i.sourceChain.chainId)){let t=i.source.txHash;try{(0,s.assertIsSignature)(t)}catch{return{...i,errorCode:e.ErrorCode.INVALID_PARAMS,errorReason:`Invalid source transaction hash`,failedAtMs:Date.now(),status:`failed`}}let n=await h(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`}:v(i)}}try{let t=await r.markrGetCrossChainStatus(a,i.source.txHash,{signal:c}),n=y(i,t);switch(t.status){case`failed`:return{...n,errorCode:e.ErrorCode.TRANSACTION_REVERTED,errorReason:`Transaction execution failed.`,failedAtMs:C(t),status:`failed`};case`pending`:return _(t.sourceChain.finalized)?v(n):n;case`committed`:case`pending_execution`:return b(n,t);case`completed`:return x(n,t);default:return S(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.ErrorCode.UNKNOWN,errorReason:`Failed to fetch cross-chain tx status`,failedAtMs:Date.now(),status:`failed`}}}async function m(e,t,r){for(;!r.aborted;){let i=await n.awaitOrAbort(e.getBlock({blockTag:`finalized`}),r);if(i.status===`aborted`)return{status:`aborted`};if(i.value.number>=t)return{status:`ok`};await n.waitForTimeoutOrAbort({timeoutMs:c,signal:r})}return{status:`aborted`}}async function h(t,r,i){let o=n.getSolanaRpcForChain({chain:t}),s=Date.now();for(;!i.aborted;){if(Date.now()-s>a.SOLANA_TX_TIMEOUT_MS)return{status:`failed`,errorCode:e.ErrorCode.TIMEOUT};try{let{value:t}=await o.getSignatureStatuses([r],{searchTransactionHistory:!0}).send(),s=t[0];if(!s){await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i});continue}if(s.err!==null)return{status:`failed`,errorCode:e.ErrorCode.TRANSACTION_REVERTED};if(s.confirmationStatus===`finalized`)return{status:`ok`};await n.waitForTimeoutOrAbort({timeoutMs:a.SOLANA_POLLING_INTERVAL_MS,signal:i})}catch(e){return{status:`failed`,errorCode:n.getErrorCodeForSolanaRpcError(e)}}}return{status:`aborted`}}function g(e,n){if(t.isEvmNamespace(n))return(0,o.isHash)(e);if(t.isSolanaNamespace(n))try{return(0,s.assertIsSignature)(e),!0}catch{return!1}return!1}function _(e){return e===!0||typeof e==`string`}function v(e){return{...e,source:{...e.source,confirmationCount:2,requiredConfirmationCount:2},status:`source-completed`}}function y(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 b(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 x(e,t){let{timestamp:n,transactionHash:r}=t.destinationChain;return{...e,completedAtMs:C(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 S(e,t){return t.progress.executed===!0?x(e,t):t.progress.committed===!0?b(e,t):_(t.sourceChain.finalized)?v(e):{...e,source:{...e.source,confirmationCount:0,requiredConfirmationCount:2},status:`source-pending`}}function C(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()}exports.trackTransferFactory=l;
2
2
  //# sourceMappingURL=track-transfer.cjs.map