tapimo 0.4.3 → 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 (192) hide show
  1. package/dist/App.d.ts +7222 -6316
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +4 -0
  4. package/dist/App.js.map +1 -1
  5. package/dist/Scope.d.ts +18 -1
  6. package/dist/Scope.d.ts.map +1 -1
  7. package/dist/Scope.js +24 -3
  8. package/dist/Scope.js.map +1 -1
  9. package/dist/admin/apps/verified-tokens.d.ts +116 -116
  10. package/dist/apps/data/App.d.ts +2541 -2607
  11. package/dist/apps/data/App.d.ts.map +1 -1
  12. package/dist/apps/data/App.js +135 -44
  13. package/dist/apps/data/App.js.map +1 -1
  14. package/dist/apps/data/FundingQuoteProviders.d.ts +36 -0
  15. package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -0
  16. package/dist/apps/data/FundingQuoteProviders.js +190 -0
  17. package/dist/apps/data/FundingQuoteProviders.js.map +1 -0
  18. package/dist/apps/data/index.d.ts +1 -1
  19. package/dist/apps/data/index.js +1 -1
  20. package/dist/apps/data/routes/activities.d.ts +242 -242
  21. package/dist/apps/data/routes/addresses.d.ts +227 -227
  22. package/dist/apps/data/routes/balances.d.ts +12 -12
  23. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  24. package/dist/apps/data/routes/balances.js +67 -149
  25. package/dist/apps/data/routes/balances.js.map +1 -1
  26. package/dist/apps/data/routes/blocks.d.ts +125 -126
  27. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  28. package/dist/apps/data/routes/blocks.js +3 -5
  29. package/dist/apps/data/routes/blocks.js.map +1 -1
  30. package/dist/apps/data/routes/coingecko.d.ts +55 -54
  31. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  32. package/dist/apps/data/routes/coingecko.js +3 -8
  33. package/dist/apps/data/routes/coingecko.js.map +1 -1
  34. package/dist/apps/data/routes/exchanges.d.ts +455 -455
  35. package/dist/apps/data/routes/fee-amm.d.ts +92 -92
  36. package/dist/apps/data/routes/funding.d.ts +91 -864
  37. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  38. package/dist/apps/data/routes/funding.js +138 -450
  39. package/dist/apps/data/routes/funding.js.map +1 -1
  40. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  41. package/dist/apps/data/routes/rpc.js +86 -16
  42. package/dist/apps/data/routes/rpc.js.map +1 -1
  43. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  44. package/dist/apps/data/routes/webhooks.d.ts +340 -0
  45. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  46. package/dist/apps/data/routes/webhooks.js +13 -1
  47. package/dist/apps/data/routes/webhooks.js.map +1 -1
  48. package/dist/apps/index.d.ts +1 -1
  49. package/dist/apps/index.js +1 -1
  50. package/dist/apps/management/App.d.ts +1843 -861
  51. package/dist/apps/management/App.d.ts.map +1 -1
  52. package/dist/apps/management/App.js +4 -0
  53. package/dist/apps/management/App.js.map +1 -1
  54. package/dist/apps/management/routes/api-keys.d.ts +121 -121
  55. package/dist/apps/management/routes/api-keys.js +2 -2
  56. package/dist/apps/management/routes/api-keys.js.map +1 -1
  57. package/dist/apps/management/routes/billing.d.ts +2 -2
  58. package/dist/apps/management/routes/invite-links.d.ts +1100 -0
  59. package/dist/apps/management/routes/invite-links.d.ts.map +1 -0
  60. package/dist/apps/management/routes/invite-links.js +411 -0
  61. package/dist/apps/management/routes/invite-links.js.map +1 -0
  62. package/dist/apps/management/routes/me.d.ts +13 -13
  63. package/dist/apps/management/routes/members.d.ts +77 -77
  64. package/dist/apps/management/routes/orgs.d.ts +96 -96
  65. package/dist/apps/management/routes/projects.d.ts +62 -62
  66. package/dist/apps/management/routes/scopes.d.ts +11 -11
  67. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  68. package/dist/apps/management/routes/scopes.js +2 -2
  69. package/dist/apps/management/routes/scopes.js.map +1 -1
  70. package/dist/apps/management/routes/usage.d.ts +79 -79
  71. package/dist/apps/mcp.d.ts.map +1 -1
  72. package/dist/apps/mcp.js +3 -1
  73. package/dist/apps/mcp.js.map +1 -1
  74. package/dist/apps/relay/App.d.ts.map +1 -1
  75. package/dist/apps/relay/App.js +42 -4
  76. package/dist/apps/relay/App.js.map +1 -1
  77. package/dist/cloudflare.d.ts +2 -0
  78. package/dist/cloudflare.d.ts.map +1 -1
  79. package/dist/cloudflare.js +4 -0
  80. package/dist/cloudflare.js.map +1 -1
  81. package/dist/db/Db.d.ts +3 -0
  82. package/dist/db/Db.d.ts.map +1 -1
  83. package/dist/db/Db.js +57 -0
  84. package/dist/db/Db.js.map +1 -1
  85. package/dist/db/Schema.d.ts +31 -0
  86. package/dist/db/Schema.d.ts.map +1 -1
  87. package/dist/db/Schema.js +31 -0
  88. package/dist/db/Schema.js.map +1 -1
  89. package/dist/db/tables/inviteLinks.d.ts +42 -0
  90. package/dist/db/tables/inviteLinks.d.ts.map +1 -0
  91. package/dist/db/tables/inviteLinks.js +148 -0
  92. package/dist/db/tables/inviteLinks.js.map +1 -0
  93. package/dist/db/tables/organizations.d.ts.map +1 -1
  94. package/dist/db/tables/organizations.js +2 -0
  95. package/dist/db/tables/organizations.js.map +1 -1
  96. package/dist/handlers/relay.d.ts.map +1 -1
  97. package/dist/handlers/relay.js +13 -3
  98. package/dist/handlers/relay.js.map +1 -1
  99. package/dist/internal/Auth.d.ts +42 -23
  100. package/dist/internal/Auth.d.ts.map +1 -1
  101. package/dist/internal/Auth.js +169 -20
  102. package/dist/internal/Auth.js.map +1 -1
  103. package/dist/internal/EdgeCache.d.ts +3 -1
  104. package/dist/internal/EdgeCache.d.ts.map +1 -1
  105. package/dist/internal/EdgeCache.js +17 -2
  106. package/dist/internal/EdgeCache.js.map +1 -1
  107. package/dist/internal/Errors.d.ts +6 -0
  108. package/dist/internal/Errors.d.ts.map +1 -0
  109. package/dist/internal/Errors.js +16 -0
  110. package/dist/internal/Errors.js.map +1 -0
  111. package/dist/internal/FundingQuotes.d.ts +644 -0
  112. package/dist/internal/FundingQuotes.d.ts.map +1 -0
  113. package/dist/internal/{FundingRoutes.js → FundingQuotes.js} +93 -289
  114. package/dist/internal/FundingQuotes.js.map +1 -0
  115. package/dist/internal/Store.d.ts +61 -16
  116. package/dist/internal/Store.d.ts.map +1 -1
  117. package/dist/internal/Store.js +72 -17
  118. package/dist/internal/Store.js.map +1 -1
  119. package/dist/internal/Viem.d.ts +2 -0
  120. package/dist/internal/Viem.d.ts.map +1 -1
  121. package/dist/internal/Viem.js +11 -2
  122. package/dist/internal/Viem.js.map +1 -1
  123. package/dist/internal/index.d.ts +27 -0
  124. package/dist/internal/index.d.ts.map +1 -0
  125. package/dist/internal/index.js +27 -0
  126. package/dist/internal/index.js.map +1 -0
  127. package/package.json +8 -3
  128. package/src/ApiKeys.test.ts +23 -0
  129. package/src/App.test-d.ts +2 -0
  130. package/src/App.test.ts +60 -4
  131. package/src/App.ts +6 -0
  132. package/src/Client.test-d.ts +16 -54
  133. package/src/Scope.test.ts +1 -0
  134. package/src/Scope.ts +30 -4
  135. package/src/apps/data/App.test.ts +354 -0
  136. package/src/apps/data/App.ts +159 -52
  137. package/src/apps/data/FundingQuoteProviders.test.ts +151 -0
  138. package/src/apps/data/FundingQuoteProviders.ts +251 -0
  139. package/src/apps/data/index.ts +1 -1
  140. package/src/apps/data/routes/balances.test.ts +64 -18
  141. package/src/apps/data/routes/balances.ts +76 -177
  142. package/src/apps/data/routes/blocks.ts +3 -5
  143. package/src/apps/data/routes/coingecko.ts +3 -8
  144. package/src/apps/data/routes/funding.test.ts +149 -306
  145. package/src/apps/data/routes/funding.ts +154 -604
  146. package/src/apps/data/routes/indexer.test.ts +99 -3
  147. package/src/apps/data/routes/rpc.test.ts +219 -0
  148. package/src/apps/data/routes/rpc.ts +92 -17
  149. package/src/apps/data/routes/webhooks.test.ts +23 -2
  150. package/src/apps/data/routes/webhooks.ts +13 -1
  151. package/src/apps/index.ts +1 -1
  152. package/src/apps/management/App.ts +4 -0
  153. package/src/apps/management/routes/api-keys.test.ts +47 -3
  154. package/src/apps/management/routes/api-keys.ts +2 -2
  155. package/src/apps/management/routes/invite-links.test.ts +385 -0
  156. package/src/apps/management/routes/invite-links.ts +570 -0
  157. package/src/apps/management/routes/scopes.test.ts +3 -2
  158. package/src/apps/management/routes/scopes.ts +4 -2
  159. package/src/apps/mcp.test.ts +55 -14
  160. package/src/apps/mcp.ts +3 -1
  161. package/src/apps/relay/App.test.ts +324 -4
  162. package/src/apps/relay/App.ts +40 -4
  163. package/src/cloudflare.ts +5 -0
  164. package/src/db/Db.ts +65 -0
  165. package/src/db/Schema.ts +39 -0
  166. package/src/db/tables/inviteLinks.ts +187 -0
  167. package/src/db/tables/organizations.ts +2 -0
  168. package/src/handlers/relay.ts +16 -4
  169. package/src/internal/Auth.test.ts +528 -37
  170. package/src/internal/Auth.ts +246 -45
  171. package/src/internal/EdgeCache.test.ts +24 -3
  172. package/src/internal/EdgeCache.ts +18 -2
  173. package/src/internal/FundingQuotes.test.ts +174 -0
  174. package/src/internal/FundingQuotes.ts +735 -0
  175. package/src/internal/Log.test.ts +4 -4
  176. package/src/internal/Store.test-d.ts +15 -0
  177. package/src/internal/Store.test.ts +153 -2
  178. package/src/internal/Store.ts +157 -41
  179. package/src/internal/Viem.ts +14 -5
  180. package/src/internal/index.test.ts +34 -0
  181. package/src/internal/index.ts +26 -0
  182. package/dist/apps/data/FundingRouteProviders.d.ts +0 -143
  183. package/dist/apps/data/FundingRouteProviders.d.ts.map +0 -1
  184. package/dist/apps/data/FundingRouteProviders.js +0 -546
  185. package/dist/apps/data/FundingRouteProviders.js.map +0 -1
  186. package/dist/internal/FundingRoutes.d.ts +0 -1085
  187. package/dist/internal/FundingRoutes.d.ts.map +0 -1
  188. package/dist/internal/FundingRoutes.js.map +0 -1
  189. package/src/apps/data/FundingRouteProviders.test.ts +0 -485
  190. package/src/apps/data/FundingRouteProviders.ts +0 -744
  191. package/src/internal/FundingRoutes.test.ts +0 -239
  192. package/src/internal/FundingRoutes.ts +0 -1067
