tapimo 0.4.4 → 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 (162) hide show
  1. package/dist/App.d.ts +7403 -6127
  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 +115 -115
  10. package/dist/apps/data/App.d.ts +1838 -1534
  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/{FundingRouteProviders.d.ts → FundingQuoteProviders.d.ts} +7 -7
  15. package/dist/apps/data/{FundingRouteProviders.d.ts.map → FundingQuoteProviders.d.ts.map} +1 -1
  16. package/dist/apps/data/{FundingRouteProviders.js → FundingQuoteProviders.js} +36 -91
  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/funding.d.ts +207 -388
  35. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  36. package/dist/apps/data/routes/funding.js +143 -221
  37. package/dist/apps/data/routes/funding.js.map +1 -1
  38. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  39. package/dist/apps/data/routes/rpc.js +86 -16
  40. package/dist/apps/data/routes/rpc.js.map +1 -1
  41. package/dist/apps/data/routes/tokenlist.d.ts +33 -33
  42. package/dist/apps/data/routes/transactions.d.ts +281 -281
  43. package/dist/apps/data/routes/transfers.d.ts +58 -58
  44. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  45. package/dist/apps/data/routes/webhooks.d.ts +340 -0
  46. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  47. package/dist/apps/data/routes/webhooks.js +13 -1
  48. package/dist/apps/data/routes/webhooks.js.map +1 -1
  49. package/dist/apps/index.d.ts +1 -1
  50. package/dist/apps/index.js +1 -1
  51. package/dist/apps/management/App.d.ts +1090 -108
  52. package/dist/apps/management/App.d.ts.map +1 -1
  53. package/dist/apps/management/App.js +4 -0
  54. package/dist/apps/management/App.js.map +1 -1
  55. package/dist/apps/management/routes/api-keys.d.ts +118 -118
  56. package/dist/apps/management/routes/api-keys.js +2 -2
  57. package/dist/apps/management/routes/api-keys.js.map +1 -1
  58. package/dist/apps/management/routes/billing.d.ts +207 -207
  59. package/dist/apps/management/routes/invite-links.d.ts +1100 -0
  60. package/dist/apps/management/routes/invite-links.d.ts.map +1 -0
  61. package/dist/apps/management/routes/invite-links.js +411 -0
  62. package/dist/apps/management/routes/invite-links.js.map +1 -0
  63. package/dist/apps/management/routes/me.d.ts +17 -17
  64. package/dist/apps/management/routes/members.d.ts +71 -71
  65. package/dist/apps/management/routes/orgs.d.ts +12 -12
  66. package/dist/apps/management/routes/projects.d.ts +70 -70
  67. package/dist/apps/management/routes/scopes.d.ts +11 -11
  68. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  69. package/dist/apps/management/routes/scopes.js +2 -2
  70. package/dist/apps/management/routes/scopes.js.map +1 -1
  71. package/dist/apps/management/routes/usage.d.ts +75 -75
  72. package/dist/apps/relay/App.d.ts.map +1 -1
  73. package/dist/apps/relay/App.js +42 -4
  74. package/dist/apps/relay/App.js.map +1 -1
  75. package/dist/db/Db.d.ts +3 -0
  76. package/dist/db/Db.d.ts.map +1 -1
  77. package/dist/db/Db.js +57 -0
  78. package/dist/db/Db.js.map +1 -1
  79. package/dist/db/Schema.d.ts +31 -0
  80. package/dist/db/Schema.d.ts.map +1 -1
  81. package/dist/db/Schema.js +31 -0
  82. package/dist/db/Schema.js.map +1 -1
  83. package/dist/db/tables/inviteLinks.d.ts +42 -0
  84. package/dist/db/tables/inviteLinks.d.ts.map +1 -0
  85. package/dist/db/tables/inviteLinks.js +148 -0
  86. package/dist/db/tables/inviteLinks.js.map +1 -0
  87. package/dist/db/tables/organizations.d.ts.map +1 -1
  88. package/dist/db/tables/organizations.js +2 -0
  89. package/dist/db/tables/organizations.js.map +1 -1
  90. package/dist/handlers/relay.d.ts.map +1 -1
  91. package/dist/handlers/relay.js +13 -3
  92. package/dist/handlers/relay.js.map +1 -1
  93. package/dist/internal/Auth.d.ts +9 -1
  94. package/dist/internal/Auth.d.ts.map +1 -1
  95. package/dist/internal/Auth.js +130 -10
  96. package/dist/internal/Auth.js.map +1 -1
  97. package/dist/internal/EdgeCache.d.ts +3 -1
  98. package/dist/internal/EdgeCache.d.ts.map +1 -1
  99. package/dist/internal/EdgeCache.js +17 -2
  100. package/dist/internal/EdgeCache.js.map +1 -1
  101. package/dist/internal/{FundingRoutes.d.ts → FundingQuotes.d.ts} +185 -428
  102. package/dist/internal/FundingQuotes.d.ts.map +1 -0
  103. package/dist/internal/{FundingRoutes.js → FundingQuotes.js} +93 -218
  104. package/dist/internal/FundingQuotes.js.map +1 -0
  105. package/dist/internal/Viem.d.ts +3 -1
  106. package/dist/internal/Viem.d.ts.map +1 -1
  107. package/dist/internal/Viem.js +11 -2
  108. package/dist/internal/Viem.js.map +1 -1
  109. package/dist/internal/index.d.ts +1 -1
  110. package/dist/internal/index.js +1 -1
  111. package/package.json +1 -1
  112. package/src/ApiKeys.test.ts +23 -0
  113. package/src/App.test-d.ts +2 -0
  114. package/src/App.ts +6 -0
  115. package/src/Client.test-d.ts +20 -11
  116. package/src/Scope.test.ts +1 -0
  117. package/src/Scope.ts +30 -4
  118. package/src/apps/data/App.test.ts +354 -0
  119. package/src/apps/data/App.ts +159 -52
  120. package/src/apps/data/FundingQuoteProviders.test.ts +151 -0
  121. package/src/apps/data/{FundingRouteProviders.ts → FundingQuoteProviders.ts} +40 -101
  122. package/src/apps/data/index.ts +1 -1
  123. package/src/apps/data/routes/balances.test.ts +64 -18
  124. package/src/apps/data/routes/balances.ts +76 -177
  125. package/src/apps/data/routes/blocks.ts +3 -5
  126. package/src/apps/data/routes/coingecko.ts +3 -8
  127. package/src/apps/data/routes/funding.test.ts +151 -206
  128. package/src/apps/data/routes/funding.ts +156 -291
  129. package/src/apps/data/routes/indexer.test.ts +97 -1
  130. package/src/apps/data/routes/rpc.test.ts +219 -0
  131. package/src/apps/data/routes/rpc.ts +92 -17
  132. package/src/apps/data/routes/webhooks.test.ts +21 -0
  133. package/src/apps/data/routes/webhooks.ts +13 -1
  134. package/src/apps/index.ts +1 -1
  135. package/src/apps/management/App.ts +4 -0
  136. package/src/apps/management/routes/api-keys.test.ts +47 -3
  137. package/src/apps/management/routes/api-keys.ts +2 -2
  138. package/src/apps/management/routes/invite-links.test.ts +385 -0
  139. package/src/apps/management/routes/invite-links.ts +570 -0
  140. package/src/apps/management/routes/scopes.test.ts +3 -2
  141. package/src/apps/management/routes/scopes.ts +4 -2
  142. package/src/apps/relay/App.test.ts +324 -4
  143. package/src/apps/relay/App.ts +40 -4
  144. package/src/db/Db.ts +65 -0
  145. package/src/db/Schema.ts +39 -0
  146. package/src/db/tables/inviteLinks.ts +187 -0
  147. package/src/db/tables/organizations.ts +2 -0
  148. package/src/handlers/relay.ts +16 -4
  149. package/src/internal/Auth.test.ts +132 -22
  150. package/src/internal/Auth.ts +171 -14
  151. package/src/internal/EdgeCache.test.ts +24 -3
  152. package/src/internal/EdgeCache.ts +18 -2
  153. package/src/internal/FundingQuotes.test.ts +174 -0
  154. package/src/internal/{FundingRoutes.ts → FundingQuotes.ts} +153 -312
  155. package/src/internal/Viem.ts +14 -5
  156. package/src/internal/index.test.ts +1 -1
  157. package/src/internal/index.ts +1 -1
  158. package/dist/apps/data/FundingRouteProviders.js.map +0 -1
  159. package/dist/internal/FundingRoutes.d.ts.map +0 -1
  160. package/dist/internal/FundingRoutes.js.map +0 -1
  161. package/src/apps/data/FundingRouteProviders.test.ts +0 -225
  162. package/src/internal/FundingRoutes.test.ts +0 -213
