@avalabs/fusion-sdk 0.14.0 → 0.14.1

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.
@@ -1,2 +1,2 @@
1
- const e=require(`../../../errors.cjs`),t=1n,n=10000n;function r({analyzeSupport:t,partnerFeeBps:n}){return async({sourceAsset:r,sourceChainId:i,targetAsset:s,targetChainId:u})=>{if(!Number.isInteger(n)||n<0)throw new e.SdkError(e.ErrorReason.UNKNOWN,e.ErrorCode.INVALID_PARAMS,{details:`Invalid partner fee basis points: ${n}`});if(!t({sourceAsset:r,sourceChainId:i,targetAsset:s,targetChainId:u}))throw new e.SdkError(e.ErrorReason.UNKNOWN,e.ErrorCode.INVALID_PARAMS,{details:`Transfer not supported by Markr. Unable to get minimum transfer amount.`});return o(r.decimals),a(c(n),l(r.decimals))}}function i(e,t){return(e+t-1n)/t}function a(e,t){return e>t?e:t}function o(t){if(!Number.isInteger(t)||t<0)throw new e.SdkError(e.ErrorReason.UNKNOWN,e.ErrorCode.INVALID_PARAMS,{details:`Invalid source asset decimals: ${t}`})}function s(e,t,n){return i(10n**BigInt(e)*t,n)}function c(e){return i((e===0?t:i(t*n,BigInt(e)))*(n+500n),n)}function l(e){return s(e,10n,100000n)}exports.getMinimumTransferAmountFactory=r;
1
+ const e=require(`../../../constants.cjs`),t=require(`../../../errors.cjs`),n=require(`../../../_utils/chain.cjs`),r=1n,i=10000n;function a({analyzeSupport:e,partnerFeeBps:n}){return async({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o})=>{if(!Number.isInteger(n)||n<0)throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INVALID_PARAMS,{details:`Invalid partner fee basis points: ${n}`});if(!e({sourceAsset:r,sourceChainId:i,targetAsset:a,targetChainId:o}))throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INVALID_PARAMS,{details:`Transfer not supported by Markr. Unable to get minimum transfer amount.`});c(r.decimals);let l=u(n),p=f({sourceAssetType:r.type,sourceChainId:i,targetChainId:o,targetAssetType:a.type});return s(l,d(r.decimals,p))}}function o(e,t){return(e+t-1n)/t}function s(e,t){return e>t?e:t}function c(e){if(!Number.isInteger(e)||e<0)throw new t.SdkError(t.ErrorReason.UNKNOWN,t.ErrorCode.INVALID_PARAMS,{details:`Invalid source asset decimals: ${e}`})}function l(e,t,n){return o(10n**BigInt(e)*t,n)}function u(e){return o((e===0?r:o(r*i,BigInt(e)))*(i+500n),i)}function d(e,t){return l(e,t,100000n)}function f({sourceAssetType:t,sourceChainId:r,targetChainId:i,targetAssetType:a}){return t===e.TokenType.NATIVE&&n.isCaip2AvalancheChainId(r)&&n.isSolanaNamespace(i)&&a===e.TokenType.NATIVE?1000n:10n}exports.getMinimumTransferAmountFactory=a;
2
2
  //# sourceMappingURL=get-minimum-transfer-amount.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-minimum-transfer-amount.cjs","names":["SdkError","ErrorReason","ErrorCode"],"sources":["../../../../src/transfer-service/markr/_handlers/get-minimum-transfer-amount.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\n\n/** Minimum core fee captured from a transfer, expressed in source-asset base units. */\nexport const MINIMUM_CORE_FEE_BASE_UNITS = 1n;\nconst BPS_SCALE = 10_000n;\nconst PARTNER_FEE_FLOOR_MARGIN_BPS = 500n; // 5%\n/**\n * Scale used for the token-asset floor calculation.\n *\n * This has been separated _just in case_ we want to adjust the value\n * lower than 10,000 (0.01%) in the future to allow smaller transfer amounts.\n */\nconst TOKEN_ASSET_SCALE = 100_000n;\n\n// Token floor target represented in units of `TOKEN_ASSET_SCALE` for one source token.\n// Converted to base units using `sourceAsset.decimals` so the floor is precision-aware.\n/**\n * Token floor target represented in units of `TOKEN_ASSET_SCALE` for one source token.\n * Converted to base units using `sourceAsset.decimals` so the floor is precision-aware.\n *\n * We are using a different scale here in case we want to allow smaller transfer amounts,\n * but for now, this is effectively the same using 10,000 scale.\n */\nconst TOKEN_ASSET_FLOOR_UNITS = 10n; // 0.010% when TOKEN_ASSET_SCALE is 100_000\n\nexport interface GetMinimumTransferAmountFactoryConfig {\n analyzeSupport: TransferService['analyzeSupport'];\n partnerFeeBps: number;\n}\n\n/**\n * Computes the minimum source amount for Markr transfers.\n *\n * Calculation summary:\n * 1) Compute `partnerFeeFloor` from `partnerFeeBps` (10_000 scale), then apply 5% margin.\n * 2) Compute `tokenAssetFloor` from source token decimals and token-asset floor units (100_000 scale).\n * 3) Return the larger value between `partnerFeeFloor` and `tokenAssetFloor`.\n *\n * Example:\n * - USDC (6 decimals) with partnerFeeBps=85 -> `partnerFeeFloor` (124) is greater than `tokenAssetFloor` (100).\n * - AVAX (18 decimals) with partnerFeeBps=85 -> `tokenAssetFloor` (100_000_000_000_000) is greater.\n */\nexport function getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n}: GetMinimumTransferAmountFactoryConfig): TransferService['getMinimumTransferAmount'] {\n return async ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n // Verify partnerFeeBps is positive integer\n if (!Number.isInteger(partnerFeeBps) || partnerFeeBps < 0) {\n // We shouldn't hit this given our Zod validation at service creation time.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid partner fee basis points: ${partnerFeeBps}`,\n });\n }\n\n if (!analyzeSupport({ sourceAsset, sourceChainId, targetAsset, targetChainId })) {\n // This should never happen given the analyzeSupport check that happens in the TransferManager.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: 'Transfer not supported by Markr. Unable to get minimum transfer amount.',\n });\n }\n\n validateSourceAssetDecimals(sourceAsset.decimals);\n\n const partnerFeeFloor = computePartnerFeeFloor(partnerFeeBps);\n const tokenAssetFloor = computeTokenAssetFloor(sourceAsset.decimals);\n\n return maxBigInt(partnerFeeFloor, tokenAssetFloor);\n };\n}\n\nfunction ceilDiv(value: bigint, divisor: bigint): bigint {\n return (value + divisor - 1n) / divisor;\n}\n\nfunction maxBigInt(left: bigint, right: bigint): bigint {\n return left > right ? left : right;\n}\n\nfunction validateSourceAssetDecimals(decimals: number): void {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid source asset decimals: ${decimals}`,\n });\n }\n}\n\nfunction toBaseUnitsOfOneTokenWithScale(decimals: number, units: bigint, scale: bigint): bigint {\n return ceilDiv(10n ** BigInt(decimals) * units, scale);\n}\n\nfunction computePartnerFeeFloor(partnerFeeBps: number): bigint {\n const basePartnerFeeFloor =\n partnerFeeBps === 0\n ? MINIMUM_CORE_FEE_BASE_UNITS\n : ceilDiv(MINIMUM_CORE_FEE_BASE_UNITS * BPS_SCALE, BigInt(partnerFeeBps));\n\n return ceilDiv(basePartnerFeeFloor * (BPS_SCALE + PARTNER_FEE_FLOOR_MARGIN_BPS), BPS_SCALE);\n}\n\nfunction computeTokenAssetFloor(sourceAssetDecimals: number): bigint {\n return toBaseUnitsOfOneTokenWithScale(sourceAssetDecimals, TOKEN_ASSET_FLOOR_UNITS, TOKEN_ASSET_SCALE);\n}\n"],"mappings":"uCAIa,EAA8B,GACrC,EAAY,OAsClB,SAAgB,EAAgC,CAC9C,iBACA,iBACqF,CACrF,OAAO,MAAO,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CAE3E,GAAI,CAAC,OAAO,UAAU,EAAc,EAAI,EAAgB,EAEtD,MAAM,IAAIA,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,qCAAqC,IAC/C,CAAC,CAGJ,GAAI,CAAC,EAAe,CAAE,cAAa,gBAAe,cAAa,gBAAe,CAAC,CAE7E,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,0EACV,CAAC,CAQJ,OALA,EAA4B,EAAY,SAAS,CAK1C,EAHiB,EAAuB,EAAc,CACrC,EAAuB,EAAY,SAAS,CAElB,EAItD,SAAS,EAAQ,EAAe,EAAyB,CACvD,OAAQ,EAAQ,EAAU,IAAM,EAGlC,SAAS,EAAU,EAAc,EAAuB,CACtD,OAAO,EAAO,EAAQ,EAAO,EAG/B,SAAS,EAA4B,EAAwB,CAC3D,GAAI,CAAC,OAAO,UAAU,EAAS,EAAI,EAAW,EAC5C,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,kCAAkC,IAC5C,CAAC,CAIN,SAAS,EAA+B,EAAkB,EAAe,EAAuB,CAC9F,OAAO,EAAQ,KAAO,OAAO,EAAS,CAAG,EAAO,EAAM,CAGxD,SAAS,EAAuB,EAA+B,CAM7D,OAAO,GAJL,IAAkB,EACd,EACA,EAAQ,EAA8B,EAAW,OAAO,EAAc,CAAC,GAEvC,EAAY,MAA+B,EAAU,CAG7F,SAAS,EAAuB,EAAqC,CACnE,OAAO,EAA+B,EAAqB,IAAyB,QAAkB"}
