boing-sdk 0.3.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 (186) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +191 -0
  3. package/dist/accessList.d.ts +22 -0
  4. package/dist/accessList.d.ts.map +1 -0
  5. package/dist/accessList.js +45 -0
  6. package/dist/bincode.d.ts +92 -0
  7. package/dist/bincode.d.ts.map +1 -0
  8. package/dist/bincode.js +154 -0
  9. package/dist/callAbi.d.ts +119 -0
  10. package/dist/callAbi.d.ts.map +1 -0
  11. package/dist/callAbi.js +156 -0
  12. package/dist/calldata.d.ts +35 -0
  13. package/dist/calldata.d.ts.map +1 -0
  14. package/dist/calldata.js +93 -0
  15. package/dist/canonicalDeployArtifacts.d.ts +154 -0
  16. package/dist/canonicalDeployArtifacts.d.ts.map +1 -0
  17. package/dist/canonicalDeployArtifacts.js +271 -0
  18. package/dist/canonicalTestnet.d.ts +15 -0
  19. package/dist/canonicalTestnet.d.ts.map +1 -0
  20. package/dist/canonicalTestnet.js +15 -0
  21. package/dist/canonicalTestnetDex.d.ts +17 -0
  22. package/dist/canonicalTestnetDex.d.ts.map +1 -0
  23. package/dist/canonicalTestnetDex.js +17 -0
  24. package/dist/chainIds.d.ts +18 -0
  25. package/dist/chainIds.d.ts.map +1 -0
  26. package/dist/chainIds.js +56 -0
  27. package/dist/client.d.ts +223 -0
  28. package/dist/client.d.ts.map +1 -0
  29. package/dist/client.js +659 -0
  30. package/dist/connectionMonitor.d.ts +47 -0
  31. package/dist/connectionMonitor.d.ts.map +1 -0
  32. package/dist/connectionMonitor.js +93 -0
  33. package/dist/create2.d.ts +94 -0
  34. package/dist/create2.d.ts.map +1 -0
  35. package/dist/create2.js +225 -0
  36. package/dist/dappDeploy.d.ts +100 -0
  37. package/dist/dappDeploy.d.ts.map +1 -0
  38. package/dist/dappDeploy.js +140 -0
  39. package/dist/dappUiHelpers.d.ts +28 -0
  40. package/dist/dappUiHelpers.d.ts.map +1 -0
  41. package/dist/dappUiHelpers.js +69 -0
  42. package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.d.ts +6 -0
  43. package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.d.ts.map +1 -0
  44. package/dist/defaultReferenceFungibleSecuredRuntimeBytecodeHex.js +5 -0
  45. package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.d.ts +6 -0
  46. package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.d.ts.map +1 -0
  47. package/dist/defaultReferenceFungibleSecuredTemplateBytecodeHex.js +5 -0
  48. package/dist/defaultReferenceFungibleTemplateBytecodeHex.d.ts +6 -0
  49. package/dist/defaultReferenceFungibleTemplateBytecodeHex.d.ts.map +1 -0
  50. package/dist/defaultReferenceFungibleTemplateBytecodeHex.js +5 -0
  51. package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.d.ts +7 -0
  52. package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.d.ts.map +1 -0
  53. package/dist/defaultReferenceNftCollectionTemplateBytecodeHex.js +6 -0
  54. package/dist/dexIntegration.d.ts +61 -0
  55. package/dist/dexIntegration.d.ts.map +1 -0
  56. package/dist/dexIntegration.js +193 -0
  57. package/dist/erc721Logs.d.ts +21 -0
  58. package/dist/erc721Logs.d.ts.map +1 -0
  59. package/dist/erc721Logs.js +69 -0
  60. package/dist/errors.d.ts +60 -0
  61. package/dist/errors.d.ts.map +1 -0
  62. package/dist/errors.js +153 -0
  63. package/dist/hex.d.ts +27 -0
  64. package/dist/hex.d.ts.map +1 -0
  65. package/dist/hex.js +82 -0
  66. package/dist/index.d.ts +83 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +78 -0
  69. package/dist/indexerBatch.d.ts +111 -0
  70. package/dist/indexerBatch.d.ts.map +1 -0
  71. package/dist/indexerBatch.js +253 -0
  72. package/dist/indexerGaps.d.ts +50 -0
  73. package/dist/indexerGaps.d.ts.map +1 -0
  74. package/dist/indexerGaps.js +117 -0
  75. package/dist/indexerSync.d.ts +61 -0
  76. package/dist/indexerSync.d.ts.map +1 -0
  77. package/dist/indexerSync.js +100 -0
  78. package/dist/nativeAmm.d.ts +64 -0
  79. package/dist/nativeAmm.d.ts.map +1 -0
  80. package/dist/nativeAmm.js +174 -0
  81. package/dist/nativeAmmLogs.d.ts +48 -0
  82. package/dist/nativeAmmLogs.d.ts.map +1 -0
  83. package/dist/nativeAmmLogs.js +114 -0
  84. package/dist/nativeAmmLpVault.d.ts +94 -0
  85. package/dist/nativeAmmLpVault.d.ts.map +1 -0
  86. package/dist/nativeAmmLpVault.js +205 -0
  87. package/dist/nativeAmmPool.d.ts +124 -0
  88. package/dist/nativeAmmPool.d.ts.map +1 -0
  89. package/dist/nativeAmmPool.js +245 -0
  90. package/dist/nativeContractSubmit.d.ts +26 -0
  91. package/dist/nativeContractSubmit.d.ts.map +1 -0
  92. package/dist/nativeContractSubmit.js +23 -0
  93. package/dist/nativeDexDirectory.d.ts +83 -0
  94. package/dist/nativeDexDirectory.d.ts.map +1 -0
  95. package/dist/nativeDexDirectory.js +147 -0
  96. package/dist/nativeDexDirectoryApi.d.ts +121 -0
  97. package/dist/nativeDexDirectoryApi.d.ts.map +1 -0
  98. package/dist/nativeDexDirectoryApi.js +408 -0
  99. package/dist/nativeDexFactory.d.ts +25 -0
  100. package/dist/nativeDexFactory.d.ts.map +1 -0
  101. package/dist/nativeDexFactory.js +72 -0
  102. package/dist/nativeDexFactoryLogs.d.ts +19 -0
  103. package/dist/nativeDexFactoryLogs.d.ts.map +1 -0
  104. package/dist/nativeDexFactoryLogs.js +61 -0
  105. package/dist/nativeDexFactoryPool.d.ts +61 -0
  106. package/dist/nativeDexFactoryPool.d.ts.map +1 -0
  107. package/dist/nativeDexFactoryPool.js +120 -0
  108. package/dist/nativeDexIndexerStats.d.ts +96 -0
  109. package/dist/nativeDexIndexerStats.d.ts.map +1 -0
  110. package/dist/nativeDexIndexerStats.js +448 -0
  111. package/dist/nativeDexLedgerRouter.d.ts +67 -0
  112. package/dist/nativeDexLedgerRouter.d.ts.map +1 -0
  113. package/dist/nativeDexLedgerRouter.js +108 -0
  114. package/dist/nativeDexLpPositions.d.ts +39 -0
  115. package/dist/nativeDexLpPositions.d.ts.map +1 -0
  116. package/dist/nativeDexLpPositions.js +69 -0
  117. package/dist/nativeDexNftIndexer.d.ts +26 -0
  118. package/dist/nativeDexNftIndexer.d.ts.map +1 -0
  119. package/dist/nativeDexNftIndexer.js +50 -0
  120. package/dist/nativeDexPoolHistory.d.ts +40 -0
  121. package/dist/nativeDexPoolHistory.d.ts.map +1 -0
  122. package/dist/nativeDexPoolHistory.js +110 -0
  123. package/dist/nativeDexReceiptArchive.d.ts +25 -0
  124. package/dist/nativeDexReceiptArchive.d.ts.map +1 -0
  125. package/dist/nativeDexReceiptArchive.js +47 -0
  126. package/dist/nativeDexRouting.d.ts +160 -0
  127. package/dist/nativeDexRouting.d.ts.map +1 -0
  128. package/dist/nativeDexRouting.js +345 -0
  129. package/dist/nativeDexSeamless.d.ts +86 -0
  130. package/dist/nativeDexSeamless.d.ts.map +1 -0
  131. package/dist/nativeDexSeamless.js +131 -0
  132. package/dist/nativeDexSwap2Router.d.ts +45 -0
  133. package/dist/nativeDexSwap2Router.d.ts.map +1 -0
  134. package/dist/nativeDexSwap2Router.js +276 -0
  135. package/dist/nativeLpShareToken.d.ts +54 -0
  136. package/dist/nativeLpShareToken.d.ts.map +1 -0
  137. package/dist/nativeLpShareToken.js +135 -0
  138. package/dist/nativeTokenSecurity.d.ts +59 -0
  139. package/dist/nativeTokenSecurity.d.ts.map +1 -0
  140. package/dist/nativeTokenSecurity.js +59 -0
  141. package/dist/networkProfile.d.ts +8 -0
  142. package/dist/networkProfile.d.ts.map +1 -0
  143. package/dist/networkProfile.js +29 -0
  144. package/dist/newHeadsWs.d.ts +43 -0
  145. package/dist/newHeadsWs.d.ts.map +1 -0
  146. package/dist/newHeadsWs.js +139 -0
  147. package/dist/preflightGate.d.ts +16 -0
  148. package/dist/preflightGate.d.ts.map +1 -0
  149. package/dist/preflightGate.js +29 -0
  150. package/dist/receiptLogs.d.ts +29 -0
  151. package/dist/receiptLogs.d.ts.map +1 -0
  152. package/dist/receiptLogs.js +66 -0
  153. package/dist/referenceFungibleSecuredDeployBytecode.d.ts +54 -0
  154. package/dist/referenceFungibleSecuredDeployBytecode.d.ts.map +1 -0
  155. package/dist/referenceFungibleSecuredDeployBytecode.js +274 -0
  156. package/dist/referenceNft.d.ts +14 -0
  157. package/dist/referenceNft.d.ts.map +1 -0
  158. package/dist/referenceNft.js +34 -0
  159. package/dist/referenceToken.d.ts +14 -0
  160. package/dist/referenceToken.d.ts.map +1 -0
  161. package/dist/referenceToken.js +29 -0
  162. package/dist/retryAfter.d.ts +6 -0
  163. package/dist/retryAfter.d.ts.map +1 -0
  164. package/dist/retryAfter.js +24 -0
  165. package/dist/rpcCapabilities.d.ts +43 -0
  166. package/dist/rpcCapabilities.d.ts.map +1 -0
  167. package/dist/rpcCapabilities.js +159 -0
  168. package/dist/rpcDoctor.d.ts +27 -0
  169. package/dist/rpcDoctor.d.ts.map +1 -0
  170. package/dist/rpcDoctor.js +66 -0
  171. package/dist/rpcSurfaceUi.d.ts +32 -0
  172. package/dist/rpcSurfaceUi.d.ts.map +1 -0
  173. package/dist/rpcSurfaceUi.js +49 -0
  174. package/dist/submitFlow.d.ts +70 -0
  175. package/dist/submitFlow.d.ts.map +1 -0
  176. package/dist/submitFlow.js +121 -0
  177. package/dist/transactionBuilder.d.ts +55 -0
  178. package/dist/transactionBuilder.d.ts.map +1 -0
  179. package/dist/transactionBuilder.js +100 -0
  180. package/dist/types.d.ts +436 -0
  181. package/dist/types.d.ts.map +1 -0
  182. package/dist/types.js +4 -0
  183. package/dist/walletProvider.d.ts +46 -0
  184. package/dist/walletProvider.d.ts.map +1 -0
  185. package/dist/walletProvider.js +126 -0
  186. package/package.json +44 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Constant-product **routing** and **quote aggregation** over Boing native pools (pure math + optional RPC hydrate).