@@ -1,1067 +0,0 @@
1
- /** Tempo mainnet as a CAIP-2 chain reference. */
2
- const destinationChain = {
3
- addressFormat: 'evm',
4
- id: 'eip155:4217',
5
- kind: 'evm',
6
- name: 'Tempo',
7
- } as const
8
-
9
- /** Tempo token used when the caller omits `destinationToken`. */
10
- const defaultDestinationToken = 'usdce'
11
-
12
- /** Source chains accepted by the funding route inventory. */
13
- const sourceChains = [
14
- {
15
- addressFormat: 'evm',
16
- aliases: ['ethereum', 'eth', 'eip155:1'],
17
- id: 'eip155:1',
18
- kind: 'evm',
19
- name: 'Ethereum',
20
- providerIds: {
21
- across: '1',
22
- bridge: 'ethereum',
23
- bungee: '1',
24
- lifi: '1',
25
- relay: '1',
26
- },
27
- slug: 'ethereum',
28
- tokens: [
29
- {
30
- address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
31
- coingeckoId: 'usd-coin',
32
- decimals: 6,
33
- name: 'USD Coin',
34
- standard: 'ERC-20',
35
- symbol: 'USDC',
36
- },
37
- {
38
- address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
39
- coingeckoId: 'tether',
40
- decimals: 6,
41
- name: 'Tether USD',
42
- standard: 'ERC-20',
43
- symbol: 'USDT',
44
- },
45
- {
46
- address: '0x6c3ea9036406852006290770bedfcaba0e23a0e8',
47
- coingeckoId: 'paypal-usd',
48
- decimals: 6,
49
- name: 'PayPal USD',
50
- standard: 'ERC-20',
51
- symbol: 'PYUSD',
52
- },
53
- {
54
- address: '0x1abaea1f7c830bd89acc67ec4af516284b1bc33c',
55
- coingeckoId: 'euro-coin',
56
- decimals: 6,
57
- name: 'Euro Coin',
58
- standard: 'ERC-20',
59
- symbol: 'EURC',
60
- },
61
- {
62
- address: '0x6b175474e89094c44da98b954eedeac495271d0f',
63
- coingeckoId: 'dai',
64
- decimals: 18,
65
- name: 'Dai Stablecoin',
66
- standard: 'ERC-20',
67
- symbol: 'DAI',
68
- },
69
- ],
70
- },
71
- {
72
- addressFormat: 'evm',
73
- aliases: ['base', 'eip155:8453'],
74
- id: 'eip155:8453',
75
- kind: 'evm',
76
- name: 'Base',
77
- providerIds: {
78
- across: '8453',
79
- bridge: 'base',
80
- bungee: '8453',
81
- lifi: '8453',
82
- relay: '8453',
83
- },
84
- slug: 'base',
85
- tokens: [
86
- {
87
- address: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
88
- coingeckoId: 'usd-coin',
89
- decimals: 6,
90
- name: 'USD Coin',
91
- standard: 'ERC-20',
92
- symbol: 'USDC',
93
- },
94
- {
95
- address: '0xfde4c96c8593536e31f229ea8f37b2ada2699bb2',
96
- coingeckoId: 'tether',
97
- decimals: 6,
98
- name: 'Tether USD',
99
- standard: 'ERC-20',
100
- symbol: 'USDT',
101
- },
102
- {
103
- address: '0x60a3e35cc302bfa44cb288bc5a4f316fdb1adb42',
104
- coingeckoId: 'euro-coin',
105
- decimals: 6,
106
- name: 'Euro Coin',
107
- standard: 'ERC-20',
108
- symbol: 'EURC',
109
- },
110
- ],
111
- },
112
- {
113
- addressFormat: 'evm',
114
- aliases: ['bnb', 'bsc', 'eip155:56'],
115
- id: 'eip155:56',
116
- kind: 'evm',
117
- name: 'BNB Smart Chain',
118
- providerIds: {
119
- across: '56',
120
- bungee: '56',
121
- lifi: '56',
122
- relay: '56',
123
- },
124
- slug: 'bnb',
125
- tokens: [
126
- {
127
- address: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d',
128
- coingeckoId: 'usd-coin',
129
- decimals: 18,
130
- name: 'Binance-Peg USD Coin',
131
- standard: 'BEP-20',
132
- symbol: 'USDC',
133
- },
134
- {
135
- address: '0x55d398326f99059ff775485246999027b3197955',
136
- coingeckoId: 'tether',
137
- decimals: 18,
138
- name: 'Tether USD',
139
- standard: 'BEP-20',
140
- symbol: 'USDT',
141
- },
142
- ],
143
- },
144
- {
145
- addressFormat: 'solana',
146
- aliases: ['solana', 'solana:mainnet'],
147
- id: 'solana:mainnet',
148
- kind: 'solana',
149
- name: 'Solana',
150
- providerIds: {
151
- bridge: 'solana',
152
- relay: 'solana',
153
- },
154
- slug: 'solana',
155
- tokens: [
156
- {
157
- address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
158
- coingeckoId: 'usd-coin',
159
- decimals: 6,
160
- name: 'USD Coin',
161
- standard: 'SPL',
162
- symbol: 'USDC',
163
- },
164
- {
165
- address: 'Es9vMFrzaCERmJfrF4H2FYD4KCo3LwC1uix9YEaQ8t1v',
166
- coingeckoId: 'tether',
167
- decimals: 6,
168
- name: 'Tether USD',
169
- standard: 'SPL',
170
- symbol: 'USDT',
171
- },
172
- ],
173
- },
174
- {
175
- addressFormat: 'tron',
176
- aliases: ['tron', 'tron:mainnet'],
177
- id: 'tron:mainnet',
178
- kind: 'tron',
179
- name: 'Tron',
180
- providerIds: {
181
- bridge: 'tron',
182
- relay: 'tron',
183
- },
184
- slug: 'tron',
185
- tokens: [
186
- {
187
- address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
188
- coingeckoId: 'tether',
189
- decimals: 6,
190
- name: 'Tether USD',
191
- standard: 'TRC-20',
192
- symbol: 'USDT',
193
- },
194
- ],
195
- },
196
- ] as const
197
-
198
- /** Tempo destination tokens supported by the initial funding route inventory. */
199
- const destinationTokens = [
200
- {
201
- address: '0x20c0000000000000000000000000000000000000',
202
- decimals: 6,
203
- name: 'pathUSD',
204
- slug: 'pathusd',
205
- standard: 'TIP-20',
206
- symbol: 'pathUSD',
207
- },
208
- {
209
- address: '0x20c000000000000000000000b9537d11c60e8b50',
210
- decimals: 6,
211
- name: 'Bridged USDC (Stargate)',
212
- slug: 'usdce',
213
- standard: 'TIP-20',
214
- symbol: 'USDC.e',
215
- },
216
- {
217
- address: '0x20c0000000000000000000001621e21f71cf12fb',
218
- decimals: 6,
219
- name: 'Bridged EURC',
220
- slug: 'eurce',
221
- standard: 'TIP-20',
222
- symbol: 'EURC.e',
223
- },
224
- {
225
- address: '0x20c00000000000000000000014f22ca97301eb73',
226
- decimals: 6,
227
- name: 'USDT0',
228
- slug: 'usdt0',
229
- standard: 'TIP-20',
230
- symbol: 'USDT0',
231
- },
232
- {
233
- address: '0x20c0000000000000000000003554d28269e0f3c2',
234
- decimals: 6,
235
- name: 'frxUSD',
236
- slug: 'frxusd',
237
- standard: 'TIP-20',
238
- symbol: 'frxUSD',
239
- },
240
- ] as const
241
-
242
- /** Providers exposed by the generic provider catalog. */
243
- const providers = [
244
- {
245
- capabilities: ['fundingRoutes'],
246
- id: 'across',
247
- kind: 'intentBridge',
248
- name: 'Across',
249
- requiresApiKey: true,
250
- status: 'inventoryOnly',
251
- },
252
- {
253
- capabilities: ['fundingRoutes'],
254
- id: 'relay',
255
- kind: 'solverNetwork',
256
- name: 'Relay',
257
- requiresApiKey: false,
258
- status: 'inventoryOnly',
259
- },
260
- {
261
- capabilities: ['fundingRoutes'],
262
- id: 'bridge',
263
- kind: 'enterpriseTransfer',
264
- name: 'Bridge.xyz',
265
- requiresApiKey: true,
266
- status: 'inventoryOnly',
267
- },
268
- {
269
- capabilities: ['fundingRoutes'],
270
- id: 'bungee',
271
- kind: 'aggregator',
272
- name: 'Bungee',
273
- requiresApiKey: false,
274
- status: 'inventoryOnly',
275
- },
276
- {
277
- capabilities: ['fundingRoutes'],
278
- id: 'lifi',
279
- kind: 'aggregator',
280
- name: 'LI.FI',
281
- requiresApiKey: true,
282
- status: 'planned',
283
- },
284
- ] as const
285
-
286
- type TokenInput = (typeof sourceChains)[number]['tokens'][number]
287
- type DestinationTokenInput = (typeof destinationTokens)[number]
288
- type ProviderInput = (typeof providers)[number]
289
- type SourceChainInput = (typeof sourceChains)[number]
290
-
291
- /** Provider ids accepted by the funding route inventory. */
292
- export type ProviderId = ProviderInput['id']
293
-
294
- /** Provider-specific route status for the requested amount. */
295
- export type RouteStatus = 'available' | 'thin' | 'unknown' | 'unavailable' | 'error'
296
-
297
- /** Machine-readable route quality tier. */
298
- export type QualityTier = 'liquid' | 'thin' | 'unknown' | 'unavailable' | 'error'
299
-
300
- /** Response expansions accepted by funding route discovery. */
301
- export type Include = 'quotes'
302
-
303
- /** Normalized chain reference passed to provider adapters. */
304
- export type ChainRef = ReturnType<typeof formatChain> | typeof destinationChain
305
-
306
- /** Normalized token amount passed to provider adapters. */
307
- export type TokenAmount = ReturnType<typeof resolveSourceAmount>
308
-
309
- /** Normalized token reference passed to provider adapters. */
310
- export type TokenRef =
311
- | ReturnType<typeof formatDestinationToken>
312
- | ReturnType<typeof formatSourceToken>
313
-
314
- /** A normalized funding route candidate returned by route discovery. */
315
- export type RouteCandidate = ReturnType<typeof formatRouteCandidate>
316
-
317
- /** Cache policy for a single funding route discovery request. */
318
- export type CachePolicy = {
319
- /** Whether provider adapters should bypass their own quote or inventory caches. */
320
- bypass: boolean
321
- }
322
-
323
- /** Normalized caller request passed to provider adapters. */
324
- export type QuoteRequest = {
325
- /** Optional Tempo destination token symbol, address, or token key. */
326
- destinationToken?: string | undefined
327
- /** Response expansions requested by the caller. */
328
- include: readonly Include[]
329
- /** Maximum number of route candidates requested by the caller. */
330
- limit: number
331
- /** Optional provider id filter. */
332
- provider?: string | undefined
333
- /** Source amount as supplied by the caller. */
334
- sourceAmount: string
335
- /** Unit used by {@link sourceAmount}. */
336
- sourceAmountUnits: SourceAmountUnits
337
- /** Chain alias or CAIP-2 source chain id. */
338
- sourceChain: string
339
- /** Source token symbol, contract address, mint, or Tempo token key. */
340
- sourceToken: string
341
- }
342
-
343
- /** Input passed to a provider adapter for one static route candidate probe. */
344
- export type QuoteProbeInput = {
345
- /** Cache policy for provider-side inventory, quote, and liquidity lookups. */
346
- cache: CachePolicy
347
- /** Destination chain, always Tempo mainnet in V1. */
348
- destinationChain: ChainRef
349
- /** Tempo token expected from this route. */
350
- destinationToken: TokenRef
351
- /** Response expansions requested by the caller. */
352
- include: readonly Include[]
353
- /** Normalized caller request that produced this route candidate. */
354
- request: QuoteRequest
355
- /** Static candidate being enriched with live provider information. */
356
- route: RouteCandidate
357
- /** Source amount in base units and display form. */
358
- sourceAmount: TokenAmount
359
- /** Chain where the caller currently holds funds. */
360
- sourceChain: ChainRef
361
- /** Token the caller currently holds. */
362
- sourceToken: TokenRef
363
- }
364
-
365
- /** Provider-specific source amount limits, expressed in source base units. */
366
- export type QuoteProbeLimits = {
367
- /** Provider-reported instant source amount capacity. */
368
- instantSourceAmount?: string | null | undefined
369
- /** Provider-reported maximum source amount. */
370
- maxSourceAmount?: string | null | undefined
371
- /** Provider-reported minimum source amount. */
372
- minSourceAmount?: string | null | undefined
373
- }
374
-
375
- /** Quote probe data returned by a provider adapter. */
376
- export type QuoteProbeResult = {
377
- /** Stable route error code when status is `error`. */
378
- errorCode?: string | null | undefined
379
- /** Provider quote expiry timestamp. */
380
- expiresAt?: string | null | undefined
381
- /** Provider-reported source amount limits. */
382
- limits?: QuoteProbeLimits | null | undefined
383
- /** Slippage-adjusted minimum destination amount in base units. */
384
- minimumOutputAmount?: string | null | undefined
385
- /** Expected destination amount in base units. */
386
- outputAmount?: string | null | undefined
387
- /** Expected destination amount rendered with destination token decimals. */
388
- outputAmountFormatted?: string | null | undefined
389
- /** Timestamp for the live quote or route probe. */
390
- sampledAt: string
391
- /** Provider-specific route status for the requested amount. */
392
- status: RouteStatus
393
- /** Provider-backed route quality metadata. */
394
- quality?: {
395
- /** Available USD capacity, when available. */
396
- availableVolumeUsd?: string | null | undefined
397
- /** Estimated settlement time in seconds, when known. */
398
- estimatedSeconds?: number | null | undefined
399
- /** Estimated fee in basis points, when known. */
400
- feeBps?: number | null | undefined
401
- /** 24h routed volume in USD, when available. */
402
- historicalVolumeUsd24h?: string | null | undefined
403
- /** Instant USD capacity, when available. */
404
- instantVolumeUsd?: string | null | undefined
405
- /** Where the live liquidity or support signal came from. */
406
- liquiditySource: string
407
- /** Explainable route score from 0 to 100, when enough signals are available. */
408
- score?: number | null | undefined
409
- /** Provider-specific quote source or endpoint detail. */
410
- sourceDetail?: string | null | undefined
411
- /** Machine-readable route quality tier. */
412
- tier?: QualityTier | undefined
413
- }
414
- }
415
-
416
- /** Token reference attached to a normalized provider fee. */
417
- export type ProviderQuoteFeeToken = {
418
- /** Token contract address on its chain. */
419
- address: string
420
- /** CAIP-2 chain id for the fee token. */
421
- chainId: string
422
- /** Number of decimal places used by the fee token. */
423
- decimals: number
424
- /** Fee token ticker symbol. */
425
- symbol: string
426
- }
427
-
428
- /** Normalized fee amount returned by a provider quote. */
429
- export type ProviderQuoteFee = {
430
- /** Fee amount in the fee token's base units. */
431
- amount: string
432
- /** Provider-estimated USD value of the fee. */
433
- amountUsd: string | null
434
- /** Fee as basis points of the quoted input, when available. */
435
- bps: number | null
436
- /** Token in which the fee amount is denominated. */
437
- token: ProviderQuoteFeeToken
438
- }
439
-
440
- /** Input passed to a provider for one explicit, depositor-specific quote. */
441
- export type ProviderQuoteInput = {
442
- /** Address that would submit the funding transaction. */
443
- depositor: string
444
- /** Optional destination recipient; providers default it to the depositor. */
445
- recipient?: string | undefined
446
- /** Curated route selected by the caller. */
447
- route: RouteCandidate
448
- }
449
-
450
- /** Dynamic data returned by an explicit provider quote. */
451
- export type ProviderQuoteResult = {
452
- /** Estimated settlement time in seconds. */
453
- estimatedSeconds: number | null
454
- /** Provider quote expiry timestamp. */
455
- expiresAt: string
456
- /** Current and maximum fee summaries. */
457
- fees: {
458
- /** Current estimated total fee. */
459
- total: ProviderQuoteFee
460
- /** Maximum total fee allowed by the quote. */
461
- totalMax: ProviderQuoteFee
462
- }
463
- /** Slippage-adjusted minimum destination amount in base units. */
464
- minimumOutputAmount: string
465
- /** Expected destination amount in base units. */
466
- outputAmount: string
467
- /** Timestamp when Tempo sampled the quote. */
468
- sampledAt: string
469
- }
470
-
471
- /** A normalized explicit funding quote returned to callers. */
472
- export type FundingQuote = ReturnType<typeof formatFundingQuote>
473
-
474
- /** Adapter used to enrich a static route candidate with live provider information. */
475
- export type ProviderAdapter = {
476
- /** Probes provider-backed quote information for one static candidate. */
477
- probeQuote(input: QuoteProbeInput, signal: AbortSignal): Promise<QuoteProbeResult>
478
- }
479
-
480
- /** Provider adapter registry, keyed by provider id. Missing adapters leave routes static. */
481
- export type ProviderAdapters = Partial<Record<ProviderId, ProviderAdapter>>
482
-
483
- /** Gets a depositor-specific quote without exposing provider execution payloads. */
484
- export type ProviderQuote = (
485
- input: ProviderQuoteInput,
486
- signal: AbortSignal,
487
- ) => Promise<ProviderQuoteResult>
488
-
489
- /** Static provider support rows used until live quote adapters are configured. */
490
- const inventory: readonly InventoryEntry[] = [
491
- { destinationToken: 'usdce', provider: 'across', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC'] }, // prettier-ignore
492
- { destinationToken: 'usdce', provider: 'relay', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC', 'USDT'] }, // prettier-ignore
493
- { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'base', 'solana'], sourceTokens: ['USDC'] }, // prettier-ignore
494
- { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'solana', 'tron'], sourceTokens: ['USDT'] }, // prettier-ignore
495
- { destinationToken: 'usdce', provider: 'bungee', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC'] }, // prettier-ignore
496
- ]
497
-
498
- type InventoryEntry = {
499
- destinationToken: string
500
- provider: ProviderInput['id']
501
- sourceChains: readonly string[]
502
- sourceTokens: readonly string[]
503
- }
504
-
505
- const defaultAdapterTimeoutMs = 750
506
- const defaultQuoteTimeoutMs = 5_000
507
- const includes = ['quotes'] as const
508
-
509
- /** Lists normalized chains and source tokens that can fund Tempo. */
510
- export function listChains() {
511
- return sourceChains.map((chain) => ({
512
- ...formatChain(chain),
513
- tokens: chain.tokens.map((token) => formatSourceToken(chain, token)),
514
- }))
515
- }
516
-
517
- /** Lists providers, optionally filtered by one provider capability. */
518
- export function listProviders(options: listProviders.Options = {}) {
519
- return providers
520
- .filter((provider) =>
521
- options.capability === undefined ? true : provider.capabilities.includes(options.capability),
522
- )
523
- .map((provider) => ({
524
- ...formatProvider(provider),
525
- status:
526
- options.adapters?.[provider.id] || options.configuredProviders?.includes(provider.id)
527
- ? ('configured' as const)
528
- : provider.status,
529
- }))
530
- }
531
-
532
- export declare namespace listProviders {
533
- /** Options for listing providers. */
534
- type Options = {
535
- /** Provider adapters configured for this deployment. */
536
- adapters?: ProviderAdapters | undefined
537
- /** Providers configured through capabilities outside discovery adapters. */
538
- configuredProviders?: readonly ProviderId[] | undefined
539
- /** Provider capability to require. */
540
- capability?: Capability | undefined
541
- }
542
- }
543
-
544
- /** Parses the comma-separated `include` query parameter. */
545
- export function parseInclude(input: string | undefined) {
546
- if (input === undefined || input.trim() === '') return []
547
- const parsed = input
548
- .split(',')
549
- .map((part) => part.trim())
550
- .filter(Boolean)
551
- for (const include of parsed)
552
- if (!(includes as readonly string[]).includes(include)) throw new UnsupportedIncludeError()
553
- return [...new Set(parsed)] as readonly Include[]
554
- }
555
-
556
- /** Lists funding route candidates, enriching static inventory when adapters are configured. */
557
- export async function listRoutes(options: listRoutes.Options) {
558
- const routes = listStaticRoutes(options)
559
- const adapterEntries = Object.entries(options.adapters ?? {})
560
- if (adapterEntries.length === 0) return routes
561
-
562
- return Promise.all(
563
- routes.map((route) =>
564
- enrichRoute(route, {
565
- adapters: options.adapters ?? {},
566
- cache: options.cache ?? { bypass: false },
567
- include: options.include ?? [],
568
- request: {
569
- destinationToken: options.destinationToken,
570
- include: options.include ?? [],
571
- limit: options.limit,
572
- provider: options.provider,
573
- sourceAmount: options.sourceAmount,
574
- sourceAmountUnits: options.sourceAmountUnits,
575
- sourceChain: options.sourceChain,
576
- sourceToken: options.sourceToken,
577
- },
578
- timeoutMs: options.adapterTimeoutMs ?? defaultAdapterTimeoutMs,
579
- }),
580
- ),
581
- )
582
- }
583
-
584
- /** Gets a depositor-specific quote for one curated funding route. */
585
- export async function quoteRoute(options: quoteRoute.Options): Promise<FundingQuote> {
586
- const [route] = listStaticRoutes({
587
- destinationToken: options.destinationToken,
588
- limit: 1,
589
- provider: options.provider,
590
- sourceAmount: options.sourceAmount,
591
- sourceAmountUnits: options.sourceAmountUnits,
592
- sourceChain: options.sourceChain,
593
- sourceToken: options.sourceToken,
594
- })
595
- if (!route) throw new FundingRouteNotFoundError()
596
-
597
- const quote = options.quote
598
- if (!quote) throw new ProviderNotConfiguredError()
599
-
600
- return formatFundingQuote(
601
- route,
602
- await runWithTimeout(
603
- (signal) =>
604
- quote(
605
- {
606
- depositor: options.depositor,
607
- ...(options.recipient === undefined ? {} : { recipient: options.recipient }),
608
- route,
609
- },
610
- signal,
611
- ),
612
- options.quoteTimeoutMs ?? defaultQuoteTimeoutMs,
613
- ),
614
- )
615
- }
616
-
617
- export declare namespace quoteRoute {
618
- /** Options for resolving and quoting one curated funding route. */
619
- type Options = Omit<listStaticRoutes.Options, 'limit' | 'provider'> & {
620
- /** Address that would submit the funding transaction. */
621
- depositor: string
622
- /** Configured provider quote capability. */
623
- quote?: ProviderQuote | undefined
624
- /** Provider selected for the quote. */
625
- provider: 'across'
626
- /** Maximum time allowed for the live provider request. */
627
- quoteTimeoutMs?: number | undefined
628
- /** Optional destination recipient; defaults to the depositor. */
629
- recipient?: string | undefined
630
- }
631
- }
632
-
633
- /** Lists static funding route candidates for a normalized caller request. */
634
- export function listStaticRoutes(options: listStaticRoutes.Options) {
635
- const sourceChain = resolveSourceChain(options.sourceChain)
636
- const sourceToken = resolveSourceToken(sourceChain, options.sourceToken)
637
- const destinationToken = resolveDestinationToken(options.destinationToken)
638
- const provider = options.provider ? resolveProvider(options.provider) : undefined
639
-
640
- if (!sourceToken) {
641
- validateSourceAmountSyntax(options.sourceAmount, options.sourceAmountUnits)
642
- return []
643
- }
644
-
645
- const sourceAmount = resolveSourceAmount({
646
- amount: options.sourceAmount,
647
- token: sourceToken,
648
- units: options.sourceAmountUnits,
649
- })
650
-
651
- return inventory
652
- .filter((entry) => entry.sourceChains.includes(sourceChain.slug))
653
- .filter((entry) => entry.sourceTokens.includes(sourceToken.symbol))
654
- .filter((entry) => entry.destinationToken === destinationToken.slug)
655
- .filter((entry) => provider === undefined || entry.provider === provider.id)
656
- .slice(0, options.limit)
657
- .map((entry) =>
658
- formatRouteCandidate({
659
- destinationToken,
660
- provider: providers.find((candidate) => candidate.id === entry.provider)!,
661
- sourceAmount,
662
- sourceChain,
663
- sourceToken,
664
- }),
665
- )
666
- }
667
-
668
- export declare namespace listStaticRoutes {
669
- /** Options for listing static funding routes. */
670
- type Options = {
671
- /** Optional Tempo destination token symbol, address, or token key. */
672
- destinationToken?: string | undefined
673
- /** Maximum number of route candidates to return. */
674
- limit: number
675
- /** Optional provider id filter. */
676
- provider?: string | undefined
677
- /** Source amount as supplied by the caller. */
678
- sourceAmount: string
679
- /** Unit used by {@link sourceAmount}. */
680
- sourceAmountUnits: SourceAmountUnits
681
- /** Chain alias or CAIP-2 source chain id. */
682
- sourceChain: string
683
- /** Source token symbol, contract address, mint, or Tempo token key. */
684
- sourceToken: string
685
- }
686
- }
687
-
688
- export declare namespace listRoutes {
689
- /** Options for listing funding routes. */
690
- type Options = listStaticRoutes.Options & {
691
- /** Provider adapters used to enrich static inventory with live data. */
692
- adapters?: ProviderAdapters | undefined
693
- /** Per-provider quote timeout in milliseconds. */
694
- adapterTimeoutMs?: number | undefined
695
- /** Cache policy for provider-side inventory, quote, and liquidity lookups. */
696
- cache?: CachePolicy | undefined
697
- /** Response expansions requested by the caller. */
698
- include?: readonly Include[] | undefined
699
- }
700
- }
701
-
702
- /** Provider capability identifiers accepted by the generic provider catalog. */
703
- export type Capability = 'fundingRoutes'
704
-
705
- /** Source amount unit accepted by the funding route request. */
706
- export type SourceAmountUnits = 'baseUnits' | 'decimal'
707
-
708
- function tokenKey(chain: { id: string }, token: TokenInput | DestinationTokenInput) {
709
- const standard =
710
- token.standard === 'SPL' ? 'spl' : token.standard === 'TRC-20' ? 'trc20' : 'erc20'
711
- return `${chain.id}/${standard}:${token.address}`
712
- }
713
-
714
- function decimalFromBaseUnits(baseUnits: string, decimals: number) {
715
- const padded = baseUnits.padStart(decimals + 1, '0')
716
- const whole = decimals === 0 ? padded : padded.slice(0, -decimals)
717
- const fraction = decimals === 0 ? '' : padded.slice(-decimals).replace(/0+$/, '')
718
- return fraction ? `${whole}.${fraction}` : whole
719
- }
720
-
721
- async function enrichRoute(
722
- route: RouteCandidate,
723
- options: {
724
- adapters: ProviderAdapters
725
- cache: CachePolicy
726
- include: readonly Include[]
727
- request: QuoteRequest
728
- timeoutMs: number
729
- },
730
- ) {
731
- const adapter = options.adapters[route.provider.id as ProviderId]
732
- if (!adapter) return route
733
-
734
- try {
735
- const quote = await runWithTimeout(
736
- (signal) =>
737
- adapter.probeQuote(
738
- {
739
- cache: options.cache,
740
- destinationChain: route.destinationChain,
741
- destinationToken: route.destinationToken,
742
- include: options.include,
743
- request: options.request,
744
- route,
745
- sourceAmount: route.sourceAmount,
746
- sourceChain: route.sourceChain,
747
- sourceToken: route.sourceToken,
748
- },
749
- signal,
750
- ),
751
- options.timeoutMs,
752
- )
753
- return {
754
- ...route,
755
- errorCode: quote.errorCode ?? null,
756
- quality: {
757
- ...route.quality,
758
- ...(quote.status === 'error' ? { tier: 'error' as const } : {}),
759
- ...quote.quality,
760
- },
761
- quote: quote.status === 'error' ? null : formatRouteQuote(route, quote),
762
- status: quote.status,
763
- }
764
- } catch (cause) {
765
- return markRouteError(route, cause instanceof ProviderAdapterTimeoutError ? 'provider_timeout' : 'provider_error') // prettier-ignore
766
- }
767
- }
768
-
769
- function formatChain(chain: SourceChainInput) {
770
- const { addressFormat, id, kind, name, providerIds } = chain
771
- return { addressFormat, id, kind, name, providerIds }
772
- }
773
-
774
- function formatDestinationToken(token: DestinationTokenInput) {
775
- return {
776
- address: token.address,
777
- decimals: token.decimals,
778
- metadata: {},
779
- name: token.name,
780
- standard: token.standard,
781
- symbol: token.symbol,
782
- tokenKey: tokenKey(destinationChain, token),
783
- verified: true,
784
- }
785
- }
786
-
787
- function formatProvider(provider: ProviderInput) {
788
- const { id, kind, name, requiresApiKey, status } = provider
789
- return { capabilities: [...provider.capabilities], id, kind, name, requiresApiKey, status }
790
- }
791
-
792
- function formatProviderRef(provider: ProviderInput) {
793
- const { id, kind, name, requiresApiKey } = provider
794
- return { id, kind, name, requiresApiKey }
795
- }
796
-
797
- function formatRouteCandidate(options: {
798
- destinationToken: DestinationTokenInput
799
- provider: ProviderInput
800
- sourceAmount: ReturnType<typeof resolveSourceAmount>
801
- sourceChain: SourceChainInput
802
- sourceToken: TokenInput
803
- }) {
804
- return {
805
- destinationChain,
806
- destinationToken: formatDestinationToken(options.destinationToken),
807
- errorCode: null,
808
- id: [
809
- options.sourceChain.slug,
810
- options.sourceToken.symbol.toLowerCase(),
811
- 'tempo',
812
- options.destinationToken.slug,
813
- options.provider.id,
814
- ].join('-'),
815
- provider: formatProviderRef(options.provider),
816
- quality: {
817
- availableVolumeUsd: null,
818
- estimatedSeconds: null,
819
- feeBps: null,
820
- historicalVolumeUsd24h: null,
821
- instantVolumeUsd: null,
822
- liquiditySource: 'staticInventory',
823
- score: null,
824
- sourceDetail: null,
825
- tier: 'unknown',
826
- },
827
- quote: null,
828
- sourceAmount: options.sourceAmount,
829
- sourceChain: formatChain(options.sourceChain),
830
- sourceToken: formatSourceToken(options.sourceChain, options.sourceToken),
831
- status: 'unknown',
832
- } as const
833
- }
834
-
835
- function formatSourceToken(chain: SourceChainInput, token: TokenInput) {
836
- return {
837
- address: token.address,
838
- decimals: token.decimals,
839
- metadata: { coingeckoId: token.coingeckoId },
840
- name: token.name,
841
- standard: token.standard,
842
- symbol: token.symbol,
843
- tokenKey: tokenKey(chain, token),
844
- verified: true,
845
- }
846
- }
847
-
848
- function normalizeInput(value: string) {
849
- return value.trim().toLowerCase()
850
- }
851
-
852
- function parseBaseUnits(value: string) {
853
- if (!/^\d+$/.test(value) || BigInt(value) <= 0n) throw new InvalidAmountError()
854
- return BigInt(value).toString()
855
- }
856
-
857
- function parseDecimalUnits(value: string, decimals: number) {
858
- if (!/^\d+(\.\d+)?$/.test(value)) throw new InvalidAmountError()
859
- const [whole, fraction = ''] = value.split('.')
860
- if (fraction.length > decimals) throw new InvalidAmountError()
861
- const baseUnits = BigInt(`${whole}${fraction.padEnd(decimals, '0')}`)
862
- if (baseUnits <= 0n) throw new InvalidAmountError()
863
- return baseUnits.toString()
864
- }
865
-
866
- function formatRouteQuote(route: RouteCandidate, quote: QuoteProbeResult) {
867
- return {
868
- expiresAt: quote.expiresAt ?? null,
869
- inputAmount: route.sourceAmount.amount,
870
- limits: quote.limits
871
- ? {
872
- instantSourceAmount: quote.limits.instantSourceAmount ?? null,
873
- maxSourceAmount: quote.limits.maxSourceAmount ?? null,
874
- minSourceAmount: quote.limits.minSourceAmount ?? null,
875
- }
876
- : null,
877
- minimumOutputAmount: quote.minimumOutputAmount ?? null,
878
- outputAmount: quote.outputAmount ?? null,
879
- outputAmountFormatted: quote.outputAmountFormatted ?? null,
880
- sampledAt: quote.sampledAt,
881
- } as const
882
- }
883
-
884
- function formatFundingQuote(route: RouteCandidate, quote: ProviderQuoteResult) {
885
- return {
886
- destinationChain: route.destinationChain,
887
- destinationToken: route.destinationToken,
888
- estimatedSeconds: quote.estimatedSeconds,
889
- expiresAt: quote.expiresAt,
890
- fees: quote.fees,
891
- inputAmount: route.sourceAmount.amount,
892
- minimumOutputAmount: quote.minimumOutputAmount,
893
- outputAmount: quote.outputAmount,
894
- outputAmountFormatted: decimalFromBaseUnits(
895
- quote.outputAmount,
896
- route.destinationToken.decimals,
897
- ),
898
- provider: route.provider,
899
- routeId: route.id,
900
- sampledAt: quote.sampledAt,
901
- sourceChain: route.sourceChain,
902
- sourceToken: route.sourceToken,
903
- } as const
904
- }
905
-
906
- function markRouteError(route: RouteCandidate, errorCode: string) {
907
- return {
908
- ...route,
909
- errorCode,
910
- quality: {
911
- ...route.quality,
912
- liquiditySource: 'providerError',
913
- score: null,
914
- sourceDetail: null,
915
- tier: 'error' as const,
916
- },
917
- quote: null,
918
- status: 'error' as const,
919
- }
920
- }
921
-
922
- function runWithTimeout<result>(fn: (signal: AbortSignal) => Promise<result>, timeoutMs: number) {
923
- const controller = new AbortController()
924
- const timeout = setTimeout(() => controller.abort(), timeoutMs)
925
- return Promise.race([
926
- fn(controller.signal),
927
- new Promise<never>((_, reject) => {
928
- if (controller.signal.aborted) {
929
- reject(new ProviderAdapterTimeoutError())
930
- return
931
- }
932
- controller.signal.addEventListener('abort', () => reject(new ProviderAdapterTimeoutError()), {
933
- once: true,
934
- })
935
- }),
936
- ]).finally(() => clearTimeout(timeout))
937
- }
938
-
939
- function resolveDestinationToken(input: string | undefined) {
940
- if (input === undefined) return destinationTokens.find((token) => token.slug === defaultDestinationToken)! // prettier-ignore
941
- const normalized = normalizeInput(input)
942
- const token = destinationTokens.find(
943
- (candidate) =>
944
- candidate.slug === normalized ||
945
- candidate.symbol.toLowerCase() === normalized ||
946
- candidate.address === normalized ||
947
- tokenKey(destinationChain, candidate).toLowerCase() === normalized,
948
- )
949
- if (!token) throw new UnsupportedDestinationTokenError()
950
- return token
951
- }
952
-
953
- function resolveProvider(input: string) {
954
- const provider = providers.find((candidate) => candidate.id === normalizeInput(input))
955
- if (!provider) throw new UnsupportedProviderError()
956
- return provider
957
- }
958
-
959
- function resolveSourceAmount(options: resolveSourceAmount.Options) {
960
- const amount =
961
- options.units === 'baseUnits'
962
- ? parseBaseUnits(options.amount)
963
- : parseDecimalUnits(options.amount, options.token.decimals)
964
- return {
965
- amount,
966
- formatted: decimalFromBaseUnits(amount, options.token.decimals),
967
- usd: null,
968
- }
969
- }
970
-
971
- declare namespace resolveSourceAmount {
972
- type Options = {
973
- amount: string
974
- token: TokenInput
975
- units: SourceAmountUnits
976
- }
977
- }
978
-
979
- function resolveSourceToken(chain: SourceChainInput, input: string) {
980
- const trimmed = input.trim()
981
- const normalized = trimmed.toLowerCase()
982
- return chain.tokens.find(
983
- (token) =>
984
- token.symbol.toLowerCase() === normalized ||
985
- matchesTokenIdentifier(chain, token.address, trimmed, normalized) ||
986
- matchesTokenIdentifier(chain, tokenKey(chain, token), trimmed, normalized),
987
- )
988
- }
989
-
990
- function matchesTokenIdentifier(
991
- chain: SourceChainInput,
992
- candidate: string,
993
- trimmed: string,
994
- normalized: string,
995
- ) {
996
- return chain.kind === 'evm' ? candidate.toLowerCase() === normalized : candidate === trimmed
997
- }
998
-
999
- function resolveSourceChain(input: string) {
1000
- const normalized = normalizeInput(input)
1001
- const chain = sourceChains.find(
1002
- (candidate) =>
1003
- candidate.id === normalized || (candidate.aliases as readonly string[]).includes(normalized),
1004
- )
1005
- if (!chain) throw new UnsupportedSourceChainError()
1006
- return chain
1007
- }
1008
-
1009
- function validateSourceAmountSyntax(value: string, units: SourceAmountUnits) {
1010
- if (units === 'baseUnits') {
1011
- parseBaseUnits(value)
1012
- return
1013
- }
1014
- if (!/^\d+(\.\d+)?$/.test(value)) throw new InvalidAmountError()
1015
- const [whole, fraction = ''] = value.split('.')
1016
- if (BigInt(`${whole}${fraction}`) <= 0n) throw new InvalidAmountError()
1017
- }
1018
-
1019
- /** Error thrown when the caller supplies an unsupported destination token. */
1020
- export class UnsupportedDestinationTokenError extends Error {
1021
- override name = 'FundingRoutes.UnsupportedDestinationTokenError'
1022
- }
1023
-
1024
- /** Error thrown when the caller supplies an invalid source amount. */
1025
- export class InvalidAmountError extends Error {
1026
- override name = 'FundingRoutes.InvalidAmountError'
1027
- }
1028
-
1029
- /** Error thrown when no curated route matches an explicit quote request. */
1030
- export class FundingRouteNotFoundError extends Error {
1031
- override name = 'FundingRoutes.FundingRouteNotFoundError'
1032
- }
1033
-
1034
- /** Error thrown internally when a provider adapter exceeds its route quote timeout. */
1035
- export class ProviderAdapterTimeoutError extends Error {
1036
- override name = 'FundingRoutes.ProviderAdapterTimeoutError'
1037
- }
1038
-
1039
- /** Error thrown when a requested provider quote is temporarily unavailable. */
1040
- export class ProviderQuoteUnavailableError extends Error {
1041
- override name = 'FundingRoutes.ProviderQuoteUnavailableError'
1042
- }
1043
-
1044
- /** Error thrown when a provider rate-limits a quote request. */
1045
- export class ProviderRateLimitError extends Error {
1046
- override name = 'FundingRoutes.ProviderRateLimitError'
1047
- }
1048
-
1049
- /** Error thrown when a route provider lacks explicit quote capability. */
1050
- export class ProviderNotConfiguredError extends Error {
1051
- override name = 'FundingRoutes.ProviderNotConfiguredError'
1052
- }
1053
-
1054
- /** Error thrown when the caller filters to an unknown provider. */
1055
- export class UnsupportedProviderError extends Error {
1056
- override name = 'FundingRoutes.UnsupportedProviderError'
1057
- }
1058
-
1059
- /** Error thrown when the caller requests an unsupported include expansion. */
1060
- export class UnsupportedIncludeError extends Error {
1061
- override name = 'FundingRoutes.UnsupportedIncludeError'
1062
- }
1063
-
1064
- /** Error thrown when the caller supplies an unsupported source chain. */
1065
- export class UnsupportedSourceChainError extends Error {
1066
- override name = 'FundingRoutes.UnsupportedSourceChainError'
1067
- }