1
+ {"version":3,"file":"get-minimum-transfer-amount.cjs","names":["SdkError","ErrorReason","ErrorCode","TokenType","isCaip2AvalancheChainId","isSolanaNamespace"],"sources":["../../../../src/transfer-service/markr/_handlers/get-minimum-transfer-amount.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport { isCaip2AvalancheChainId, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport type { TransferService } from '../../../types/service';\n\n/** Minimum core fee captured from a transfer, expressed in source-asset base units. */\nexport const MINIMUM_CORE_FEE_BASE_UNITS = 1n;\nconst BPS_SCALE = 10_000n;\nconst PARTNER_FEE_FLOOR_MARGIN_BPS = 500n; // 5%\n/**\n * Scale used for the token-asset floor calculation.\n *\n * This has been separated _just in case_ we want to adjust the value\n * lower than 10,000 (0.01%) in the future to allow smaller transfer amounts.\n */\nconst TOKEN_ASSET_SCALE = 100_000n;\n\n/**\n * Default token-floor units for one source token.\n *\n * With `TOKEN_ASSET_SCALE=100_000`, this is 0.010% of one source token.\n */\nconst DEFAULT_TOKEN_ASSET_FLOOR_UNITS = 10n;\n\n/**\n * Elevated token-floor units for Avalanche native -> Solana native routes.\n *\n * With `TOKEN_ASSET_SCALE=100_000`, this is 1.000% of one source token.\n */\nconst AVALANCHE_NATIVE_TO_SOL_NATIVE_TOKEN_ASSET_FLOOR_UNITS = 1_000n;\n\nexport interface GetMinimumTransferAmountFactoryConfig {\n analyzeSupport: TransferService['analyzeSupport'];\n partnerFeeBps: number;\n}\n\n/**\n * Computes the minimum source amount for Markr transfers.\n *\n * Calculation summary:\n * 1) Compute `partnerFeeFloor` from `partnerFeeBps` (10_000 scale), then apply 5% margin.\n * 2) Compute `tokenAssetFloor` from source token decimals and route-aware floor units (100_000 scale).\n * 3) Return the larger value between `partnerFeeFloor` and `tokenAssetFloor`.\n *\n * Example:\n * - USDC (6 decimals) with partnerFeeBps=85 -> `partnerFeeFloor` (124) is greater than `tokenAssetFloor` (100).\n * - AVAX (18 decimals) with partnerFeeBps=85 -> `tokenAssetFloor` (100_000_000_000_000) is greater.\n */\nexport function getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n}: GetMinimumTransferAmountFactoryConfig): TransferService['getMinimumTransferAmount'] {\n return async ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n // Verify partnerFeeBps is positive integer\n if (!Number.isInteger(partnerFeeBps) || partnerFeeBps < 0) {\n // We shouldn't hit this given our Zod validation at service creation time.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid partner fee basis points: ${partnerFeeBps}`,\n });\n }\n\n if (!analyzeSupport({ sourceAsset, sourceChainId, targetAsset, targetChainId })) {\n // This should never happen given the analyzeSupport check that happens in the TransferManager.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: 'Transfer not supported by Markr. Unable to get minimum transfer amount.',\n });\n }\n\n validateSourceAssetDecimals(sourceAsset.decimals);\n\n const partnerFeeFloor = computePartnerFeeFloor(partnerFeeBps);\n const tokenAssetFloorUnits = getTokenAssetFloorUnitsForRoute({\n sourceAssetType: sourceAsset.type,\n sourceChainId,\n targetChainId,\n targetAssetType: targetAsset.type,\n });\n const tokenAssetFloor = computeTokenAssetFloor(sourceAsset.decimals, tokenAssetFloorUnits);\n\n return maxBigInt(partnerFeeFloor, tokenAssetFloor);\n };\n}\n\nfunction ceilDiv(value: bigint, divisor: bigint): bigint {\n return (value + divisor - 1n) / divisor;\n}\n\nfunction maxBigInt(left: bigint, right: bigint): bigint {\n return left > right ? left : right;\n}\n\nfunction validateSourceAssetDecimals(decimals: number): void {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid source asset decimals: ${decimals}`,\n });\n }\n}\n\nfunction toBaseUnitsOfOneTokenWithScale(decimals: number, units: bigint, scale: bigint): bigint {\n return ceilDiv(10n ** BigInt(decimals) * units, scale);\n}\n\nfunction computePartnerFeeFloor(partnerFeeBps: number): bigint {\n const basePartnerFeeFloor =\n partnerFeeBps === 0\n ? MINIMUM_CORE_FEE_BASE_UNITS\n : ceilDiv(MINIMUM_CORE_FEE_BASE_UNITS * BPS_SCALE, BigInt(partnerFeeBps));\n\n return ceilDiv(basePartnerFeeFloor * (BPS_SCALE + PARTNER_FEE_FLOOR_MARGIN_BPS), BPS_SCALE);\n}\n\nfunction computeTokenAssetFloor(sourceAssetDecimals: number, tokenAssetFloorUnits: bigint): bigint {\n return toBaseUnitsOfOneTokenWithScale(sourceAssetDecimals, tokenAssetFloorUnits, TOKEN_ASSET_SCALE);\n}\n\n/**\n * Select token-floor units based on route characteristics.\n *\n * We currently elevate the floor only for native Avalanche C-Chain -> native SOL routes,\n * where quote availability requires a higher practical input threshold.\n */\nfunction getTokenAssetFloorUnitsForRoute({\n sourceAssetType,\n sourceChainId,\n targetChainId,\n targetAssetType,\n}: {\n sourceAssetType: TokenType;\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n targetAssetType: TokenType;\n}): bigint {\n // Native Avalanche C-Chain -> Native SOL routes require a higher floor due to liquidity/quote availability constraints on Markr's side.\n if (\n sourceAssetType === TokenType.NATIVE &&\n isCaip2AvalancheChainId(sourceChainId) &&\n isSolanaNamespace(targetChainId) &&\n targetAssetType === TokenType.NATIVE\n ) {\n return AVALANCHE_NATIVE_TO_SOL_NATIVE_TOKEN_ASSET_FLOOR_UNITS;\n }\n\n return DEFAULT_TOKEN_ASSET_FLOOR_UNITS;\n}\n"],"mappings":"kHAOa,EAA8B,GACrC,EAAY,OAyClB,SAAgB,EAAgC,CAC9C,iBACA,iBACqF,CACrF,OAAO,MAAO,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CAE3E,GAAI,CAAC,OAAO,UAAU,EAAc,EAAI,EAAgB,EAEtD,MAAM,IAAIA,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,qCAAqC,IAC/C,CAAC,CAGJ,GAAI,CAAC,EAAe,CAAE,cAAa,gBAAe,cAAa,gBAAe,CAAC,CAE7E,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,0EACV,CAAC,CAGJ,EAA4B,EAAY,SAAS,CAEjD,IAAM,EAAkB,EAAuB,EAAc,CACvD,EAAuB,EAAgC,CAC3D,gBAAiB,EAAY,KAC7B,gBACA,gBACA,gBAAiB,EAAY,KAC9B,CAAC,CAGF,OAAO,EAAU,EAFO,EAAuB,EAAY,SAAU,EAAqB,CAExC,EAItD,SAAS,EAAQ,EAAe,EAAyB,CACvD,OAAQ,EAAQ,EAAU,IAAM,EAGlC,SAAS,EAAU,EAAc,EAAuB,CACtD,OAAO,EAAO,EAAQ,EAAO,EAG/B,SAAS,EAA4B,EAAwB,CAC3D,GAAI,CAAC,OAAO,UAAU,EAAS,EAAI,EAAW,EAC5C,MAAM,IAAIF,EAAAA,SAASC,EAAAA,YAAY,QAASC,EAAAA,UAAU,eAAgB,CAChE,QAAS,kCAAkC,IAC5C,CAAC,CAIN,SAAS,EAA+B,EAAkB,EAAe,EAAuB,CAC9F,OAAO,EAAQ,KAAO,OAAO,EAAS,CAAG,EAAO,EAAM,CAGxD,SAAS,EAAuB,EAA+B,CAM7D,OAAO,GAJL,IAAkB,EACd,EACA,EAAQ,EAA8B,EAAW,OAAO,EAAc,CAAC,GAEvC,EAAY,MAA+B,EAAU,CAG7F,SAAS,EAAuB,EAA6B,EAAsC,CACjG,OAAO,EAA+B,EAAqB,EAAsB,QAAkB,CASrG,SAAS,EAAgC,CACvC,kBACA,gBACA,gBACA,mBAMS,CAWT,OARE,IAAoBC,EAAAA,UAAU,QAC9BC,EAAAA,wBAAwB,EAAc,EACtCC,EAAAA,kBAAkB,EAAc,EAChC,IAAoBF,EAAAA,UAAU,OAEvB,MAGF"}
@@ -1,2 +1,2 @@
1
- import{ErrorCode as e,ErrorReason as t,SdkError as n}from"../../../errors.js";const r=1n,i=10000n;function a({analyzeSupport:r,partnerFeeBps:i}){return async({sourceAsset:a,sourceChainId:o,targetAsset:l,targetChainId:f})=>{if(!Number.isInteger(i)||i<0)throw new n(t.UNKNOWN,e.INVALID_PARAMS,{details:`Invalid partner fee basis points: ${i}`});if(!r({sourceAsset:a,sourceChainId:o,targetAsset:l,targetChainId:f}))throw new n(t.UNKNOWN,e.INVALID_PARAMS,{details:`Transfer not supported by Markr. Unable to get minimum transfer amount.`});return c(a.decimals),s(u(i),d(a.decimals))}}function o(e,t){return(e+t-1n)/t}function s(e,t){return e>t?e:t}function c(r){if(!Number.isInteger(r)||r<0)throw new n(t.UNKNOWN,e.INVALID_PARAMS,{details:`Invalid source asset decimals: ${r}`})}function l(e,t,n){return o(10n**BigInt(e)*t,n)}function u(e){return o((e===0?r:o(r*i,BigInt(e)))*(i+500n),i)}function d(e){return l(e,10n,100000n)}export{a as getMinimumTransferAmountFactory};
1
+ import{TokenType as e}from"../../../constants.js";import{ErrorCode as t,ErrorReason as n,SdkError as r}from"../../../errors.js";import{isCaip2AvalancheChainId as i,isSolanaNamespace as a}from"../../../_utils/chain.js";const o=1n,s=10000n;function c({analyzeSupport:e,partnerFeeBps:i}){return async({sourceAsset:a,sourceChainId:o,targetAsset:s,targetChainId:c})=>{if(!Number.isInteger(i)||i<0)throw new r(n.UNKNOWN,t.INVALID_PARAMS,{details:`Invalid partner fee basis points: ${i}`});if(!e({sourceAsset:a,sourceChainId:o,targetAsset:s,targetChainId:c}))throw new r(n.UNKNOWN,t.INVALID_PARAMS,{details:`Transfer not supported by Markr. Unable to get minimum transfer amount.`});d(a.decimals);let l=p(i),f=h({sourceAssetType:a.type,sourceChainId:o,targetChainId:c,targetAssetType:s.type});return u(l,m(a.decimals,f))}}function l(e,t){return(e+t-1n)/t}function u(e,t){return e>t?e:t}function d(e){if(!Number.isInteger(e)||e<0)throw new r(n.UNKNOWN,t.INVALID_PARAMS,{details:`Invalid source asset decimals: ${e}`})}function f(e,t,n){return l(10n**BigInt(e)*t,n)}function p(e){return l((e===0?o:l(o*s,BigInt(e)))*(s+500n),s)}function m(e,t){return f(e,t,100000n)}function h({sourceAssetType:t,sourceChainId:n,targetChainId:r,targetAssetType:o}){return t===e.NATIVE&&i(n)&&a(r)&&o===e.NATIVE?1000n:10n}export{c as getMinimumTransferAmountFactory};
2
2
  //# sourceMappingURL=get-minimum-transfer-amount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-minimum-transfer-amount.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/get-minimum-transfer-amount.ts"],"sourcesContent":["import { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { TransferService } from '../../../types/service';\n\n/** Minimum core fee captured from a transfer, expressed in source-asset base units. */\nexport const MINIMUM_CORE_FEE_BASE_UNITS = 1n;\nconst BPS_SCALE = 10_000n;\nconst PARTNER_FEE_FLOOR_MARGIN_BPS = 500n; // 5%\n/**\n * Scale used for the token-asset floor calculation.\n *\n * This has been separated _just in case_ we want to adjust the value\n * lower than 10,000 (0.01%) in the future to allow smaller transfer amounts.\n */\nconst TOKEN_ASSET_SCALE = 100_000n;\n\n// Token floor target represented in units of `TOKEN_ASSET_SCALE` for one source token.\n// Converted to base units using `sourceAsset.decimals` so the floor is precision-aware.\n/**\n * Token floor target represented in units of `TOKEN_ASSET_SCALE` for one source token.\n * Converted to base units using `sourceAsset.decimals` so the floor is precision-aware.\n *\n * We are using a different scale here in case we want to allow smaller transfer amounts,\n * but for now, this is effectively the same using 10,000 scale.\n */\nconst TOKEN_ASSET_FLOOR_UNITS = 10n; // 0.010% when TOKEN_ASSET_SCALE is 100_000\n\nexport interface GetMinimumTransferAmountFactoryConfig {\n analyzeSupport: TransferService['analyzeSupport'];\n partnerFeeBps: number;\n}\n\n/**\n * Computes the minimum source amount for Markr transfers.\n *\n * Calculation summary:\n * 1) Compute `partnerFeeFloor` from `partnerFeeBps` (10_000 scale), then apply 5% margin.\n * 2) Compute `tokenAssetFloor` from source token decimals and token-asset floor units (100_000 scale).\n * 3) Return the larger value between `partnerFeeFloor` and `tokenAssetFloor`.\n *\n * Example:\n * - USDC (6 decimals) with partnerFeeBps=85 -> `partnerFeeFloor` (124) is greater than `tokenAssetFloor` (100).\n * - AVAX (18 decimals) with partnerFeeBps=85 -> `tokenAssetFloor` (100_000_000_000_000) is greater.\n */\nexport function getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n}: GetMinimumTransferAmountFactoryConfig): TransferService['getMinimumTransferAmount'] {\n return async ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n // Verify partnerFeeBps is positive integer\n if (!Number.isInteger(partnerFeeBps) || partnerFeeBps < 0) {\n // We shouldn't hit this given our Zod validation at service creation time.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid partner fee basis points: ${partnerFeeBps}`,\n });\n }\n\n if (!analyzeSupport({ sourceAsset, sourceChainId, targetAsset, targetChainId })) {\n // This should never happen given the analyzeSupport check that happens in the TransferManager.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: 'Transfer not supported by Markr. Unable to get minimum transfer amount.',\n });\n }\n\n validateSourceAssetDecimals(sourceAsset.decimals);\n\n const partnerFeeFloor = computePartnerFeeFloor(partnerFeeBps);\n const tokenAssetFloor = computeTokenAssetFloor(sourceAsset.decimals);\n\n return maxBigInt(partnerFeeFloor, tokenAssetFloor);\n };\n}\n\nfunction ceilDiv(value: bigint, divisor: bigint): bigint {\n return (value + divisor - 1n) / divisor;\n}\n\nfunction maxBigInt(left: bigint, right: bigint): bigint {\n return left > right ? left : right;\n}\n\nfunction validateSourceAssetDecimals(decimals: number): void {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid source asset decimals: ${decimals}`,\n });\n }\n}\n\nfunction toBaseUnitsOfOneTokenWithScale(decimals: number, units: bigint, scale: bigint): bigint {\n return ceilDiv(10n ** BigInt(decimals) * units, scale);\n}\n\nfunction computePartnerFeeFloor(partnerFeeBps: number): bigint {\n const basePartnerFeeFloor =\n partnerFeeBps === 0\n ? MINIMUM_CORE_FEE_BASE_UNITS\n : ceilDiv(MINIMUM_CORE_FEE_BASE_UNITS * BPS_SCALE, BigInt(partnerFeeBps));\n\n return ceilDiv(basePartnerFeeFloor * (BPS_SCALE + PARTNER_FEE_FLOOR_MARGIN_BPS), BPS_SCALE);\n}\n\nfunction computeTokenAssetFloor(sourceAssetDecimals: number): bigint {\n return toBaseUnitsOfOneTokenWithScale(sourceAssetDecimals, TOKEN_ASSET_FLOOR_UNITS, TOKEN_ASSET_SCALE);\n}\n"],"mappings":"8EAIA,MAAa,EAA8B,GACrC,EAAY,OAsClB,SAAgB,EAAgC,CAC9C,iBACA,iBACqF,CACrF,OAAO,MAAO,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CAE3E,GAAI,CAAC,OAAO,UAAU,EAAc,EAAI,EAAgB,EAEtD,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,qCAAqC,IAC/C,CAAC,CAGJ,GAAI,CAAC,EAAe,CAAE,cAAa,gBAAe,cAAa,gBAAe,CAAC,CAE7E,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,0EACV,CAAC,CAQJ,OALA,EAA4B,EAAY,SAAS,CAK1C,EAHiB,EAAuB,EAAc,CACrC,EAAuB,EAAY,SAAS,CAElB,EAItD,SAAS,EAAQ,EAAe,EAAyB,CACvD,OAAQ,EAAQ,EAAU,IAAM,EAGlC,SAAS,EAAU,EAAc,EAAuB,CACtD,OAAO,EAAO,EAAQ,EAAO,EAG/B,SAAS,EAA4B,EAAwB,CAC3D,GAAI,CAAC,OAAO,UAAU,EAAS,EAAI,EAAW,EAC5C,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,kCAAkC,IAC5C,CAAC,CAIN,SAAS,EAA+B,EAAkB,EAAe,EAAuB,CAC9F,OAAO,EAAQ,KAAO,OAAO,EAAS,CAAG,EAAO,EAAM,CAGxD,SAAS,EAAuB,EAA+B,CAM7D,OAAO,GAJL,IAAkB,EACd,EACA,EAAQ,EAA8B,EAAW,OAAO,EAAc,CAAC,GAEvC,EAAY,MAA+B,EAAU,CAG7F,SAAS,EAAuB,EAAqC,CACnE,OAAO,EAA+B,EAAqB,IAAyB,QAAkB"}