@@ -9,7 +9,7 @@ const destinationChain = {
9
9
  /** Tempo token used when the caller omits `destinationToken`. */
10
10
  const defaultDestinationToken = 'usdce'
11
11
 
12
- /** Source chains accepted by the funding route inventory. */
12
+ /** Source chains considered by funding quote providers. */
13
13
  const sourceChains = [
14
14
  {
15
15
  addressFormat: 'evm',
@@ -18,9 +18,6 @@ const sourceChains = [
18
18
  kind: 'evm',
19
19
  name: 'Ethereum',
20
20
  providerIds: {
21
- bridge: 'ethereum',
22
- bungee: '1',
23
- lifi: '1',
24
21
  relay: '1',
25
22
  },
26
23
  slug: 'ethereum',
@@ -74,9 +71,6 @@ const sourceChains = [
74
71
  kind: 'evm',
75
72
  name: 'Base',
76
73
  providerIds: {
77
- bridge: 'base',
78
- bungee: '8453',
79
- lifi: '8453',
80
74
  relay: '8453',
81
75
  },
82
76
  slug: 'base',
@@ -114,8 +108,6 @@ const sourceChains = [
114
108
  kind: 'evm',
115
109
  name: 'BNB Smart Chain',
116
110
  providerIds: {
117
- bungee: '56',
118
- lifi: '56',
119
111
  relay: '56',
120
112
  },
121
113
  slug: 'bnb',
@@ -138,61 +130,9 @@ const sourceChains = [
138
130
  },
139
131
  ],
140
132
  },
141
- {
142
- addressFormat: 'solana',
143
- aliases: ['solana', 'solana:mainnet'],
144
- id: 'solana:mainnet',
145
- kind: 'solana',
146
- name: 'Solana',
147
- providerIds: {
148
- bridge: 'solana',
149
- relay: 'solana',
150
- },
151
- slug: 'solana',
152
- tokens: [
153
- {
154
- address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
155
- coingeckoId: 'usd-coin',
156
- decimals: 6,
157
- name: 'USD Coin',
158
- standard: 'SPL',
159
- symbol: 'USDC',
160
- },
161
- {
162
- address: 'Es9vMFrzaCERmJfrF4H2FYD4KCo3LwC1uix9YEaQ8t1v',
163
- coingeckoId: 'tether',
164
- decimals: 6,
165
- name: 'Tether USD',
166
- standard: 'SPL',
167
- symbol: 'USDT',
168
- },
169
- ],
170
- },
171
- {
172
- addressFormat: 'tron',
173
- aliases: ['tron', 'tron:mainnet'],
174
- id: 'tron:mainnet',
175
- kind: 'tron',
176
- name: 'Tron',
177
- providerIds: {
178
- bridge: 'tron',
179
- relay: 'tron',
180
- },
181
- slug: 'tron',
182
- tokens: [
183
- {
184
- address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
185
- coingeckoId: 'tether',
186
- decimals: 6,
187
- name: 'Tether USD',
188
- standard: 'TRC-20',
189
- symbol: 'USDT',
190
- },
191
- ],
192
- },
193
133
  ] as const
194
134
 
195
- /** Tempo destination tokens supported by the initial funding route inventory. */
135
+ /** Tempo destination tokens supported by funding quote providers. */
196
136
  const destinationTokens = [
197
137
  {
198
138
  address: '0x20c0000000000000000000000000000000000000',
@@ -236,39 +176,14 @@ const destinationTokens = [
236
176
  },
237
177
  ] as const
238
178
 
239
- /** Providers exposed by the generic provider catalog. */
179
+ /** Providers supported by live funding quotes. */
240
180
  const providers = [
241
181
  {
242
- capabilities: ['fundingRoutes'],
243
182
  id: 'relay',
244
183
  kind: 'solverNetwork',
245
184
  name: 'Relay',
246
185
  requiresApiKey: false,
247
- status: 'inventoryOnly',
248
- },
249
- {
250
- capabilities: ['fundingRoutes'],
251
- id: 'bridge',
252
- kind: 'enterpriseTransfer',
253
- name: 'Bridge.xyz',
254
- requiresApiKey: true,
255
- status: 'inventoryOnly',
256
- },
257
- {
258
- capabilities: ['fundingRoutes'],
259
- id: 'bungee',
260
- kind: 'aggregator',
261
- name: 'Bungee',
262
- requiresApiKey: false,
263
- status: 'inventoryOnly',
264
- },
265
- {
266
- capabilities: ['fundingRoutes'],
267
- id: 'lifi',
268
- kind: 'aggregator',
269
- name: 'LI.FI',
270
- requiresApiKey: true,
271
- status: 'planned',
186
+ status: 'unconfigured',
272
187
  },
273
188
  ] as const
274
189
 
@@ -277,17 +192,14 @@ type DestinationTokenInput = (typeof destinationTokens)[number]
277
192
  type ProviderInput = (typeof providers)[number]
278
193
  type SourceChainInput = (typeof sourceChains)[number]
279
194
 
280
- /** Provider ids accepted by the funding route inventory. */
195
+ /** Provider ids accepted by funding quote requests. */
281
196
  export type ProviderId = ProviderInput['id']
282
197
 
283
- /** Provider-specific route status for the requested amount. */
284
- export type RouteStatus = 'available' | 'thin' | 'unknown' | 'unavailable' | 'error'
285
-
286
- /** Machine-readable route quality tier. */
287
- export type QualityTier = 'liquid' | 'thin' | 'unknown' | 'unavailable' | 'error'
198
+ /** Provider-specific quote status for the requested amount. */
199
+ export type QuoteStatus = 'available' | 'thin' | 'unknown' | 'unavailable'
288
200
 
289
- /** Response expansions accepted by funding route discovery. */
290
- export type Include = 'quotes'
201
+ /** Machine-readable quote quality tier. */
202
+ export type QualityTier = 'liquid' | 'thin' | 'unknown' | 'unavailable'
291
203
 
292
204
  /** Normalized chain reference passed to provider adapters. */
293
205
  export type ChainRef = ReturnType<typeof formatChain> | typeof destinationChain
@@ -300,10 +212,13 @@ export type TokenRef =
300
212
  | ReturnType<typeof formatDestinationToken>
301
213
  | ReturnType<typeof formatSourceToken>
302
214
 
303
- /** A normalized funding route candidate returned by route discovery. */
304
- export type RouteCandidate = ReturnType<typeof formatRouteCandidate>
215
+ /** A normalized internal candidate passed to funding quote providers. */
216
+ export type QuoteCandidate = ReturnType<typeof formatQuoteCandidate>
217
+
218
+ /** A successful normalized funding quote returned to callers. */
219
+ export type FundingQuote = ReturnType<typeof formatFundingQuote>
305
220
 
306
- /** Cache policy for a single funding route discovery request. */
221
+ /** Cache policy for a single funding quote request. */
307
222
  export type CachePolicy = {
308
223
  /** Whether provider adapters should bypass their own quote or inventory caches. */
309
224
  bypass: boolean
@@ -313,10 +228,6 @@ export type CachePolicy = {
313
228
  export type QuoteRequest = {
314
229
  /** Optional Tempo destination token symbol, address, or token key. */
315
230
  destinationToken?: string | undefined
316
- /** Response expansions requested by the caller. */
317
- include: readonly Include[]
318
- /** Maximum number of route candidates requested by the caller. */
319
- limit: number
320
231
  /** Optional provider id filter. */
321
232
  provider?: string | undefined
322
233
  /** Source amount as supplied by the caller. */
@@ -329,20 +240,18 @@ export type QuoteRequest = {
329
240
  sourceToken: string
330
241
  }
331
242
 
332
- /** Input passed to a provider adapter for one static route candidate probe. */
243
+ /** Input passed to a provider adapter for one curated quote candidate. */
333
244
  export type QuoteProbeInput = {
334
- /** Cache policy for provider-side inventory, quote, and liquidity lookups. */
245
+ /** Cache policy for provider-side discovery and quote lookups. */
335
246
  cache: CachePolicy
336
247
  /** Destination chain, always Tempo mainnet in V1. */
337
248
  destinationChain: ChainRef
338
- /** Tempo token expected from this route. */
249
+ /** Tempo token expected from this quote. */
339
250
  destinationToken: TokenRef
340
- /** Response expansions requested by the caller. */
341
- include: readonly Include[]
342
- /** Normalized caller request that produced this route candidate. */
251
+ /** Normalized caller request that produced this quote candidate. */
343
252
  request: QuoteRequest
344
- /** Static candidate being enriched with live provider information. */
345
- route: RouteCandidate
253
+ /** Curated candidate selected for live provider quoting. */
254
+ candidate: QuoteCandidate
346
255
  /** Source amount in base units and display form. */
347
256
  sourceAmount: TokenAmount
348
257
  /** Chain where the caller currently holds funds. */
@@ -351,72 +260,43 @@ export type QuoteProbeInput = {
351
260
  sourceToken: TokenRef
352
261
  }
353
262
 
354
- /** Provider-specific source amount limits, expressed in source base units. */
355
- export type QuoteProbeLimits = {
356
- /** Provider-reported instant source amount capacity. */
357
- instantSourceAmount?: string | null | undefined
358
- /** Provider-reported maximum source amount. */
359
- maxSourceAmount?: string | null | undefined
360
- /** Provider-reported minimum source amount. */
361
- minSourceAmount?: string | null | undefined
362
- }
363
-
364
263
  /** Quote probe data returned by a provider adapter. */
365
264
  export type QuoteProbeResult = {
366
- /** Stable route error code when status is `error`. */
367
- errorCode?: string | null | undefined
368
- /** Provider quote expiry timestamp. */
369
- expiresAt?: string | null | undefined
370
- /** Provider-reported source amount limits. */
371
- limits?: QuoteProbeLimits | null | undefined
372
265
  /** Slippage-adjusted minimum destination amount in base units. */
373
- minimumOutputAmount?: string | null | undefined
266
+ minimumOutputAmount?: string | undefined
374
267
  /** Expected destination amount in base units. */
375
- outputAmount?: string | null | undefined
268
+ outputAmount?: string | undefined
376
269
  /** Expected destination amount rendered with destination token decimals. */
377
- outputAmountFormatted?: string | null | undefined
378
- /** Timestamp for the live quote or route probe. */
270
+ outputAmountFormatted?: string | undefined
271
+ /** Timestamp for the live quote probe. */
379
272
  sampledAt: string
380
- /** Provider-specific route status for the requested amount. */
381
- status: RouteStatus
382
- /** Provider-backed route quality metadata. */
273
+ /** Provider-specific quote status for the requested amount. */
274
+ status: QuoteStatus
275
+ /** Provider-backed quote quality metadata. */
383
276
  quality?: {
384
- /** Available USD capacity, when available. */
385
- availableVolumeUsd?: string | null | undefined
386
277
  /** Estimated settlement time in seconds, when known. */
387
- estimatedSeconds?: number | null | undefined
388
- /** Estimated fee in basis points, when known. */
389
- feeBps?: number | null | undefined
390
- /** 24h routed volume in USD, when available. */
391
- historicalVolumeUsd24h?: string | null | undefined
392
- /** Instant USD capacity, when available. */
393
- instantVolumeUsd?: string | null | undefined
278
+ estimatedSeconds?: number | undefined
394
279
  /** Where the live liquidity or support signal came from. */
395
280
  liquiditySource: string
396
- /** Explainable route score from 0 to 100, when enough signals are available. */
397
- score?: number | null | undefined
398
281
  /** Provider-specific quote source or endpoint detail. */
399
- sourceDetail?: string | null | undefined
400
- /** Machine-readable route quality tier. */
282
+ sourceDetail?: string | undefined
283
+ /** Machine-readable quote quality tier. */
401
284
  tier?: QualityTier | undefined
402
285
  }
403
286
  }
404
287
 
405
- /** Adapter used to enrich a static route candidate with live provider information. */
288
+ /** Adapter used to request a live provider quote. */
406
289
  export type ProviderAdapter = {
407
290
  /** Probes provider-backed quote information for one static candidate. */
408
291
  probeQuote(input: QuoteProbeInput, signal: AbortSignal): Promise<QuoteProbeResult>
409
292
  }
410
293
 
411
- /** Provider adapter registry, keyed by provider id. Missing adapters leave routes static. */
294
+ /** Provider adapter registry, keyed by provider id. */
412
295
  export type ProviderAdapters = Partial<Record<ProviderId, ProviderAdapter>>
413
296
 
414
- /** Static provider support rows used until live quote adapters are configured. */
297
+ /** Curated provider support rows used to select live quote probes. */
415
298
  const inventory: readonly InventoryEntry[] = [
416
299
  { destinationToken: 'usdce', provider: 'relay', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC', 'USDT'] }, // prettier-ignore
417
- { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'base', 'solana'], sourceTokens: ['USDC'] }, // prettier-ignore
418
- { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'solana', 'tron'], sourceTokens: ['USDT'] }, // prettier-ignore
419
- { destinationToken: 'usdce', provider: 'bungee', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC'] }, // prettier-ignore
420
300
  ]
421
301
 
422
302
  type InventoryEntry = {
@@ -426,27 +306,34 @@ type InventoryEntry = {
426
306
  sourceTokens: readonly string[]
427
307
  }
428
308
 
429
- const defaultAdapterTimeoutMs = 750
430
- const includes = ['quotes'] as const
309
+ const defaultAdapterTimeoutMs = 2_000
431
310
 
432
- /** Lists normalized chains and source tokens that can fund Tempo. */
311
+ /** Lists normalized chains and source tokens supported by quote providers. */
433
312
  export function listChains() {
434
- return sourceChains.map((chain) => ({
435
- ...formatChain(chain),
436
- tokens: chain.tokens.map((token) => formatSourceToken(chain, token)),
437
- }))
313
+ return sourceChains.flatMap((chain) => {
314
+ const symbols = new Set(
315
+ inventory
316
+ .filter((entry) => entry.sourceChains.includes(chain.slug))
317
+ .flatMap((entry) => entry.sourceTokens),
318
+ )
319
+ if (symbols.size === 0) return []
320
+ return [
321
+ {
322
+ ...formatChain(chain),
323
+ tokens: chain.tokens
324
+ .filter((token) => symbols.has(token.symbol))
325
+ .map((token) => formatSourceToken(chain, token)),
326
+ },
327
+ ]
328
+ })
438
329
  }
439
330
 
440
- /** Lists providers, optionally filtered by one provider capability. */
331
+ /** Lists funding quote providers and their deployment status. */
441
332
  export function listProviders(options: listProviders.Options = {}) {
442
- return providers
443
- .filter((provider) =>
444
- options.capability === undefined ? true : provider.capabilities.includes(options.capability),
445
- )
446
- .map((provider) => ({
447
- ...formatProvider(provider),
448
- status: options.adapters?.[provider.id] ? ('configured' as const) : provider.status,
449
- }))
333
+ return providers.map((provider) => ({
334
+ ...formatProvider(provider),
335
+ status: options.adapters?.[provider.id] ? ('configured' as const) : provider.status,
336
+ }))
450
337
  }
451
338
 
452
339
  export declare namespace listProviders {
@@ -454,39 +341,19 @@ export declare namespace listProviders {
454
341
  type Options = {
455
342
  /** Provider adapters configured for this deployment. */
456
343
  adapters?: ProviderAdapters | undefined
457
- /** Provider capability to require. */
458
- capability?: Capability | undefined
459
344
  }
460
345
  }
461
346
 
462
- /** Parses the comma-separated `include` query parameter. */
463
- export function parseInclude(input: string | undefined) {
464
- if (input === undefined || input.trim() === '') return []
465
- const parsed = input
466
- .split(',')
467
- .map((part) => part.trim())
468
- .filter(Boolean)
469
- for (const include of parsed)
470
- if (!(includes as readonly string[]).includes(include)) throw new UnsupportedIncludeError()
471
- return [...new Set(parsed)] as readonly Include[]
472
- }
473
-
474
- /** Lists funding route candidates, enriching static inventory when adapters are configured. */
475
- export async function listRoutes(options: listRoutes.Options) {
476
- const routes = listStaticRoutes(options)
477
- const adapterEntries = Object.entries(options.adapters ?? {})
478
- if (adapterEntries.length === 0) return routes
479
-
480
- return Promise.all(
481
- routes.map((route) =>
482
- enrichRoute(route, {
347
+ /** Returns successful live funding quotes from configured providers. */
348
+ export async function listQuotes(options: listQuotes.Options) {
349
+ const candidates = listQuoteCandidates(options)
350
+ const results = await Promise.allSettled(
351
+ candidates.map((candidate) =>
352
+ quoteCandidate(candidate, {
483
353
  adapters: options.adapters ?? {},
484
354
  cache: options.cache ?? { bypass: false },
485
- include: options.include ?? [],
486
355
  request: {
487
356
  destinationToken: options.destinationToken,
488
- include: options.include ?? [],
489
- limit: options.limit,
490
357
  provider: options.provider,
491
358
  sourceAmount: options.sourceAmount,
492
359
  sourceAmountUnits: options.sourceAmountUnits,
@@ -497,10 +364,16 @@ export async function listRoutes(options: listRoutes.Options) {
497
364
  }),
498
365
  ),
499
366
  )
367
+ const quotes = results.flatMap((result) =>
368
+ result.status === 'fulfilled' && result.value ? [result.value] : [],
369
+ )
370
+ if (quotes.length === 0 && results.some((result) => result.status === 'rejected'))
371
+ throw new ProviderQuoteError()
372
+ return quotes
500
373
  }
501
374
 
502
- /** Lists static funding route candidates for a normalized caller request. */
503
- export function listStaticRoutes(options: listStaticRoutes.Options) {
375
+ /** Lists internal quote candidates for a normalized caller request. */
376
+ export function listQuoteCandidates(options: listQuoteCandidates.Options) {
504
377
  const sourceChain = resolveSourceChain(options.sourceChain)
505
378
  const sourceToken = resolveSourceToken(sourceChain, options.sourceToken)
506
379
  const destinationToken = resolveDestinationToken(options.destinationToken)
@@ -522,9 +395,8 @@ export function listStaticRoutes(options: listStaticRoutes.Options) {
522
395
  .filter((entry) => entry.sourceTokens.includes(sourceToken.symbol))
523
396
  .filter((entry) => entry.destinationToken === destinationToken.slug)
524
397
  .filter((entry) => provider === undefined || entry.provider === provider.id)
525
- .slice(0, options.limit)
526
398
  .map((entry) =>
527
- formatRouteCandidate({
399
+ formatQuoteCandidate({
528
400
  destinationToken,
529
401
  provider: providers.find((candidate) => candidate.id === entry.provider)!,
530
402
  sourceAmount,
@@ -534,13 +406,11 @@ export function listStaticRoutes(options: listStaticRoutes.Options) {
534
406
  )
535
407
  }
536
408
 
537
- export declare namespace listStaticRoutes {
538
- /** Options for listing static funding routes. */
409
+ export declare namespace listQuoteCandidates {
410
+ /** Options for selecting funding quote candidates. */
539
411
  type Options = {
540
412
  /** Optional Tempo destination token symbol, address, or token key. */
541
413
  destinationToken?: string | undefined
542
- /** Maximum number of route candidates to return. */
543
- limit: number
544
414
  /** Optional provider id filter. */
545
415
  provider?: string | undefined
546
416
  /** Source amount as supplied by the caller. */
@@ -554,30 +424,23 @@ export declare namespace listStaticRoutes {
554
424
  }
555
425
  }
556
426
 
557
- export declare namespace listRoutes {
558
- /** Options for listing funding routes. */
559
- type Options = listStaticRoutes.Options & {
560
- /** Provider adapters used to enrich static inventory with live data. */
427
+ export declare namespace listQuotes {
428
+ /** Options for requesting live funding quotes. */
429
+ type Options = listQuoteCandidates.Options & {
430
+ /** Provider adapters used to request live quotes. */
561
431
  adapters?: ProviderAdapters | undefined
562
432
  /** Per-provider quote timeout in milliseconds. */
563
433
  adapterTimeoutMs?: number | undefined
564
- /** Cache policy for provider-side inventory, quote, and liquidity lookups. */
434
+ /** Cache policy for provider-side discovery and quote lookups. */
565
435
  cache?: CachePolicy | undefined
566
- /** Response expansions requested by the caller. */
567
- include?: readonly Include[] | undefined
568
436
  }
569
437
  }
570
438
 
571
- /** Provider capability identifiers accepted by the generic provider catalog. */
572
- export type Capability = 'fundingRoutes'
573
-
574
- /** Source amount unit accepted by the funding route request. */
439
+ /** Source amount unit accepted by the funding quote request. */
575
440
  export type SourceAmountUnits = 'baseUnits' | 'decimal'
576
441
 
577
442
  function tokenKey(chain: { id: string }, token: TokenInput | DestinationTokenInput) {
578
- const standard =
579
- token.standard === 'SPL' ? 'spl' : token.standard === 'TRC-20' ? 'trc20' : 'erc20'
580
- return `${chain.id}/${standard}:${token.address}`
443
+ return `${chain.id}/erc20:${token.address}`
581
444
  }
582
445
 
583
446
  function decimalFromBaseUnits(baseUnits: string, decimals: number) {
@@ -587,52 +450,47 @@ function decimalFromBaseUnits(baseUnits: string, decimals: number) {
587
450
  return fraction ? `${whole}.${fraction}` : whole
588
451
  }
589
452
 
590
- async function enrichRoute(
591
- route: RouteCandidate,
453
+ async function quoteCandidate(
454
+ candidate: QuoteCandidate,
592
455
  options: {
593
456
  adapters: ProviderAdapters
594
457
  cache: CachePolicy
595
- include: readonly Include[]
596
458
  request: QuoteRequest
597
459
  timeoutMs: number
598
460
  },
599
461
  ) {
600
- const adapter = options.adapters[route.provider.id as ProviderId]
601
- if (!adapter) return route
602
-
603
- try {
604
- const quote = await runWithTimeout(
605
- (signal) =>
606
- adapter.probeQuote(
607
- {
608
- cache: options.cache,
609
- destinationChain: route.destinationChain,
610
- destinationToken: route.destinationToken,
611
- include: options.include,
612
- request: options.request,
613
- route,
614
- sourceAmount: route.sourceAmount,
615
- sourceChain: route.sourceChain,
616
- sourceToken: route.sourceToken,
617
- },
618
- signal,
619
- ),
620
- options.timeoutMs,
621
- )
622
- return {
623
- ...route,
624
- errorCode: quote.errorCode ?? null,
625
- quality: {
626
- ...route.quality,
627
- ...(quote.status === 'error' ? { tier: 'error' as const } : {}),
628
- ...quote.quality,
629
- },
630
- quote: quote.status === 'error' ? null : formatRouteQuote(route, quote),
631
- status: quote.status,
632
- }
633
- } catch (cause) {
634
- return markRouteError(route, cause instanceof ProviderAdapterTimeoutError ? 'provider_timeout' : 'provider_error') // prettier-ignore
635
- }
462
+ const adapter = options.adapters[candidate.provider.id as ProviderId]
463
+ if (!adapter) return undefined
464
+
465
+ const quote = await runWithTimeout(
466
+ (signal) =>
467
+ adapter.probeQuote(
468
+ {
469
+ cache: options.cache,
470
+ destinationChain: candidate.destinationChain,
471
+ destinationToken: candidate.destinationToken,
472
+ request: options.request,
473
+ candidate,
474
+ sourceAmount: candidate.sourceAmount,
475
+ sourceChain: candidate.sourceChain,
476
+ sourceToken: candidate.sourceToken,
477
+ },
478
+ signal,
479
+ ),
480
+ options.timeoutMs,
481
+ )
482
+ if (quote.status === 'unavailable') return undefined
483
+ if (
484
+ (quote.status !== 'available' && quote.status !== 'thin') ||
485
+ quote.outputAmount === undefined ||
486
+ quote.outputAmount === null
487
+ )
488
+ throw new ProviderQuoteError()
489
+ return formatFundingQuote(candidate, {
490
+ ...quote,
491
+ outputAmount: quote.outputAmount,
492
+ status: quote.status,
493
+ })
636
494
  }
637
495
 
638
496
  function formatChain(chain: SourceChainInput) {
@@ -655,7 +513,7 @@ function formatDestinationToken(token: DestinationTokenInput) {
655
513
 
656
514
  function formatProvider(provider: ProviderInput) {
657
515
  const { id, kind, name, requiresApiKey, status } = provider
658
- return { capabilities: [...provider.capabilities], id, kind, name, requiresApiKey, status }
516
+ return { id, kind, name, requiresApiKey, status }
659
517
  }
660
518
 
661
519
  function formatProviderRef(provider: ProviderInput) {
@@ -663,7 +521,7 @@ function formatProviderRef(provider: ProviderInput) {
663
521
  return { id, kind, name, requiresApiKey }
664
522
  }
665
523
 
666
- function formatRouteCandidate(options: {
524
+ function formatQuoteCandidate(options: {
667
525
  destinationToken: DestinationTokenInput
668
526
  provider: ProviderInput
669
527
  sourceAmount: ReturnType<typeof resolveSourceAmount>
@@ -673,7 +531,6 @@ function formatRouteCandidate(options: {
673
531
  return {
674
532
  destinationChain,
675
533
  destinationToken: formatDestinationToken(options.destinationToken),
676
- errorCode: null,
677
534
  id: [
678
535
  options.sourceChain.slug,
679
536
  options.sourceToken.symbol.toLowerCase(),
@@ -682,22 +539,9 @@ function formatRouteCandidate(options: {
682
539
  options.provider.id,
683
540
  ].join('-'),
684
541
  provider: formatProviderRef(options.provider),
685
- quality: {
686
- availableVolumeUsd: null,
687
- estimatedSeconds: null,
688
- feeBps: null,
689
- historicalVolumeUsd24h: null,
690
- instantVolumeUsd: null,
691
- liquiditySource: 'staticInventory',
692
- score: null,
693
- sourceDetail: null,
694
- tier: 'unknown',
695
- },
696
- quote: null,
697
542
  sourceAmount: options.sourceAmount,
698
543
  sourceChain: formatChain(options.sourceChain),
699
544
  sourceToken: formatSourceToken(options.sourceChain, options.sourceToken),
700
- status: 'unknown',
701
545
  } as const
702
546
  }
703
547
 
@@ -732,38 +576,36 @@ function parseDecimalUnits(value: string, decimals: number) {
732
576
  return baseUnits.toString()
733
577
  }
734
578
 
735
- function formatRouteQuote(route: RouteCandidate, quote: QuoteProbeResult) {
736
- return {
737
- expiresAt: quote.expiresAt ?? null,
738
- inputAmount: route.sourceAmount.amount,
739
- limits: quote.limits
740
- ? {
741
- instantSourceAmount: quote.limits.instantSourceAmount ?? null,
742
- maxSourceAmount: quote.limits.maxSourceAmount ?? null,
743
- minSourceAmount: quote.limits.minSourceAmount ?? null,
744
- }
745
- : null,
746
- minimumOutputAmount: quote.minimumOutputAmount ?? null,
747
- outputAmount: quote.outputAmount ?? null,
748
- outputAmountFormatted: quote.outputAmountFormatted ?? null,
749
- sampledAt: quote.sampledAt,
750
- } as const
579
+ type SuccessfulQuoteProbe = QuoteProbeResult & {
580
+ outputAmount: string
581
+ status: 'available' | 'thin'
751
582
  }
752
583
 
753
- function markRouteError(route: RouteCandidate, errorCode: string) {
584
+ function formatFundingQuote(candidate: QuoteCandidate, quote: SuccessfulQuoteProbe) {
754
585
  return {
755
- ...route,
756
- errorCode,
586
+ ...candidate,
757
587
  quality: {
758
- ...route.quality,
759
- liquiditySource: 'providerError',
760
- score: null,
761
- sourceDetail: null,
762
- tier: 'error' as const,
588
+ ...(quote.quality?.estimatedSeconds !== undefined
589
+ ? { estimatedSeconds: quote.quality.estimatedSeconds }
590
+ : {}),
591
+ liquiditySource: quote.quality?.liquiditySource ?? 'providerQuote',
592
+ ...(quote.quality?.sourceDetail !== undefined
593
+ ? { sourceDetail: quote.quality.sourceDetail }
594
+ : {}),
595
+ tier: quote.status === 'thin' ? ('thin' as const) : ('liquid' as const),
763
596
  },
764
- quote: null,
765
- status: 'error' as const,
766
- }
597
+ quote: {
598
+ inputAmount: candidate.sourceAmount.amount,
599
+ ...(quote.minimumOutputAmount !== undefined
600
+ ? { minimumOutputAmount: quote.minimumOutputAmount }
601
+ : {}),
602
+ outputAmount: quote.outputAmount,
603
+ outputAmountFormatted:
604
+ quote.outputAmountFormatted ??
605
+ decimalFromBaseUnits(quote.outputAmount, candidate.destinationToken.decimals),
606
+ sampledAt: quote.sampledAt,
607
+ },
608
+ } as const
767
609
  }
768
610
 
769
611
  function runWithTimeout<result>(fn: (signal: AbortSignal) => Promise<result>, timeoutMs: number) {
@@ -811,7 +653,6 @@ function resolveSourceAmount(options: resolveSourceAmount.Options) {
811
653
  return {
812
654
  amount,
813
655
  formatted: decimalFromBaseUnits(amount, options.token.decimals),
814
- usd: null,
815
656
  }
816
657
  }
817
658
 
@@ -865,30 +706,30 @@ function validateSourceAmountSyntax(value: string, units: SourceAmountUnits) {
865
706
 
866
707
  /** Error thrown when the caller supplies an unsupported destination token. */
867
708
  export class UnsupportedDestinationTokenError extends Error {
868
- override name = 'FundingRoutes.UnsupportedDestinationTokenError'
709
+ override name = 'FundingQuotes.UnsupportedDestinationTokenError'
869
710
  }
870
711
 
871
712
  /** Error thrown when the caller supplies an invalid source amount. */
872
713
  export class InvalidAmountError extends Error {
873
- override name = 'FundingRoutes.InvalidAmountError'
714
+ override name = 'FundingQuotes.InvalidAmountError'
874
715
  }
875
716
 
876
- /** Error thrown internally when a provider adapter exceeds its route quote timeout. */
717
+ /** Error thrown internally when a provider adapter exceeds its quote timeout. */
877
718
  export class ProviderAdapterTimeoutError extends Error {
878
- override name = 'FundingRoutes.ProviderAdapterTimeoutError'
719
+ override name = 'FundingQuotes.ProviderAdapterTimeoutError'
879
720
  }
880
721
 
881
- /** Error thrown when the caller filters to an unknown provider. */
882
- export class UnsupportedProviderError extends Error {
883
- override name = 'FundingRoutes.UnsupportedProviderError'
722
+ /** Error thrown when every matching provider fails to produce a quote. */
723
+ export class ProviderQuoteError extends Error {
724
+ override name = 'FundingQuotes.ProviderQuoteError'
884
725
  }
885
726
 
886
- /** Error thrown when the caller requests an unsupported include expansion. */
887
- export class UnsupportedIncludeError extends Error {
888
- override name = 'FundingRoutes.UnsupportedIncludeError'
727
+ /** Error thrown when the caller filters to an unknown provider. */
728
+ export class UnsupportedProviderError extends Error {
729
+ override name = 'FundingQuotes.UnsupportedProviderError'
889
730
  }
890
731
 
891
732
  /** Error thrown when the caller supplies an unsupported source chain. */
892
733
  export class UnsupportedSourceChainError extends Error {
893
- override name = 'FundingRoutes.UnsupportedSourceChainError'
734
+ override name = 'FundingQuotes.UnsupportedSourceChainError'
894
735
  }