3
+ * No external chains. Execution still uses **`contract_call`** / multihop router encoders elsewhere in the SDK.
4
+ */
5
+ import type { BoingClient } from './client.js';
6
+ import type { NativeDexIntegrationOverrides } from './dexIntegration.js';
7
+ import { type NativeDexDirectorySnapshot } from './nativeDexDirectory.js';
8
+ /** One tradeable CP pool with oriented reserves (A/B match on-chain slot semantics). */
9
+ export type CpPoolVenue = {
10
+ poolHex: `0x${string}`;
11
+ tokenAHex: `0x${string}`;
12
+ tokenBHex: `0x${string}`;
13
+ reserveA: bigint;
14
+ reserveB: bigint;
15
+ /** Output-side fee bps; use **`NATIVE_CP_SWAP_FEE_BPS`** when on-chain reads **`0`**. */
16
+ feeBps: bigint;
17
+ };
18
+ export type CpQuoteResult = {
19
+ amountOut: bigint;
20
+ tokenOutHex: string;
21
+ /** Native AMM **`swap`** direction: **`0`** = A→B, **`1`** = B→A. */
22
+ directionForSwapCalldata: bigint;
23
+ };
24
+ /**
25
+ * Exact output quote for **`tokenIn` → opposite side** on one venue (fails if **`tokenIn`** is not **`tokenA`** or **`tokenB`**).
26
+ */
27
+ export declare function quoteCpPoolSwap(venue: CpPoolVenue, tokenInHex: string, amountIn: bigint): CpQuoteResult;
28
+ /** Rank venues that list **`(tokenIn, tokenOut)`** by **`amountOut`** for a given **`amountIn`** (best first). */
29
+ export declare function rankDirectCpPools(venues: readonly CpPoolVenue[], tokenInHex: string, tokenOutHex: string, amountIn: bigint): Array<{
30
+ venue: CpPoolVenue;
31
+ amountOut: bigint;
32
+ directionForSwapCalldata: bigint;
33
+ }>;
34
+ export type RouteHop = {
35
+ venue: CpPoolVenue;
36
+ tokenInHex: string;
37
+ tokenOutHex: string;
38
+ amountIn: bigint;
39
+ amountOut: bigint;
40
+ directionForSwapCalldata: bigint;
41
+ };
42
+ export type CpSwapRoute = {
43
+ hops: RouteHop[];
44
+ tokenInHex: string;
45
+ tokenOutHex: string;
46
+ amountIn: bigint;
47
+ amountOut: bigint;
48
+ };
49
+ /** First route with **≥ 2** hops, or **`undefined`** (skips direct single-pool rows). */
50
+ export declare function pickFirstMultihopCpRoute(routes: readonly CpSwapRoute[]): CpSwapRoute | undefined;
51
+ /**
52
+ * Unique **`tokenA`** / **`tokenB`** ids across **`route.hops`** (**sorted** hex). Pass as **`additionalAccountsHex32`** when pools **`CALL`** reference-token contracts (v2+).
53
+ */
54
+ export declare function uniqueSortedTokenHex32FromCpRoute(route: CpSwapRoute): string[];
55
+ /** Maximum sequential pool **`Call`s** supported by canonical multihop router bytecode (selectors **`0xE5`–`0xEE`**). */
56
+ export declare const NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS = 6;
57
+ /**
58
+ * Basis points denominator for {@link minOutFloorAfterSlippageBps} (**10000** = 100%).
59
+ * Example: **`50`** bps ⇒ allow **0.5%** worse execution vs the quoted amount.
60
+ */
61
+ export declare const NATIVE_DEX_SLIPPAGE_BPS_SCALE = 10000n;
62
+ /**
63
+ * Floor of **`amountOut * (SCALE - slippageBps) / SCALE`** — conservative per-hop **`minOut`** for multihop **`swap`** / **`swap_to`** inners.
64
+ */
65
+ export declare function minOutFloorAfterSlippageBps(amountOut: bigint, slippageBps: bigint): bigint;
66
+ /** One slippage floor per {@link CpSwapRoute} hop, aligned with {@link RouteHop.amountOut} order. */
67
+ export declare function minOutPerHopFromQuotedRouteSlippageBps(route: CpSwapRoute, slippageBps: bigint): bigint[];
68
+ /**
69
+ * Enumerate simple CP paths (**no** same-pool reuse) up to **`maxHops`** pools; returns routes sorted by **`amountOut`** (best first).
70
+ * Default **`maxHops`** matches on-chain multihop router capacity ({@link NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS}); pass a lower value for large **`venues`** sets.
71
+ */
72
+ export declare function findBestCpRoutes(venues: readonly CpPoolVenue[], tokenInHex: string, tokenOutHex: string, amountIn: bigint, options?: {
73
+ maxHops?: number;
74
+ maxRoutes?: number;
75
+ }): CpSwapRoute[];
76
+ /** Best route or **`undefined`** when none. */
77
+ export declare function findBestCpRoute(venues: readonly CpPoolVenue[], tokenInHex: string, tokenOutHex: string, amountIn: bigint, options?: {
78
+ maxHops?: number;
79
+ maxRoutes?: number;
80
+ }): CpSwapRoute | undefined;
81
+ export type EncodeNativeDexMultihopFromRouteOptions128 = {
82
+ /** One minimum output per hop; length must equal **`route.hops.length`**. */
83
+ minOutPerHop: readonly bigint[];
84
+ };
85
+ export type EncodeNativeDexMultihopFromRouteOptions160 = {
86
+ minOutPerHop: readonly bigint[];
87
+ /** Multihop router **`AccountId`**; intermediate **`swap_to`** deliveries use this address. */
88
+ routerAccountHex32: string;
89
+ /** Final hop **`swap_to`** recipient (typically the trader). */
90
+ finalRecipientHex32: string;
91
+ };
92
+ /**
93
+ * Build **128-byte** inner **`swap`** calldata for a quoted {@link CpSwapRoute} (**2–6** hops).
94
+ * Pair with **`contract_call`** targeting the multihop router account.
95
+ */
96
+ export declare function encodeNativeDexMultihopRouterCalldata128FromRoute(route: CpSwapRoute, options: EncodeNativeDexMultihopFromRouteOptions128): Uint8Array;
97
+ /**
98
+ * Build **160-byte** inner **`swap_to`** (v5 pool) calldata for a quoted {@link CpSwapRoute}.
99
+ * Intermediate hops send output to **`routerAccountHex32`**; the last hop sends to **`finalRecipientHex32`**.
100
+ */
101
+ export declare function encodeNativeDexMultihopRouterCalldata160FromRoute(route: CpSwapRoute, options: EncodeNativeDexMultihopFromRouteOptions160): Uint8Array;
102
+ /**
103
+ * Same as {@link encodeNativeDexMultihopRouterCalldata128FromRoute} with **`minOutPerHop`** from
104
+ * {@link minOutPerHopFromQuotedRouteSlippageBps}.
105
+ */
106
+ export declare function encodeNativeDexMultihopRouterCalldata128FromRouteWithSlippage(route: CpSwapRoute, slippageBps: bigint): Uint8Array;
107
+ /**
108
+ * Same as {@link encodeNativeDexMultihopRouterCalldata160FromRoute} with **`minOutPerHop`** from
109
+ * {@link minOutPerHopFromQuotedRouteSlippageBps}.
110
+ */
111
+ export declare function encodeNativeDexMultihopRouterCalldata160FromRouteWithSlippage(route: CpSwapRoute, routerAccountHex32: string, finalRecipientHex32: string, slippageBps: bigint): Uint8Array;
112
+ /**
113
+ * Even-split **aggregation heuristic**: divide **`totalAmountIn`** across the top **`poolCount`** direct pools (by full-size quote rank), sum outputs.
114
+ * Not an optimal CEX splitter; useful for UI estimates and incremental liquidity use.
115
+ */
116
+ export declare function quoteCpEvenSplitAcrossDirectPools(venues: readonly CpPoolVenue[], tokenInHex: string, tokenOutHex: string, totalAmountIn: bigint, poolCount: number): {
117
+ rankedPools: Array<{
118
+ venue: CpPoolVenue;
119
+ amountOut: bigint;
120
+ directionForSwapCalldata: bigint;
121
+ }>;
122
+ allocations: Array<{
123
+ venue: CpPoolVenue;
124
+ amountIn: bigint;
125
+ amountOut: bigint;
126
+ directionForSwapCalldata: bigint;
127
+ }>;
128
+ totalOut: bigint;
129
+ };
130
+ export type PoolTokenRow = {
131
+ poolHex: string;
132
+ tokenAHex: string;
133
+ tokenBHex: string;
134
+ };
135
+ /**
136
+ * Hydrate **`CpPoolVenue`** rows from Boing RPC (reserves + fee bps per pool). **Boing-only.**
137
+ */
138
+ export declare function hydrateCpPoolVenuesFromRpc(client: BoingClient, rows: readonly PoolTokenRow[], options?: {
139
+ concurrency?: number;
140
+ }): Promise<CpPoolVenue[]>;
141
+ export type FetchCpRoutingFromDirectoryLogsOptions = {
142
+ overrides?: NativeDexIntegrationOverrides;
143
+ registerLogs: {
144
+ fromBlock: number;
145
+ toBlock?: number;
146
+ };
147
+ maxHops?: number;
148
+ maxRoutes?: number;
149
+ hydrateConcurrency?: number;
150
+ };
151
+ /**
152
+ * **Boing-only** pipeline: directory **`register_pair`** log range → hydrate venues → best CP route(s).
153
+ * Pair with **`encodeNativeDexMultihopRouterCalldata128FromRoute`** / **`encodeNativeDexMultihopRouterCalldata160FromRoute`** or **`pickFirstMultihopCpRoute`** + **`buildNativeDexMultihopSwapExpressTxFromRoute128`** when executing multihop on-chain.
154
+ */
155
+ export declare function fetchCpRoutingFromDirectoryLogs(client: BoingClient, tokenInHex: string, tokenOutHex: string, amountIn: bigint, options: FetchCpRoutingFromDirectoryLogsOptions): Promise<{
156
+ snapshot: NativeDexDirectorySnapshot;
157
+ venues: CpPoolVenue[];
158
+ routes: CpSwapRoute[];
159
+ }>;
160
+ //# sourceMappingURL=nativeDexRouting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeDexRouting.d.ts","sourceRoot":"","sources":["../src/nativeDexRouting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,345 @@
1
+ /**
2
+ * Constant-product **routing** and **quote aggregation** over Boing native pools (pure math + optional RPC hydrate).
3
+ * No external chains. Execution still uses **`contract_call`** / multihop router encoders elsewhere in the SDK.
4
+ */
5
+ import { fetchNativeDexDirectorySnapshot } from './nativeDexDirectory.js';
6
+ import { validateHex32 } from './hex.js';
7
+ import { mapWithConcurrencyLimit } from './indexerBatch.js';
8
+ import { NATIVE_CP_SWAP_FEE_BPS, constantProductAmountOutWithFeeBps, encodeNativeAmmSwapCalldata, encodeNativeAmmSwapToCalldata, } from './nativeAmm.js';
9
+ import { encodeNativeDexSwap2RouterCalldata128, encodeNativeDexSwap2RouterCalldata160, encodeNativeDexSwap3RouterCalldata128, encodeNativeDexSwap3RouterCalldata160, encodeNativeDexSwap4RouterCalldata128, encodeNativeDexSwap4RouterCalldata160, encodeNativeDexSwap5RouterCalldata128, encodeNativeDexSwap5RouterCalldata160, encodeNativeDexSwap6RouterCalldata128, encodeNativeDexSwap6RouterCalldata160, } from './nativeDexSwap2Router.js';
10
+ import { fetchNativeConstantProductPoolSnapshot, fetchNativeConstantProductSwapFeeBps, } from './nativeAmmPool.js';
11
+ function normHex32(h) {
12
+ return validateHex32(h).toLowerCase();
13
+ }
14
+ function effectiveFeeBps(raw) {
15
+ return raw === 0n ? BigInt(NATIVE_CP_SWAP_FEE_BPS) : raw;
16
+ }
17
+ /**
18
+ * Exact output quote for **`tokenIn` → opposite side** on one venue (fails if **`tokenIn`** is not **`tokenA`** or **`tokenB`**).
19
+ */
20
+ export function quoteCpPoolSwap(venue, tokenInHex, amountIn) {
21
+ if (amountIn < 0n)
22
+ throw new RangeError('amountIn must be non-negative');
23
+ const a = normHex32(venue.tokenAHex);
24
+ const b = normHex32(venue.tokenBHex);
25
+ const tin = normHex32(tokenInHex);
26
+ if (tin === a) {
27
+ const amountOut = constantProductAmountOutWithFeeBps(venue.reserveA, venue.reserveB, amountIn, venue.feeBps);
28
+ return { amountOut, tokenOutHex: b, directionForSwapCalldata: 0n };
29
+ }
30
+ if (tin === b) {
31
+ const amountOut = constantProductAmountOutWithFeeBps(venue.reserveB, venue.reserveA, amountIn, venue.feeBps);
32
+ return { amountOut, tokenOutHex: a, directionForSwapCalldata: 1n };
33
+ }
34
+ throw new Error('quoteCpPoolSwap: tokenIn is not a pool token');
35
+ }
36
+ /** Rank venues that list **`(tokenIn, tokenOut)`** by **`amountOut`** for a given **`amountIn`** (best first). */
37
+ export function rankDirectCpPools(venues, tokenInHex, tokenOutHex, amountIn) {
38
+ const tout = normHex32(tokenOutHex);
39
+ const out = [];
40
+ for (const v of venues) {
41
+ let q;
42
+ try {
43
+ q = quoteCpPoolSwap(v, tokenInHex, amountIn);
44
+ }
45
+ catch {
46
+ continue;
47
+ }
48
+ if (q.tokenOutHex === tout && q.amountOut > 0n) {
49
+ out.push({ venue: v, amountOut: q.amountOut, directionForSwapCalldata: q.directionForSwapCalldata });
50
+ }
51
+ }
52
+ out.sort((x, y) => (x.amountOut > y.amountOut ? -1 : x.amountOut < y.amountOut ? 1 : 0));
53
+ return out;
54
+ }
55
+ /** First route with **≥ 2** hops, or **`undefined`** (skips direct single-pool rows). */
56
+ export function pickFirstMultihopCpRoute(routes) {
57
+ return routes.find((r) => r.hops.length >= 2);
58
+ }
59
+ /**
60
+ * Unique **`tokenA`** / **`tokenB`** ids across **`route.hops`** (**sorted** hex). Pass as **`additionalAccountsHex32`** when pools **`CALL`** reference-token contracts (v2+).
61
+ */
62
+ export function uniqueSortedTokenHex32FromCpRoute(route) {
63
+ const seen = new Set();
64
+ for (const h of route.hops) {
65
+ seen.add(normHex32(h.venue.tokenAHex));
66
+ seen.add(normHex32(h.venue.tokenBHex));
67
+ }
68
+ return [...seen].sort();
69
+ }
70
+ /** Maximum sequential pool **`Call`s** supported by canonical multihop router bytecode (selectors **`0xE5`–`0xEE`**). */
71
+ export const NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS = 6;
72
+ /**
73
+ * Basis points denominator for {@link minOutFloorAfterSlippageBps} (**10000** = 100%).
74
+ * Example: **`50`** bps ⇒ allow **0.5%** worse execution vs the quoted amount.
75
+ */
76
+ export const NATIVE_DEX_SLIPPAGE_BPS_SCALE = 10000n;
77
+ /**
78
+ * Floor of **`amountOut * (SCALE - slippageBps) / SCALE`** — conservative per-hop **`minOut`** for multihop **`swap`** / **`swap_to`** inners.
79
+ */
80
+ export function minOutFloorAfterSlippageBps(amountOut, slippageBps) {
81
+ if (amountOut < 0n)
82
+ throw new RangeError('amountOut must be non-negative');
83
+ if (slippageBps < 0n || slippageBps > NATIVE_DEX_SLIPPAGE_BPS_SCALE) {
84
+ throw new RangeError(`slippageBps must satisfy 0 <= slippageBps <= ${NATIVE_DEX_SLIPPAGE_BPS_SCALE.toString()}`);
85
+ }
86
+ return (amountOut * (NATIVE_DEX_SLIPPAGE_BPS_SCALE - slippageBps)) / NATIVE_DEX_SLIPPAGE_BPS_SCALE;
87
+ }
88
+ /** One slippage floor per {@link CpSwapRoute} hop, aligned with {@link RouteHop.amountOut} order. */
89
+ export function minOutPerHopFromQuotedRouteSlippageBps(route, slippageBps) {
90
+ return route.hops.map((h) => minOutFloorAfterSlippageBps(h.amountOut, slippageBps));
91
+ }
92
+ function edgesFromToken(venues, currentToken) {
93
+ const t = normHex32(currentToken);
94
+ const hit = [];
95
+ for (const v of venues) {
96
+ const a = normHex32(v.tokenAHex);
97
+ const b = normHex32(v.tokenBHex);
98
+ if (a === t || b === t)
99
+ hit.push(v);
100
+ }
101
+ return hit;
102
+ }
103
+ /**
104
+ * Enumerate simple CP paths (**no** same-pool reuse) up to **`maxHops`** pools; returns routes sorted by **`amountOut`** (best first).
105
+ * Default **`maxHops`** matches on-chain multihop router capacity ({@link NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS}); pass a lower value for large **`venues`** sets.
106
+ */
107
+ export function findBestCpRoutes(venues, tokenInHex, tokenOutHex, amountIn, options) {
108
+ const maxHops = options?.maxHops ?? NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS;
109
+ const maxRoutes = options?.maxRoutes ?? 32;
110
+ if (maxHops < 1)
111
+ throw new RangeError('maxHops must be >= 1');
112
+ if (maxHops > NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS) {
113
+ throw new RangeError(`maxHops cannot exceed ${NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS} (multihop router cap)`);
114
+ }
115
+ const tin = normHex32(tokenInHex);
116
+ const tout = normHex32(tokenOutHex);
117
+ if (tin === tout) {
118
+ return [{ hops: [], tokenInHex: tin, tokenOutHex: tout, amountIn, amountOut: amountIn }];
119
+ }
120
+ const routes = [];
121
+ function dfs(currentToken, amount, path, visitedPools) {
122
+ if (routes.length >= maxRoutes)
123
+ return;
124
+ for (const v of edgesFromToken(venues, currentToken)) {
125
+ const ph = normHex32(v.poolHex);
126
+ if (visitedPools.has(ph))
127
+ continue;
128
+ let q;
129
+ try {
130
+ q = quoteCpPoolSwap(v, currentToken, amount);
131
+ }
132
+ catch {
133
+ continue;
134
+ }
135
+ if (q.amountOut === 0n)
136
+ continue;
137
+ const hop = {
138
+ venue: v,
139
+ tokenInHex: currentToken,
140
+ tokenOutHex: q.tokenOutHex,
141
+ amountIn: amount,
142
+ amountOut: q.amountOut,
143
+ directionForSwapCalldata: q.directionForSwapCalldata,
144
+ };
145
+ if (normHex32(q.tokenOutHex) === tout) {
146
+ routes.push({
147
+ hops: [...path, hop],
148
+ tokenInHex: tin,
149
+ tokenOutHex: tout,
150
+ amountIn,
151
+ amountOut: q.amountOut,
152
+ });
153
+ continue;
154
+ }
155
+ if (path.length + 1 >= maxHops)
156
+ continue;
157
+ visitedPools.add(ph);
158
+ dfs(q.tokenOutHex, q.amountOut, [...path, hop], visitedPools);
159
+ visitedPools.delete(ph);
160
+ if (routes.length >= maxRoutes)
161
+ return;
162
+ }
163
+ }
164
+ dfs(tin, amountIn, [], new Set());
165
+ routes.sort((a, b) => (a.amountOut > b.amountOut ? -1 : a.amountOut < b.amountOut ? 1 : 0));
166
+ return routes.slice(0, maxRoutes);
167
+ }
168
+ /** Best route or **`undefined`** when none. */
169
+ export function findBestCpRoute(venues, tokenInHex, tokenOutHex, amountIn, options) {
170
+ return findBestCpRoutes(venues, tokenInHex, tokenOutHex, amountIn, options)[0];
171
+ }
172
+ /**
173
+ * Build **128-byte** inner **`swap`** calldata for a quoted {@link CpSwapRoute} (**2–6** hops).
174
+ * Pair with **`contract_call`** targeting the multihop router account.
175
+ */
176
+ export function encodeNativeDexMultihopRouterCalldata128FromRoute(route, options) {
177
+ const n = route.hops.length;
178
+ if (n < 2 || n > NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS) {
179
+ throw new RangeError(`multihop router expects 2..${NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS} hops, got ${n}`);
180
+ }
181
+ if (options.minOutPerHop.length !== n) {
182
+ throw new RangeError('minOutPerHop length must match route.hops.length');
183
+ }
184
+ const pools = route.hops.map((h) => validateHex32(h.venue.poolHex));
185
+ const inners = route.hops.map((hop, i) => encodeNativeAmmSwapCalldata(hop.directionForSwapCalldata, hop.amountIn, options.minOutPerHop[i]));
186
+ switch (n) {
187
+ case 2:
188
+ return encodeNativeDexSwap2RouterCalldata128(pools[0], inners[0], pools[1], inners[1]);
189
+ case 3:
190
+ return encodeNativeDexSwap3RouterCalldata128(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2]);
191
+ case 4:
192
+ return encodeNativeDexSwap4RouterCalldata128(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3]);
193
+ case 5:
194
+ return encodeNativeDexSwap5RouterCalldata128(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3], pools[4], inners[4]);
195
+ case 6:
196
+ return encodeNativeDexSwap6RouterCalldata128(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3], pools[4], inners[4], pools[5], inners[5]);
197
+ default:
198
+ throw new RangeError(`unsupported hop count ${n}`);
199
+ }
200
+ }
201
+ /**
202
+ * Build **160-byte** inner **`swap_to`** (v5 pool) calldata for a quoted {@link CpSwapRoute}.
203
+ * Intermediate hops send output to **`routerAccountHex32`**; the last hop sends to **`finalRecipientHex32`**.
204
+ */
205
+ export function encodeNativeDexMultihopRouterCalldata160FromRoute(route, options) {
206
+ const n = route.hops.length;
207
+ if (n < 2 || n > NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS) {
208
+ throw new RangeError(`multihop router expects 2..${NATIVE_DEX_MULTIHOP_ROUTER_MAX_POOLS} hops, got ${n}`);
209
+ }
210
+ if (options.minOutPerHop.length !== n) {
211
+ throw new RangeError('minOutPerHop length must match route.hops.length');
212
+ }
213
+ const router = validateHex32(options.routerAccountHex32);
214
+ const finalRecip = validateHex32(options.finalRecipientHex32);
215
+ const pools = route.hops.map((h) => validateHex32(h.venue.poolHex));
216
+ const inners = route.hops.map((hop, i) => {
217
+ const recip = i === n - 1 ? finalRecip : router;
218
+ return encodeNativeAmmSwapToCalldata(hop.directionForSwapCalldata, hop.amountIn, options.minOutPerHop[i], recip);
219
+ });
220
+ switch (n) {
221
+ case 2:
222
+ return encodeNativeDexSwap2RouterCalldata160(pools[0], inners[0], pools[1], inners[1]);
223
+ case 3:
224
+ return encodeNativeDexSwap3RouterCalldata160(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2]);
225
+ case 4:
226
+ return encodeNativeDexSwap4RouterCalldata160(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3]);
227
+ case 5:
228
+ return encodeNativeDexSwap5RouterCalldata160(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3], pools[4], inners[4]);
229
+ case 6:
230
+ return encodeNativeDexSwap6RouterCalldata160(pools[0], inners[0], pools[1], inners[1], pools[2], inners[2], pools[3], inners[3], pools[4], inners[4], pools[5], inners[5]);
231
+ default:
232
+ throw new RangeError(`unsupported hop count ${n}`);
233
+ }
234
+ }
235
+ /**
236
+ * Same as {@link encodeNativeDexMultihopRouterCalldata128FromRoute} with **`minOutPerHop`** from
237
+ * {@link minOutPerHopFromQuotedRouteSlippageBps}.
238
+ */
239
+ export function encodeNativeDexMultihopRouterCalldata128FromRouteWithSlippage(route, slippageBps) {
240
+ return encodeNativeDexMultihopRouterCalldata128FromRoute(route, {
241
+ minOutPerHop: minOutPerHopFromQuotedRouteSlippageBps(route, slippageBps),
242
+ });
243
+ }
244
+ /**
245
+ * Same as {@link encodeNativeDexMultihopRouterCalldata160FromRoute} with **`minOutPerHop`** from
246
+ * {@link minOutPerHopFromQuotedRouteSlippageBps}.
247
+ */
248
+ export function encodeNativeDexMultihopRouterCalldata160FromRouteWithSlippage(route, routerAccountHex32, finalRecipientHex32, slippageBps) {
249
+ return encodeNativeDexMultihopRouterCalldata160FromRoute(route, {
250
+ minOutPerHop: minOutPerHopFromQuotedRouteSlippageBps(route, slippageBps),
251
+ routerAccountHex32,
252
+ finalRecipientHex32,
253
+ });
254
+ }
255
+ /**
256
+ * Even-split **aggregation heuristic**: divide **`totalAmountIn`** across the top **`poolCount`** direct pools (by full-size quote rank), sum outputs.
257
+ * Not an optimal CEX splitter; useful for UI estimates and incremental liquidity use.
258
+ */
259
+ export function quoteCpEvenSplitAcrossDirectPools(venues, tokenInHex, tokenOutHex, totalAmountIn, poolCount) {
260
+ if (poolCount < 1)
261
+ throw new RangeError('poolCount must be >= 1');
262
+ if (totalAmountIn < 0n)
263
+ throw new RangeError('totalAmountIn must be non-negative');
264
+ const ranked = rankDirectCpPools(venues, tokenInHex, tokenOutHex, totalAmountIn);
265
+ const n = Math.min(poolCount, ranked.length);
266
+ if (n === 0 || totalAmountIn === 0n) {
267
+ return { rankedPools: ranked, allocations: [], totalOut: 0n };
268
+ }
269
+ const base = totalAmountIn / BigInt(n);
270
+ const rem = Number(totalAmountIn % BigInt(n));
271
+ const allocations = [];
272
+ let totalOut = 0n;
273
+ for (let i = 0; i < n; i++) {
274
+ const row = ranked[i];
275
+ const ai = base + (i < rem ? 1n : 0n);
276
+ if (ai === 0n)
277
+ continue;
278
+ const q = quoteCpPoolSwap(row.venue, tokenInHex, ai);
279
+ allocations.push({
280
+ venue: row.venue,
281
+ amountIn: ai,
282
+ amountOut: q.amountOut,
283
+ directionForSwapCalldata: q.directionForSwapCalldata,
284
+ });
285
+ totalOut += q.amountOut;
286
+ }
287
+ return { rankedPools: ranked, allocations, totalOut };
288
+ }
289
+ function dedupePoolRows(rows) {
290
+ const m = new Map();
291
+ for (const r of rows) {
292
+ const k = normHex32(r.poolHex);
293
+ if (!m.has(k))
294
+ m.set(k, r);
295
+ }
296
+ return [...m.values()];
297
+ }
298
+ /**
299
+ * Hydrate **`CpPoolVenue`** rows from Boing RPC (reserves + fee bps per pool). **Boing-only.**
300
+ */
301
+ export async function hydrateCpPoolVenuesFromRpc(client, rows, options) {
302
+ const uniq = dedupePoolRows(rows);
303
+ const concurrency = options?.concurrency ?? 8;
304
+ return mapWithConcurrencyLimit(uniq, concurrency, async (r) => {
305
+ const poolHex = validateHex32(r.poolHex);
306
+ const tokenAHex = validateHex32(r.tokenAHex);
307
+ const tokenBHex = validateHex32(r.tokenBHex);
308
+ const [snap, feeRaw] = await Promise.all([
309
+ fetchNativeConstantProductPoolSnapshot(client, poolHex),
310
+ fetchNativeConstantProductSwapFeeBps(client, poolHex),
311
+ ]);
312
+ return {
313
+ poolHex,
314
+ tokenAHex,
315
+ tokenBHex,
316
+ reserveA: snap.reserveA,
317
+ reserveB: snap.reserveB,
318
+ feeBps: effectiveFeeBps(feeRaw),
319
+ };
320
+ });
321
+ }
322
+ /**
323
+ * **Boing-only** pipeline: directory **`register_pair`** log range → hydrate venues → best CP route(s).
324
+ * Pair with **`encodeNativeDexMultihopRouterCalldata128FromRoute`** / **`encodeNativeDexMultihopRouterCalldata160FromRoute`** or **`pickFirstMultihopCpRoute`** + **`buildNativeDexMultihopSwapExpressTxFromRoute128`** when executing multihop on-chain.
325
+ */
326
+ export async function fetchCpRoutingFromDirectoryLogs(client, tokenInHex, tokenOutHex, amountIn, options) {
327
+ const snapshot = await fetchNativeDexDirectorySnapshot(client, {
328
+ overrides: options.overrides,
329
+ registerLogs: options.registerLogs,
330
+ });
331
+ const logs = snapshot.registerLogs ?? [];
332
+ const rows = logs.map((l) => ({
333
+ poolHex: l.poolHex,
334
+ tokenAHex: l.tokenAHex,
335
+ tokenBHex: l.tokenBHex,
336
+ }));
337
+ const venues = await hydrateCpPoolVenuesFromRpc(client, rows, {
338
+ concurrency: options.hydrateConcurrency,
339
+ });
340
+ const routes = findBestCpRoutes(venues, tokenInHex, tokenOutHex, amountIn, {
341
+ maxHops: options.maxHops,
342
+ maxRoutes: options.maxRoutes,
343
+ });
344
+ return { snapshot, venues, routes };
345
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Copy, preflight, and one-shot tx helpers for native Boing DEX integration.
3
+ * Reinforces that Boing is **not** a drop-in Uniswap/EVM router and keeps flows **Boing-RPC-only**.
4
+ */
5
+ import type { BoingClient } from './client.js';
6
+ import type { NativeDexIntegrationDefaults } from './dexIntegration.js';
7
+ import { buildNativeConstantProductContractCallTx, buildNativeDexMultihopRouterContractCallTx, type NativePoolAccessListOptions } from './nativeAmmPool.js';
8
+ import type { CpSwapRoute } from './nativeDexRouting.js';
9
+ import { type BoingRpcPreflightError } from './preflightGate.js';
10
+ import type { SimulateResult } from './types.js';
11
+ /** Short line for tooltips / footers. */
12
+ export declare const BOING_NATIVE_DEX_NOT_EVM_TAGLINE = "Boing native DEX uses 32-byte account ids, explicit access lists, and VM-specific calldata\u2014not a paste-any-Uniswap-address router.";
13
+ /** Bullet list for onboarding modals or docs snippets. */
14
+ export declare const BOING_NATIVE_DEX_NOT_EVM_BULLETS: readonly ["Accounts are 32-byte Boing AccountIds (64 hex chars), not 20-byte Ethereum contract addresses.", "Each `contract_call` needs calldata per NATIVE-AMM / NATIVE-DEX specs plus explicit `access_list` read/write sets.", "Pool, factory, multihop router, ledger forwarders, and LP vault/share ids resolve via RPC `end_user` hints, `fetchNativeDexIntegrationDefaults`, env overrides, or CREATE2 prediction—there is no universal router ABI."];
15
+ export declare function formatBoingNativeDexNotEvmDisclaimer(): string;
16
+ /**
17
+ * Surfaces missing operator hints so UIs can link to ops runbooks instead of failing silently.
18
+ */
19
+ export declare function describeNativeDexDefaultGaps(defaults: NativeDexIntegrationDefaults): readonly string[];
20
+ /** RPC methods a typical native DEX dApp (read + simulate + logs) expects from **boing-node**. */
21
+ export declare const BOING_NATIVE_DEX_TOOLKIT_RPC_METHODS: readonly ["boing_getNetworkInfo", "boing_simulateTransaction", "boing_getLogs", "boing_getContractStorage"];
22
+ /**
23
+ * {@link assertBoingRpcEnvironment} with {@link BOING_NATIVE_DEX_TOOLKIT_RPC_METHODS}.
24
+ * Throws {@link BoingRpcPreflightError} when the endpoint is missing methods or failing discovery.
25
+ */
26
+ export declare function assertBoingNativeDexToolkitRpc(client: BoingClient): Promise<import("./rpcDoctor.js").BoingRpcDoctorResult>;
27
+ /** User-facing text when {@link assertBoingNativeDexToolkitRpc} fails (QA / pruned / old node). */
28
+ export declare function formatNativeDexToolkitPreflightForUi(err: BoingRpcPreflightError): string;
29
+ /**
30
+ * One-shot **`contract_call`** object for **`boing_sendTransaction`** / Boing Express: native CP **`swap`** calldata + pool access list.
31
+ */
32
+ export declare function buildNativeCpPoolSwapExpressTx(input: {
33
+ senderHex32: string;
34
+ poolHex32: string;
35
+ direction: bigint;
36
+ amountIn: bigint;
37
+ minOut: bigint;
38
+ poolAccessListOptions?: NativePoolAccessListOptions;
39
+ }): ReturnType<typeof buildNativeConstantProductContractCallTx>;
40
+ /** Multihop router **`contract_call`** from a quoted {@link CpSwapRoute} (**128-byte** pool inners). Pass **`minOutPerHop`** or **`slippageBps`** (explicit **`minOutPerHop`** wins when set). */
41
+ export type BuildNativeDexMultihopSwapExpressTxFromRoute128Input = {
42
+ senderHex32: string;
43
+ routerHex32: string;
44
+ route: CpSwapRoute;
45
+ minOutPerHop?: readonly bigint[];
46
+ slippageBps?: bigint;
47
+ /**
48
+ * When **`true`**, append {@link uniqueSortedTokenHex32FromCpRoute} to **`additionalAccountsHex32`**
49
+ * (reference-token pools that **`CALL`** token contracts during **`swap`**).
50
+ */
51
+ includeVenueTokenAccounts?: boolean;
52
+ poolAccessListOptions?: NativePoolAccessListOptions;
53
+ };
54
+ /** Multihop router **`contract_call`** with **160-byte** **`swap_to`** inners (v5 pools). */
55
+ export type BuildNativeDexMultihopSwapExpressTxFromRoute160Input = BuildNativeDexMultihopSwapExpressTxFromRoute128Input & {
56
+ finalRecipientHex32: string;
57
+ };
58
+ /**
59
+ * Recompute **`access_list`** after **`boing_simulateTransaction`** using {@link mergeNativeDexMultihopRouterAccessListWithSimulation}.
60
+ * **`poolHex32List`** and **`poolAccessListOptions`** should match the pools / extras used to build **`tx`**.
61
+ */
62
+ export declare function applyNativeDexMultihopSimulationToContractCallTx(tx: {
63
+ type: 'contract_call';
64
+ contract: string;
65
+ calldata: string;
66
+ access_list: {
67
+ read: string[];
68
+ write: string[];
69
+ };
70
+ }, input: {
71
+ senderHex32: string;
72
+ poolHex32List: readonly string[];
73
+ sim: SimulateResult;
74
+ poolAccessListOptions?: NativePoolAccessListOptions;
75
+ }): {
76
+ type: 'contract_call';
77
+ contract: string;
78
+ calldata: string;
79
+ access_list: {
80
+ read: string[];
81
+ write: string[];
82
+ };
83
+ };
84
+ export declare function buildNativeDexMultihopSwapExpressTxFromRoute128(input: BuildNativeDexMultihopSwapExpressTxFromRoute128Input): ReturnType<typeof buildNativeDexMultihopRouterContractCallTx>;
85
+ export declare function buildNativeDexMultihopSwapExpressTxFromRoute160(input: BuildNativeDexMultihopSwapExpressTxFromRoute160Input): ReturnType<typeof buildNativeDexMultihopRouterContractCallTx>;
86
+ //# sourceMappingURL=nativeDexSeamless.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeDexSeamless.d.ts","sourceRoot":"","sources":["../src/nativeDexSeamless.ts"],"names":[],"mappings":"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"}