1
+ {"version":3,"file":"get-minimum-transfer-amount.js","names":[],"sources":["../../../../src/transfer-service/markr/_handlers/get-minimum-transfer-amount.ts"],"sourcesContent":["import { TokenType } from '../../../constants';\nimport { isCaip2AvalancheChainId, isSolanaNamespace } from '../../../_utils/chain';\nimport { ErrorCode, ErrorReason, SdkError } from '../../../errors';\nimport type { Caip2ChainId } from '../../../types/caip';\nimport type { TransferService } from '../../../types/service';\n\n/** Minimum core fee captured from a transfer, expressed in source-asset base units. */\nexport const MINIMUM_CORE_FEE_BASE_UNITS = 1n;\nconst BPS_SCALE = 10_000n;\nconst PARTNER_FEE_FLOOR_MARGIN_BPS = 500n; // 5%\n/**\n * Scale used for the token-asset floor calculation.\n *\n * This has been separated _just in case_ we want to adjust the value\n * lower than 10,000 (0.01%) in the future to allow smaller transfer amounts.\n */\nconst TOKEN_ASSET_SCALE = 100_000n;\n\n/**\n * Default token-floor units for one source token.\n *\n * With `TOKEN_ASSET_SCALE=100_000`, this is 0.010% of one source token.\n */\nconst DEFAULT_TOKEN_ASSET_FLOOR_UNITS = 10n;\n\n/**\n * Elevated token-floor units for Avalanche native -> Solana native routes.\n *\n * With `TOKEN_ASSET_SCALE=100_000`, this is 1.000% of one source token.\n */\nconst AVALANCHE_NATIVE_TO_SOL_NATIVE_TOKEN_ASSET_FLOOR_UNITS = 1_000n;\n\nexport interface GetMinimumTransferAmountFactoryConfig {\n analyzeSupport: TransferService['analyzeSupport'];\n partnerFeeBps: number;\n}\n\n/**\n * Computes the minimum source amount for Markr transfers.\n *\n * Calculation summary:\n * 1) Compute `partnerFeeFloor` from `partnerFeeBps` (10_000 scale), then apply 5% margin.\n * 2) Compute `tokenAssetFloor` from source token decimals and route-aware floor units (100_000 scale).\n * 3) Return the larger value between `partnerFeeFloor` and `tokenAssetFloor`.\n *\n * Example:\n * - USDC (6 decimals) with partnerFeeBps=85 -> `partnerFeeFloor` (124) is greater than `tokenAssetFloor` (100).\n * - AVAX (18 decimals) with partnerFeeBps=85 -> `tokenAssetFloor` (100_000_000_000_000) is greater.\n */\nexport function getMinimumTransferAmountFactory({\n analyzeSupport,\n partnerFeeBps,\n}: GetMinimumTransferAmountFactoryConfig): TransferService['getMinimumTransferAmount'] {\n return async ({ sourceAsset, sourceChainId, targetAsset, targetChainId }) => {\n // Verify partnerFeeBps is positive integer\n if (!Number.isInteger(partnerFeeBps) || partnerFeeBps < 0) {\n // We shouldn't hit this given our Zod validation at service creation time.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid partner fee basis points: ${partnerFeeBps}`,\n });\n }\n\n if (!analyzeSupport({ sourceAsset, sourceChainId, targetAsset, targetChainId })) {\n // This should never happen given the analyzeSupport check that happens in the TransferManager.\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: 'Transfer not supported by Markr. Unable to get minimum transfer amount.',\n });\n }\n\n validateSourceAssetDecimals(sourceAsset.decimals);\n\n const partnerFeeFloor = computePartnerFeeFloor(partnerFeeBps);\n const tokenAssetFloorUnits = getTokenAssetFloorUnitsForRoute({\n sourceAssetType: sourceAsset.type,\n sourceChainId,\n targetChainId,\n targetAssetType: targetAsset.type,\n });\n const tokenAssetFloor = computeTokenAssetFloor(sourceAsset.decimals, tokenAssetFloorUnits);\n\n return maxBigInt(partnerFeeFloor, tokenAssetFloor);\n };\n}\n\nfunction ceilDiv(value: bigint, divisor: bigint): bigint {\n return (value + divisor - 1n) / divisor;\n}\n\nfunction maxBigInt(left: bigint, right: bigint): bigint {\n return left > right ? left : right;\n}\n\nfunction validateSourceAssetDecimals(decimals: number): void {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new SdkError(ErrorReason.UNKNOWN, ErrorCode.INVALID_PARAMS, {\n details: `Invalid source asset decimals: ${decimals}`,\n });\n }\n}\n\nfunction toBaseUnitsOfOneTokenWithScale(decimals: number, units: bigint, scale: bigint): bigint {\n return ceilDiv(10n ** BigInt(decimals) * units, scale);\n}\n\nfunction computePartnerFeeFloor(partnerFeeBps: number): bigint {\n const basePartnerFeeFloor =\n partnerFeeBps === 0\n ? MINIMUM_CORE_FEE_BASE_UNITS\n : ceilDiv(MINIMUM_CORE_FEE_BASE_UNITS * BPS_SCALE, BigInt(partnerFeeBps));\n\n return ceilDiv(basePartnerFeeFloor * (BPS_SCALE + PARTNER_FEE_FLOOR_MARGIN_BPS), BPS_SCALE);\n}\n\nfunction computeTokenAssetFloor(sourceAssetDecimals: number, tokenAssetFloorUnits: bigint): bigint {\n return toBaseUnitsOfOneTokenWithScale(sourceAssetDecimals, tokenAssetFloorUnits, TOKEN_ASSET_SCALE);\n}\n\n/**\n * Select token-floor units based on route characteristics.\n *\n * We currently elevate the floor only for native Avalanche C-Chain -> native SOL routes,\n * where quote availability requires a higher practical input threshold.\n */\nfunction getTokenAssetFloorUnitsForRoute({\n sourceAssetType,\n sourceChainId,\n targetChainId,\n targetAssetType,\n}: {\n sourceAssetType: TokenType;\n sourceChainId: Caip2ChainId;\n targetChainId: Caip2ChainId;\n targetAssetType: TokenType;\n}): bigint {\n // Native Avalanche C-Chain -> Native SOL routes require a higher floor due to liquidity/quote availability constraints on Markr's side.\n if (\n sourceAssetType === TokenType.NATIVE &&\n isCaip2AvalancheChainId(sourceChainId) &&\n isSolanaNamespace(targetChainId) &&\n targetAssetType === TokenType.NATIVE\n ) {\n return AVALANCHE_NATIVE_TO_SOL_NATIVE_TOKEN_ASSET_FLOOR_UNITS;\n }\n\n return DEFAULT_TOKEN_ASSET_FLOOR_UNITS;\n}\n"],"mappings":"0NAOA,MAAa,EAA8B,GACrC,EAAY,OAyClB,SAAgB,EAAgC,CAC9C,iBACA,iBACqF,CACrF,OAAO,MAAO,CAAE,cAAa,gBAAe,cAAa,mBAAoB,CAE3E,GAAI,CAAC,OAAO,UAAU,EAAc,EAAI,EAAgB,EAEtD,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,qCAAqC,IAC/C,CAAC,CAGJ,GAAI,CAAC,EAAe,CAAE,cAAa,gBAAe,cAAa,gBAAe,CAAC,CAE7E,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,0EACV,CAAC,CAGJ,EAA4B,EAAY,SAAS,CAEjD,IAAM,EAAkB,EAAuB,EAAc,CACvD,EAAuB,EAAgC,CAC3D,gBAAiB,EAAY,KAC7B,gBACA,gBACA,gBAAiB,EAAY,KAC9B,CAAC,CAGF,OAAO,EAAU,EAFO,EAAuB,EAAY,SAAU,EAAqB,CAExC,EAItD,SAAS,EAAQ,EAAe,EAAyB,CACvD,OAAQ,EAAQ,EAAU,IAAM,EAGlC,SAAS,EAAU,EAAc,EAAuB,CACtD,OAAO,EAAO,EAAQ,EAAO,EAG/B,SAAS,EAA4B,EAAwB,CAC3D,GAAI,CAAC,OAAO,UAAU,EAAS,EAAI,EAAW,EAC5C,MAAM,IAAI,EAAS,EAAY,QAAS,EAAU,eAAgB,CAChE,QAAS,kCAAkC,IAC5C,CAAC,CAIN,SAAS,EAA+B,EAAkB,EAAe,EAAuB,CAC9F,OAAO,EAAQ,KAAO,OAAO,EAAS,CAAG,EAAO,EAAM,CAGxD,SAAS,EAAuB,EAA+B,CAM7D,OAAO,GAJL,IAAkB,EACd,EACA,EAAQ,EAA8B,EAAW,OAAO,EAAc,CAAC,GAEvC,EAAY,MAA+B,EAAU,CAG7F,SAAS,EAAuB,EAA6B,EAAsC,CACjG,OAAO,EAA+B,EAAqB,EAAsB,QAAkB,CASrG,SAAS,EAAgC,CACvC,kBACA,gBACA,gBACA,mBAMS,CAWT,OARE,IAAoB,EAAU,QAC9B,EAAwB,EAAc,EACtC,EAAkB,EAAc,EAChC,IAAoB,EAAU,OAEvB,MAGF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@avalabs/fusion-sdk",
3
3
  "license": "Limited Ecosystem License",
4
- "version": "0.14.0",
4
+ "version": "0.14.1",
5
5
  "type": "module",
6
6
  "main": "./dist/mod.cjs",
7
7
  "module": "./dist/mod.js",
@@ -47,8 +47,8 @@
47
47
  "vitest": "4.0.6",
48
48
  "tsdown": "0.20.3",
49
49
  "zod": "4.1.12",
50
- "eslint-config-custom": "0.1.0",
51
- "@internal/tsdown-config": "0.0.1"
50
+ "@internal/tsdown-config": "0.0.1",
51
+ "eslint-config-custom": "0.1.0"
52
52
  },
53
53
  "sideEffects": false,
54
54
  "scripts": {