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
@@ -4,18 +4,18 @@ import * as z from 'zod/mini'
4
4
  import type * as App from '../../../App.js'
5
5
  import * as Auth from '../../../internal/Auth.js'
6
6
  import * as Cache from '../../../internal/Cache.js'
7
- import * as FundingRoutes from '../../../internal/FundingRoutes.js'
7
+ import * as FundingQuotes from '../../../internal/FundingQuotes.js'
8
8
  import * as OpenApi from '../../../internal/OpenApi.js'
9
9
  import * as Response from '../../../internal/Response.js'
10
10
  import * as Schema from '../../../internal/Schema.js'
11
11
 
12
- /** Zod schemas owned by the funding routes resource. */
12
+ /** Zod schemas owned by funding quote resources. */
13
13
  export namespace schema {
14
14
  /** Source or destination chain reference. */
15
15
  export const Chain = Schema.describe(
16
16
  z.object({
17
17
  addressFormat: z
18
- .enum(['evm', 'solana', 'tron'])
18
+ .literal('evm')
19
19
  .check(
20
20
  z.describe('Address family used by accounts and token identifiers on this chain.'),
21
21
  z.meta({ examples: ['evm'] }),
@@ -24,12 +24,12 @@ export namespace schema {
24
24
  .string()
25
25
  .check(
26
26
  z.describe(
27
- 'Stable chain id, preferably CAIP-2 when one exists. Funding spans non-EVM chains, so ids are strings, unlike numeric `chainId` params elsewhere.',
27
+ 'Stable CAIP-2 chain id, represented as a string instead of the numeric `chainId` used elsewhere.',
28
28
  ),
29
29
  z.meta({ examples: ['eip155:8453'] }),
30
30
  ),
31
31
  kind: z
32
- .enum(['evm', 'solana', 'tron'])
32
+ .literal('evm')
33
33
  .check(
34
34
  z.describe('Chain execution family used for provider routing.'),
35
35
  z.meta({ examples: ['evm'] }),
@@ -40,11 +40,11 @@ export namespace schema {
40
40
  providerIds: z
41
41
  .optional(z.record(z.string(), z.string()))
42
42
  .check(
43
- z.describe('Provider-specific chain ids Tempo uses when querying route providers.'),
44
- z.meta({ examples: [{ bridge: 'base', relay: '8453' }] }),
43
+ z.describe('Provider-specific chain ids Tempo uses when requesting quotes.'),
44
+ z.meta({ examples: [{ relay: '8453' }] }),
45
45
  ),
46
46
  }),
47
- 'A normalized chain reference for funding routes.',
47
+ 'A normalized chain reference for funding quotes.',
48
48
  )
49
49
 
50
50
  /** Source or destination token reference. */
@@ -88,14 +88,14 @@ export namespace schema {
88
88
  verified: z
89
89
  .boolean()
90
90
  .check(
91
- z.describe('Whether Tempo recognizes this token in its funding route inventory.'),
91
+ z.describe('Whether Tempo recognizes this token in its funding quote inventory.'),
92
92
  z.meta({ examples: [true] }),
93
93
  ),
94
94
  }),
95
- 'A normalized token reference for funding routes.',
95
+ 'A normalized token reference for funding quotes.',
96
96
  )
97
97
 
98
- /** Source amount echoed by a funding route response. */
98
+ /** Source amount echoed by a funding quote response. */
99
99
  export const TokenAmount = Schema.describe(
100
100
  z.object({
101
101
  amount: Schema.DecimalString.check(
@@ -109,25 +109,21 @@ export namespace schema {
109
109
  ),
110
110
  z.meta({ examples: ['1'] }),
111
111
  ),
112
- usd: z
113
- .nullable(z.string())
114
- .check(
115
- z.describe('USD estimate for the requested source amount, when available.'),
116
- z.meta({ examples: ['1.00'] }),
117
- ),
118
112
  }),
119
113
  'The requested source amount in provider-safe base units and display form.',
120
114
  )
121
115
 
122
- /** Provider summary embedded in a route candidate. */
116
+ /** Provider summary embedded in a funding quote. */
123
117
  export const ProviderRef = Schema.describe(
124
118
  z.object({
125
- id: z.string().check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
119
+ id: z
120
+ .literal('relay')
121
+ .check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
126
122
  kind: z
127
123
  .string()
128
124
  .check(
129
- z.describe('Provider category, such as an intent bridge, solver network, or aggregator.'),
130
- z.meta({ examples: ['intentBridge'] }),
125
+ z.describe('Provider category, such as a solver network or aggregator.'),
126
+ z.meta({ examples: ['solverNetwork'] }),
131
127
  ),
132
128
  name: z
133
129
  .string()
@@ -136,124 +132,65 @@ export namespace schema {
136
132
  .boolean()
137
133
  .check(
138
134
  z.describe('Whether Tempo needs provider credentials to query or use this provider.'),
139
- z.meta({ examples: [true] }),
135
+ z.meta({ examples: [false] }),
140
136
  ),
141
137
  }),
142
- 'Provider metadata embedded in a route candidate.',
138
+ 'Provider metadata embedded in a funding quote.',
143
139
  )
144
140
 
145
- /** Route quality signals exposed directly instead of implied by list order. */
141
+ /** Quote quality signals exposed directly instead of implied by list order. */
146
142
  export const Quality = Schema.describe(
147
143
  z.object({
148
- availableVolumeUsd: z
149
- .nullable(z.string())
150
- .check(
151
- z.describe('Available USD capacity, when available.'),
152
- z.meta({ examples: ['1114274.43'] }),
153
- ),
154
144
  estimatedSeconds: z
155
- .nullable(z.number().check(z.int(), z.nonnegative()))
145
+ .optional(z.number().check(z.int(), z.nonnegative()))
156
146
  .check(
157
147
  z.describe('Estimated settlement time in seconds, when known.'),
158
148
  z.meta({ examples: [2] }),
159
149
  ),
160
- feeBps: z
161
- .nullable(z.number().check(z.int(), z.nonnegative()))
162
- .check(
163
- z.describe('Estimated fee in basis points, when known.'),
164
- z.meta({ examples: [109] }),
165
- ),
166
- historicalVolumeUsd24h: z
167
- .nullable(z.string())
168
- .check(
169
- z.describe('24h routed volume in USD, when available.'),
170
- z.meta({ examples: ['250000.00'] }),
171
- ),
172
- instantVolumeUsd: z
173
- .nullable(z.string())
174
- .check(
175
- z.describe('Instant USD capacity, when available.'),
176
- z.meta({ examples: ['12453.94'] }),
177
- ),
178
150
  liquiditySource: z
179
151
  .string()
180
152
  .check(
181
- z.describe('Where the liquidity or support signal came from.'),
182
- z.meta({ examples: ['staticInventory'] }),
183
- ),
184
- score: z
185
- .nullable(z.number().check(z.int(), z.gte(0), z.lte(100)))
186
- .check(
187
- z.describe('Explainable route score from 0 to 100, when enough signals are available.'),
188
- z.meta({ examples: [91] }),
153
+ z.describe('Provider source for the live quote quality signal.'),
154
+ z.meta({ examples: ['providerQuote'] }),
189
155
  ),
190
156
  sourceDetail: z
191
- .nullable(z.string())
157
+ .optional(z.string())
192
158
  .check(
193
159
  z.describe('Provider-specific source or endpoint detail for the quality signal.'),
194
160
  z.meta({ examples: ['providerEndpoint'] }),
195
161
  ),
196
162
  tier: z
197
- .enum(['liquid', 'thin', 'unknown', 'unavailable', 'error'])
163
+ .enum(['liquid', 'thin'])
198
164
  .check(
199
- z.describe('Machine-readable route quality tier.'),
200
- z.meta({ examples: ['unknown'] }),
165
+ z.describe('Machine-readable quality tier for a successful quote.'),
166
+ z.meta({ examples: ['liquid'] }),
201
167
  ),
202
168
  }),
203
- 'Machine-readable liquidity, fee, and source signals for a route candidate.',
169
+ 'Machine-readable liquidity, fee, and source signals for a successful quote.',
204
170
  )
205
171
 
206
- /** Provider-derived quote data for a route candidate. */
207
- export const RouteQuote = Schema.describe(
172
+ /** Provider-derived output, limits, and freshness data. */
173
+ export const QuoteDetails = Schema.describe(
208
174
  z.object({
209
- expiresAt: z
210
- .nullable(z.iso.datetime())
211
- .check(
212
- z.describe('Provider quote expiry timestamp.'),
213
- z.meta({ examples: ['2026-01-01T00:00:30Z'] }),
214
- ),
215
175
  inputAmount: Schema.DecimalString.check(
216
176
  z.describe('Source amount sent to the provider in base units.'),
217
177
  z.meta({ examples: ['1000000'] }),
218
178
  ),
219
- limits: z
220
- .nullable(
221
- z.object({
222
- instantSourceAmount: z
223
- .nullable(Schema.DecimalString)
224
- .check(
225
- z.describe('Provider-reported instant source amount capacity.'),
226
- z.meta({ examples: ['12453940000'] }),
227
- ),
228
- maxSourceAmount: z
229
- .nullable(Schema.DecimalString)
230
- .check(
231
- z.describe('Provider-reported maximum source amount.'),
232
- z.meta({ examples: ['1114274433200'] }),
233
- ),
234
- minSourceAmount: z
235
- .nullable(Schema.DecimalString)
236
- .check(
237
- z.describe('Provider-reported minimum source amount.'),
238
- z.meta({ examples: ['500063'] }),
239
- ),
240
- }),
241
- )
242
- .check(z.describe('Provider limits expressed in source base units.')),
243
179
  minimumOutputAmount: z
244
- .nullable(Schema.DecimalString)
180
+ .optional(Schema.DecimalString)
245
181
  .check(
246
182
  z.describe('Slippage-adjusted minimum destination amount in base units.'),
247
183
  z.meta({ examples: ['988000'] }),
248
184
  ),
249
185
  outputAmount: z
250
- .nullable(Schema.DecimalString)
186
+ .string()
187
+ .check(z.regex(/^\d+$/))
251
188
  .check(
252
189
  z.describe('Expected destination amount in base units.'),
253
190
  z.meta({ examples: ['989102'] }),
254
191
  ),
255
192
  outputAmountFormatted: z
256
- .nullable(z.string())
193
+ .string()
257
194
  .check(
258
195
  z.describe('Expected destination amount rendered with destination token decimals.'),
259
196
  z.meta({ examples: ['0.989102'] }),
@@ -261,58 +198,40 @@ export namespace schema {
261
198
  sampledAt: z.iso
262
199
  .datetime()
263
200
  .check(
264
- z.describe('Timestamp for the live quote or route probe.'),
201
+ z.describe('Timestamp for the live quote probe.'),
265
202
  z.meta({ examples: ['2026-01-01T00:00:00Z'] }),
266
203
  ),
267
204
  }),
268
- 'Provider-derived quote, limit, and freshness data for a route candidate.',
205
+ 'Provider-derived output, limits, and freshness data for a funding quote.',
269
206
  )
270
207
 
271
- /** Static or live funding route candidate. */
272
- export const RouteCandidate = Schema.describe(
208
+ /** Successful live funding quote. */
209
+ export const FundingQuote = Schema.describe(
273
210
  z.object({
274
211
  destinationChain: Chain.check(z.describe('Destination chain, always Tempo mainnet in V1.')),
275
- destinationToken: Token.check(z.describe('Tempo token expected from this route.')),
276
- errorCode: z
277
- .nullable(z.string())
278
- .check(
279
- z.describe('Stable route error code, when status is `error`.'),
280
- z.meta({ examples: ['provider_timeout'] }),
281
- ),
212
+ destinationToken: Token.check(z.describe('Tempo token expected from this quote.')),
282
213
  id: z
283
214
  .string()
284
215
  .check(
285
- z.describe('Stable deterministic route candidate id.'),
216
+ z.describe('Stable deterministic funding quote id.'),
286
217
  z.meta({ examples: ['base-usdc-tempo-usdce-relay'] }),
287
218
  ),
288
219
  provider: ProviderRef,
289
220
  quality: Quality,
290
- quote: z
291
- .nullable(RouteQuote)
292
- .check(z.describe('Provider-derived quote data, when a live route probe succeeds.')),
221
+ quote: QuoteDetails,
293
222
  sourceAmount: TokenAmount,
294
223
  sourceChain: Chain.check(z.describe('Chain where the caller currently holds funds.')),
295
224
  sourceToken: Token.check(z.describe('Token the caller currently holds.')),
296
- status: z
297
- .enum(['available', 'thin', 'unknown', 'unavailable', 'error'])
298
- .check(
299
- z.describe('Provider-specific route status for the requested amount.'),
300
- z.meta({ examples: ['unknown'] }),
301
- ),
302
225
  }),
303
- 'One provider-specific funding route candidate.',
226
+ 'One successful provider-specific funding quote.',
304
227
  )
305
228
 
306
- /** Generic provider catalog entry. */
229
+ /** Funding quote provider catalog entry. */
307
230
  export const Provider = Schema.describe(
308
231
  z.object({
309
- capabilities: z
310
- .array(z.enum(['fundingRoutes']))
311
- .check(
312
- z.describe('Provider capabilities Tempo exposes through public APIs.'),
313
- z.meta({ examples: [['fundingRoutes']] }),
314
- ),
315
- id: z.string().check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
232
+ id: z
233
+ .literal('relay')
234
+ .check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
316
235
  kind: z
317
236
  .string()
318
237
  .check(z.describe('Provider category.'), z.meta({ examples: ['solverNetwork'] })),
@@ -326,15 +245,15 @@ export namespace schema {
326
245
  z.meta({ examples: [false] }),
327
246
  ),
328
247
  status: z
329
- .enum(['configured', 'inventoryOnly', 'planned'])
248
+ .enum(['configured', 'unconfigured'])
330
249
  .check(
331
250
  z.describe(
332
- '`inventoryOnly` means Tempo exposes static route support but does not query live quotes yet. `planned` means the provider is listed for future support and may not return route candidates.',
251
+ '`configured` means live quotes are enabled for this deployment. `unconfigured` means the provider is supported but unavailable here.',
333
252
  ),
334
- z.meta({ examples: ['inventoryOnly'] }),
253
+ z.meta({ examples: ['configured', 'unconfigured'] }),
335
254
  ),
336
255
  }),
337
- 'One provider in the generic provider catalog.',
256
+ 'One funding quote provider.',
338
257
  )
339
258
 
340
259
  /** Chain inventory entry returned by the funding chains endpoint. */
@@ -345,9 +264,9 @@ export namespace schema {
345
264
  'One source chain and its known stablecoin inventory.',
346
265
  )
347
266
 
348
- /** Schemas for the listFundingRoutes operation. */
349
- export namespace listFundingRoutes {
350
- /** Query parameters for funding route discovery. */
267
+ /** Schemas for the quoteFunding operation. */
268
+ export namespace quoteFunding {
269
+ /** Query parameters for live funding quotes. */
351
270
  export const Query = z
352
271
  .strictObject({
353
272
  destinationToken: z
@@ -358,26 +277,21 @@ export namespace schema {
358
277
  ),
359
278
  z.meta({ examples: ['USDC.e'] }),
360
279
  ),
361
- include: z
362
- .optional(z.string())
363
- .check(
364
- z.describe('Comma-separated response expansions. V1 accepts `quotes`.'),
365
- z.meta({ examples: ['quotes'] }),
366
- ),
367
- limit: Schema.Limit,
368
280
  provider: z
369
- .optional(z.string())
281
+ .optional(z.literal('relay'))
370
282
  .check(
371
283
  z.describe(
372
- 'Only return candidates from this provider id, such as `relay`, `bridge`, or `bungee`. Planned providers can return an empty list.',
284
+ 'Only request a quote from this provider. The supported id is `relay`; omit it to query every configured provider.',
373
285
  ),
374
- z.meta({ examples: ['relay', 'bridge'] }),
286
+ z.meta({ examples: ['relay'] }),
375
287
  ),
376
288
  sourceAmount: z
377
289
  .string()
378
290
  .check(
379
- z.minLength(1),
380
- z.describe('Source token amount. Base units by default, so 1 USDC is `1000000`.'),
291
+ z.regex(/^(?=.*[1-9])\d+(\.\d+)?$/),
292
+ z.describe(
293
+ 'Positive source token amount. Base units by default, so 1 USDC is `1000000`.',
294
+ ),
381
295
  z.meta({ examples: ['1000000'] }),
382
296
  ),
383
297
  sourceAmountUnits: z
@@ -387,38 +301,30 @@ export namespace schema {
387
301
  z.meta({ examples: ['baseUnits', 'decimal'] }),
388
302
  ),
389
303
  sourceChain: z
304
+ .string()
305
+ .check(
306
+ z.minLength(1),
307
+ z.describe('Source chain alias or CAIP-2 id, such as `base` or `eip155:8453`.'),
308
+ z.meta({ examples: ['base', 'eip155:8453'] }),
309
+ ),
310
+ sourceToken: z
390
311
  .string()
391
312
  .check(
392
313
  z.minLength(1),
393
314
  z.describe(
394
- 'Source chain alias or CAIP-2 id, such as `base`, `solana`, `tron`, or `eip155:8453`.',
315
+ 'Source token symbol, contract address, or Tempo token key. Symbol and address lookup is scoped to `sourceChain` and case-insensitive. An unknown token returns an empty list.',
395
316
  ),
396
- z.meta({ examples: ['base', 'solana', 'tron'] }),
317
+ z.meta({ examples: ['USDC', '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'] }),
397
318
  ),
398
- sourceToken: z.string().check(
399
- z.minLength(1),
400
- z.describe(
401
- 'Source token symbol, contract address, mint, or Tempo token key. Symbol lookup is scoped to `sourceChain`; EVM identifiers are case-insensitive, while Solana and Tron identifiers must match exactly. An unknown token returns an empty list, not an error.',
402
- ),
403
- z.meta({
404
- examples: [
405
- 'USDC',
406
- 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
407
- 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
408
- ],
409
- }),
410
- ),
411
319
  })
412
- .check(z.describe('Query parameters for discovering funding routes into Tempo.'))
320
+ .check(z.describe('Query parameters for live funding quotes into Tempo.'))
413
321
 
414
- /** Non-paginated list of funding route candidates. */
322
+ /** Non-paginated list of successful funding quotes. */
415
323
  export const Response = Schema.describe(
416
324
  z.object({
417
- data: z
418
- .array(RouteCandidate)
419
- .check(z.describe('Funding route candidates matching the request.')),
325
+ data: z.array(FundingQuote).check(z.describe('Successful live funding quotes.')),
420
326
  }),
421
- 'A non-paginated list of funding route candidates.',
327
+ 'A non-paginated list of successful live funding quotes.',
422
328
  )
423
329
  }
424
330
 
@@ -429,7 +335,7 @@ export namespace schema {
429
335
  z.object({
430
336
  data: z
431
337
  .array(ChainInventory)
432
- .check(z.describe('Source chains and stablecoins known to the funding route API.')),
338
+ .check(z.describe('Source chains and stablecoins supported by funding quotes.')),
433
339
  }),
434
340
  'A non-paginated list of source chains and stablecoin inventory.',
435
341
  )
@@ -437,118 +343,89 @@ export namespace schema {
437
343
 
438
344
  /** Schemas for the listProviders operation. */
439
345
  export namespace listProviders {
440
- /** Query parameters for the generic provider catalog. */
441
- export const Query = z
442
- .strictObject({
443
- capability: z
444
- .optional(z.enum(['fundingRoutes']))
445
- .check(
446
- z.describe('Optional provider capability filter.'),
447
- z.meta({ examples: ['fundingRoutes'] }),
448
- ),
449
- })
450
- .check(z.describe('Query parameters for listing providers.'))
451
-
452
- /** Non-paginated generic provider catalog. */
346
+ /** Non-paginated funding quote provider catalog. */
453
347
  export const Response = Schema.describe(
454
348
  z.object({
455
- data: z.array(Provider).check(z.describe("Providers in Tempo's generic provider catalog.")),
349
+ data: z.array(Provider).check(z.describe("Providers in Tempo's funding quote catalog.")),
456
350
  }),
457
- 'A non-paginated list of providers.',
351
+ 'A non-paginated list of funding quote providers.',
458
352
  )
459
353
  }
460
354
  }
461
355
 
462
- // Examples derive from the static inventory so they never drift from real responses.
463
- const fundingRouteResponseExamples = {
464
- baseUsdc: {
465
- description:
466
- '`GET /v1/funding/routes?sourceChain=base&sourceToken=USDC&sourceAmount=1000000&provider=relay`',
467
- summary: 'Base USDC',
468
- value: {
469
- data: FundingRoutes.listStaticRoutes({
470
- limit: 10,
471
- provider: 'relay',
472
- sourceAmount: '1000000',
473
- sourceAmountUnits: 'baseUnits',
474
- sourceChain: 'base',
475
- sourceToken: 'USDC',
476
- }),
477
- } satisfies z.output<typeof schema.listFundingRoutes.Response>,
478
- },
479
- solanaUsdc: {
480
- description:
481
- '`GET /v1/funding/routes?sourceChain=solana&sourceToken=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&sourceAmount=1000000&provider=bridge`',
482
- summary: 'Solana USDC',
483
- value: {
484
- data: FundingRoutes.listStaticRoutes({
485
- limit: 10,
486
- provider: 'bridge',
487
- sourceAmount: '1000000',
488
- sourceAmountUnits: 'baseUnits',
489
- sourceChain: 'solana',
490
- sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
491
- }),
492
- } satisfies z.output<typeof schema.listFundingRoutes.Response>,
493
- },
494
- tronUsdt: {
495
- description:
496
- '`GET /v1/funding/routes?sourceChain=tron&sourceToken=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t&sourceAmount=1000000&provider=bridge`',
497
- summary: 'Tron USDT',
498
- value: {
499
- data: FundingRoutes.listStaticRoutes({
500
- limit: 10,
501
- provider: 'bridge',
502
- sourceAmount: '1000000',
503
- sourceAmountUnits: 'baseUnits',
504
- sourceChain: 'tron',
505
- sourceToken: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
506
- }),
507
- } satisfies z.output<typeof schema.listFundingRoutes.Response>,
508
- },
509
- } satisfies OpenApi.responses.Options<
510
- typeof schema.listFundingRoutes.Response
511
- >['success']['examples']
356
+ const fundingQuoteResponseExample = (() => {
357
+ const [candidate] = FundingQuotes.listQuoteCandidates({
358
+ provider: 'relay',
359
+ sourceAmount: '1000000',
360
+ sourceAmountUnits: 'baseUnits',
361
+ sourceChain: 'base',
362
+ sourceToken: 'USDC',
363
+ })
364
+ if (!candidate) throw new Error('Missing Relay funding quote example candidate')
365
+ return {
366
+ data: [
367
+ {
368
+ ...candidate,
369
+ quality: {
370
+ estimatedSeconds: 1,
371
+ liquiditySource: 'providerQuote',
372
+ sourceDetail: 'relay:quote-v2',
373
+ tier: 'liquid',
374
+ },
375
+ quote: {
376
+ inputAmount: '1000000',
377
+ minimumOutputAmount: '939242',
378
+ outputAmount: '979295',
379
+ outputAmountFormatted: '0.979295',
380
+ sampledAt: '2026-01-01T00:00:00.000Z',
381
+ },
382
+ },
383
+ ],
384
+ }
385
+ })() satisfies z.output<typeof schema.quoteFunding.Response>
512
386
 
513
387
  const fundingChainsResponseExample = {
514
- data: FundingRoutes.listChains(),
388
+ data: FundingQuotes.listChains(),
515
389
  } satisfies z.output<typeof schema.listFundingChains.Response>
516
390
 
517
391
  const providersResponseExample = {
518
- data: FundingRoutes.listProviders(),
392
+ data: FundingQuotes.listProviders().map((provider) => ({
393
+ ...provider,
394
+ status: 'configured' as const,
395
+ })),
519
396
  } satisfies z.output<typeof schema.listProviders.Response>
520
397
 
521
- /** Mounts funding route discovery and generic provider inventory endpoints. */
398
+ /** Mounts live funding quotes and their supporting inventory endpoints. */
522
399
  export function funding(options: funding.Options = {}) {
523
400
  return new Hono<App.Environment>()
524
401
  .get(
525
- '/v1/funding/routes',
402
+ '/v1/funding/quotes',
526
403
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
527
- OpenApi.validate('query', schema.listFundingRoutes.Query, {
404
+ OpenApi.validate('query', schema.quoteFunding.Query, {
528
405
  code: 'query_invalid',
529
406
  message: 'Invalid query parameters',
530
407
  }),
531
408
  OpenApi.describeRoute({
532
409
  description:
533
- 'Lists provider-specific route candidates for moving a source stablecoin amount into Tempo. This endpoint is discovery-only: it does not execute a bridge, reserve liquidity, or guarantee settlement. Static inventory candidates use `status: unknown`; provider adapters may add best-effort live quote fields.',
534
- operationId: 'listFundingRoutes',
410
+ 'Returns live quotes for funding Tempo with a stablecoin. Omit `provider` to query all configured providers. This endpoint does not execute a transfer.',
411
+ operationId: 'quoteFunding',
535
412
  responses: OpenApi.responses({
536
- errors: { 400: { codes: ['query_invalid'] } },
413
+ errors: {
414
+ 400: { codes: ['query_invalid'] },
415
+ 502: {
416
+ codes: ['upstream_error'],
417
+ description: 'Every matching quote provider failed unexpectedly.',
418
+ },
419
+ },
537
420
  success: {
538
- description:
539
- 'Discovery-only funding route candidates for the requested source chain and token.',
540
- examples: fundingRouteResponseExamples,
541
- schema: schema.listFundingRoutes.Response,
421
+ description: 'Live funding quotes. An empty list means no provider returned a quote.',
422
+ example: fundingQuoteResponseExample,
423
+ schema: schema.quoteFunding.Response,
542
424
  },
543
425
  }),
544
- summary: 'List funding routes',
426
+ summary: 'Get funding quotes',
545
427
  tags: ['Funding'],
546
428
  }),
547
- Cache.response<App.Environment>({
548
- cacheControl: Cache.policies.noStore,
549
- name: 'tempo-api:funding-routes:v1',
550
- key: (c) => Cache.urlKey(c, schema.listFundingRoutes.Query),
551
- }),
552
429
  async (c) => {
553
430
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
554
431
  if (OpenApi.narrowValidation)
@@ -559,16 +436,14 @@ export function funding(options: funding.Options = {}) {
559
436
 
560
437
  const query = c.req.valid('query')
561
438
  try {
562
- const include = FundingRoutes.parseInclude(query.include)
439
+ c.header('Cache-Control', 'no-store')
563
440
  return c.json(
564
- Response.validated(schema.listFundingRoutes.Response, {
565
- data: await FundingRoutes.listRoutes({
441
+ Response.validated(schema.quoteFunding.Response, {
442
+ data: await FundingQuotes.listQuotes({
566
443
  adapters: options.adapters,
567
444
  adapterTimeoutMs: options.adapterTimeoutMs,
568
445
  cache: { bypass: cacheBypass(c.req.raw) },
569
446
  destinationToken: query.destinationToken,
570
- include,
571
- limit: query.limit,
572
447
  provider: query.provider,
573
448
  sourceAmount: query.sourceAmount,
574
449
  sourceAmountUnits: query.sourceAmountUnits,
@@ -581,6 +456,12 @@ export function funding(options: funding.Options = {}) {
581
456
  } catch (cause) {
582
457
  const message = requestErrorMessage(cause)
583
458
  if (message) return Response.error(c, { code: 'query_invalid', message, status: 400 })
459
+ if (cause instanceof FundingQuotes.ProviderQuoteError)
460
+ return Response.error(c, {
461
+ code: 'upstream_error',
462
+ message: 'Quote providers could not complete the request.',
463
+ status: 502,
464
+ })
584
465
  throw cause
585
466
  }
586
467
  },
@@ -590,11 +471,11 @@ export function funding(options: funding.Options = {}) {
590
471
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
591
472
  OpenApi.describeRoute({
592
473
  description:
593
- 'Lists source chains and stablecoins understood by the funding route API, including provider-specific ids useful when comparing provider docs. This is static inventory metadata, not a live liquidity check.',
474
+ 'Lists the source chains and stablecoins you can use when requesting a funding quote.',
594
475
  operationId: 'listFundingChains',
595
476
  responses: OpenApi.responses({
596
477
  success: {
597
- description: 'Source-chain and stablecoin inventory for funding route discovery.',
478
+ description: 'Supported source chains and stablecoins.',
598
479
  example: fundingChainsResponseExample,
599
480
  schema: schema.listFundingChains.Response,
600
481
  },
@@ -611,54 +492,39 @@ export function funding(options: funding.Options = {}) {
611
492
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
612
493
  return c.json(
613
494
  Response.validated(schema.listFundingChains.Response, {
614
- data: FundingRoutes.listChains(),
495
+ data: FundingQuotes.listChains(),
615
496
  }),
616
497
  200,
617
498
  )
618
499
  },
619
500
  )
620
501
  .get(
621
- '/v1/providers',
502
+ '/v1/funding/providers',
622
503
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
623
- OpenApi.validate('query', schema.listProviders.Query, {
624
- code: 'query_invalid',
625
- message: 'Invalid query parameters',
626
- }),
627
504
  OpenApi.describeRoute({
628
505
  description:
629
- 'Lists provider metadata, capability flags, auth requirements, and integration status across provider domains. `inventoryOnly` providers can appear in static route candidates; `planned` providers are visible for roadmap transparency and may not return candidates.',
630
- operationId: 'listProviders',
506
+ 'Lists funding quote providers and whether live quoting is configured for this deployment.',
507
+ operationId: 'listFundingProviders',
631
508
  responses: OpenApi.responses({
632
- errors: { 400: { codes: ['query_invalid'] } },
633
509
  success: {
634
- description: 'Providers known to Tempo.',
510
+ description: 'Funding quote providers supported by Tempo.',
635
511
  example: providersResponseExample,
636
512
  schema: schema.listProviders.Response,
637
513
  },
638
514
  }),
639
- summary: 'List providers',
640
- tags: ['Providers'],
515
+ summary: 'List funding providers',
516
+ tags: ['Funding'],
641
517
  }),
642
518
  Cache.response<App.Environment>({
643
519
  cacheControl: Cache.policies.stable,
644
- name: 'tempo-api:providers:v1',
645
- key: (c) => Cache.urlKey(c, schema.listProviders.Query),
520
+ name: 'tempo-api:funding-providers:v1',
521
+ key: (c) => c.req.url,
646
522
  }),
647
523
  (c) => {
648
524
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
649
- if (OpenApi.narrowValidation)
650
- return OpenApi.validationError(c, {
651
- code: 'query_invalid',
652
- message: 'Invalid query parameters',
653
- })
654
-
655
- const query = c.req.valid('query')
656
525
  return c.json(
657
526
  Response.validated(schema.listProviders.Response, {
658
- data: FundingRoutes.listProviders({
659
- adapters: options.adapters,
660
- capability: query.capability,
661
- }),
527
+ data: FundingQuotes.listProviders({ adapters: options.adapters }),
662
528
  }),
663
529
  200,
664
530
  )
@@ -667,10 +533,10 @@ export function funding(options: funding.Options = {}) {
667
533
  }
668
534
 
669
535
  export declare namespace funding {
670
- /** Options for funding route discovery. */
536
+ /** Options for live funding quotes. */
671
537
  type Options = {
672
- /** Provider adapters used to enrich static inventory with live data. */
673
- adapters?: FundingRoutes.ProviderAdapters | undefined
538
+ /** Provider adapters used to request live quotes. */
539
+ adapters?: FundingQuotes.ProviderAdapters | undefined
674
540
  /** Per-provider quote timeout in milliseconds. */
675
541
  adapterTimeoutMs?: number | undefined
676
542
  }
@@ -678,12 +544,11 @@ export declare namespace funding {
678
544
 
679
545
  // Maps caller-input errors to a specific 400 message; anything else rethrows.
680
546
  function requestErrorMessage(cause: unknown) {
681
- if (cause instanceof FundingRoutes.InvalidAmountError) return 'Invalid `sourceAmount`.'
682
- if (cause instanceof FundingRoutes.UnsupportedIncludeError) return 'Unsupported `include`.'
683
- if (cause instanceof FundingRoutes.UnsupportedDestinationTokenError)
547
+ if (cause instanceof FundingQuotes.InvalidAmountError) return 'Invalid `sourceAmount`.'
548
+ if (cause instanceof FundingQuotes.UnsupportedDestinationTokenError)
684
549
  return 'Unsupported `destinationToken`.'
685
- if (cause instanceof FundingRoutes.UnsupportedProviderError) return 'Unsupported `provider`.'
686
- if (cause instanceof FundingRoutes.UnsupportedSourceChainError)
550
+ if (cause instanceof FundingQuotes.UnsupportedProviderError) return 'Unsupported `provider`.'
551
+ if (cause instanceof FundingQuotes.UnsupportedSourceChainError)
687
552
  return 'Unsupported `sourceChain`.'
688
553
  return undefined
689
554
  }