tapimo 0.4.4 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/dist/App.d.ts +4701 -3416
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +24 -2
  4. package/dist/App.js.map +1 -1
  5. package/dist/Assets.js +3 -3
  6. package/dist/Assets.js.map +1 -1
  7. package/dist/Scope.d.ts +18 -1
  8. package/dist/Scope.d.ts.map +1 -1
  9. package/dist/Scope.js +23 -3
  10. package/dist/Scope.js.map +1 -1
  11. package/dist/Webhooks.d.ts +1 -1
  12. package/dist/Webhooks.d.ts.map +1 -1
  13. package/dist/Webhooks.js +5 -10
  14. package/dist/Webhooks.js.map +1 -1
  15. package/dist/admin/App.d.ts +6 -34
  16. package/dist/admin/App.d.ts.map +1 -1
  17. package/dist/admin/apps/api-keys.d.ts +3 -3
  18. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  19. package/dist/admin/apps/api-keys.js +4 -1
  20. package/dist/admin/apps/api-keys.js.map +1 -1
  21. package/dist/admin/apps/scopes.d.ts +6 -34
  22. package/dist/admin/apps/scopes.d.ts.map +1 -1
  23. package/dist/admin/apps/scopes.js +2 -2
  24. package/dist/admin/apps/scopes.js.map +1 -1
  25. package/dist/admin/apps/verified-tokens.d.ts +57 -57
  26. package/dist/admin/ui.generated.d.ts +1 -1
  27. package/dist/admin/ui.generated.js +33 -33
  28. package/dist/admin/ui.generated.js.map +1 -1
  29. package/dist/apps/data/App.d.ts +4574 -4277
  30. package/dist/apps/data/App.d.ts.map +1 -1
  31. package/dist/apps/data/App.js +155 -77
  32. package/dist/apps/data/App.js.map +1 -1
  33. package/dist/apps/data/FundingQuoteProviders.d.ts +109 -0
  34. package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -0
  35. package/dist/apps/data/FundingQuoteProviders.js +464 -0
  36. package/dist/apps/data/FundingQuoteProviders.js.map +1 -0
  37. package/dist/apps/data/index.d.ts +1 -1
  38. package/dist/apps/data/index.js +1 -1
  39. package/dist/apps/data/routes/activities.d.ts +26 -26
  40. package/dist/apps/data/routes/addresses.d.ts +38 -38
  41. package/dist/apps/data/routes/balances.d.ts +45 -45
  42. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  43. package/dist/apps/data/routes/balances.js +67 -149
  44. package/dist/apps/data/routes/balances.js.map +1 -1
  45. package/dist/apps/data/routes/blocks.d.ts +2 -3
  46. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  47. package/dist/apps/data/routes/blocks.js +3 -5
  48. package/dist/apps/data/routes/blocks.js.map +1 -1
  49. package/dist/apps/data/routes/coingecko.d.ts +177 -176
  50. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  51. package/dist/apps/data/routes/coingecko.js +3 -8
  52. package/dist/apps/data/routes/coingecko.js.map +1 -1
  53. package/dist/apps/data/routes/funding.d.ts +131 -228
  54. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  55. package/dist/apps/data/routes/funding.js +152 -219
  56. package/dist/apps/data/routes/funding.js.map +1 -1
  57. package/dist/apps/data/routes/indexer.d.ts +34 -34
  58. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  59. package/dist/apps/data/routes/indexer.js +9 -2
  60. package/dist/apps/data/routes/indexer.js.map +1 -1
  61. package/dist/apps/data/routes/receipts.d.ts +228 -228
  62. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  63. package/dist/apps/data/routes/rpc.js +86 -16
  64. package/dist/apps/data/routes/rpc.js.map +1 -1
  65. package/dist/apps/data/routes/tokenlist.d.ts +12 -12
  66. package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
  67. package/dist/apps/data/routes/webhooks.d.ts +340 -0
  68. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  69. package/dist/apps/data/routes/webhooks.js +13 -1
  70. package/dist/apps/data/routes/webhooks.js.map +1 -1
  71. package/dist/apps/index.d.ts +1 -1
  72. package/dist/apps/index.js +1 -1
  73. package/dist/apps/management/App.d.ts +1833 -851
  74. package/dist/apps/management/App.d.ts.map +1 -1
  75. package/dist/apps/management/App.js +4 -0
  76. package/dist/apps/management/App.js.map +1 -1
  77. package/dist/apps/management/routes/api-keys.d.ts +41 -41
  78. package/dist/apps/management/routes/api-keys.js +2 -2
  79. package/dist/apps/management/routes/api-keys.js.map +1 -1
  80. package/dist/apps/management/routes/billing.d.ts +48 -48
  81. package/dist/apps/management/routes/invitations.d.ts +132 -132
  82. package/dist/apps/management/routes/invite-links.d.ts +1100 -0
  83. package/dist/apps/management/routes/invite-links.d.ts.map +1 -0
  84. package/dist/apps/management/routes/invite-links.js +411 -0
  85. package/dist/apps/management/routes/invite-links.js.map +1 -0
  86. package/dist/apps/management/routes/members.d.ts +41 -41
  87. package/dist/apps/management/routes/orgs.d.ts +92 -92
  88. package/dist/apps/management/routes/projects.d.ts +9 -9
  89. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  90. package/dist/apps/management/routes/scopes.js +2 -2
  91. package/dist/apps/management/routes/scopes.js.map +1 -1
  92. package/dist/apps/management/routes/usage.d.ts +24 -24
  93. package/dist/apps/mcp.js +2 -2
  94. package/dist/apps/mcp.js.map +1 -1
  95. package/dist/apps/relay/App.d.ts +2 -2
  96. package/dist/apps/relay/App.d.ts.map +1 -1
  97. package/dist/apps/relay/App.js +44 -6
  98. package/dist/apps/relay/App.js.map +1 -1
  99. package/dist/db/Db.d.ts +3 -0
  100. package/dist/db/Db.d.ts.map +1 -1
  101. package/dist/db/Db.js +57 -0
  102. package/dist/db/Db.js.map +1 -1
  103. package/dist/db/Schema.d.ts +31 -0
  104. package/dist/db/Schema.d.ts.map +1 -1
  105. package/dist/db/Schema.js +31 -0
  106. package/dist/db/Schema.js.map +1 -1
  107. package/dist/db/tables/inviteLinks.d.ts +42 -0
  108. package/dist/db/tables/inviteLinks.d.ts.map +1 -0
  109. package/dist/db/tables/inviteLinks.js +148 -0
  110. package/dist/db/tables/inviteLinks.js.map +1 -0
  111. package/dist/db/tables/organizations.d.ts.map +1 -1
  112. package/dist/db/tables/organizations.js +2 -0
  113. package/dist/db/tables/organizations.js.map +1 -1
  114. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  115. package/dist/db/tables/sponsoredTransactions.js +6 -2
  116. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  117. package/dist/handlers/relay.d.ts.map +1 -1
  118. package/dist/handlers/relay.js +13 -3
  119. package/dist/handlers/relay.js.map +1 -1
  120. package/dist/internal/Auth.d.ts +9 -1
  121. package/dist/internal/Auth.d.ts.map +1 -1
  122. package/dist/internal/Auth.js +138 -10
  123. package/dist/internal/Auth.js.map +1 -1
  124. package/dist/internal/EdgeCache.d.ts +3 -1
  125. package/dist/internal/EdgeCache.d.ts.map +1 -1
  126. package/dist/internal/EdgeCache.js +17 -2
  127. package/dist/internal/EdgeCache.js.map +1 -1
  128. package/dist/internal/{FundingRoutes.d.ts → FundingQuotes.d.ts} +240 -369
  129. package/dist/internal/FundingQuotes.d.ts.map +1 -0
  130. package/dist/internal/{FundingRoutes.js → FundingQuotes.js} +144 -183
  131. package/dist/internal/FundingQuotes.js.map +1 -0
  132. package/dist/internal/Log.d.ts +18 -12
  133. package/dist/internal/Log.d.ts.map +1 -1
  134. package/dist/internal/Log.js +2 -0
  135. package/dist/internal/Log.js.map +1 -1
  136. package/dist/internal/Tidx.d.ts +9 -3
  137. package/dist/internal/Tidx.d.ts.map +1 -1
  138. package/dist/internal/Tidx.js +13 -7
  139. package/dist/internal/Tidx.js.map +1 -1
  140. package/dist/internal/Viem.d.ts +17 -2
  141. package/dist/internal/Viem.d.ts.map +1 -1
  142. package/dist/internal/Viem.js +30 -3
  143. package/dist/internal/Viem.js.map +1 -1
  144. package/dist/internal/index.d.ts +1 -1
  145. package/dist/internal/index.js +1 -1
  146. package/package.json +2 -2
  147. package/src/ApiKeys.test.ts +25 -0
  148. package/src/App.test-d.ts +2 -0
  149. package/src/App.test.ts +13 -2
  150. package/src/App.ts +37 -5
  151. package/src/Assets.ts +3 -3
  152. package/src/Client.test-d.ts +21 -11
  153. package/src/Scope.test.ts +1 -0
  154. package/src/Scope.ts +32 -4
  155. package/src/Webhooks.ts +5 -10
  156. package/src/admin/apps/api-keys.test.ts +27 -0
  157. package/src/admin/apps/api-keys.ts +8 -1
  158. package/src/admin/apps/scopes.test.ts +7 -2
  159. package/src/admin/apps/scopes.ts +2 -2
  160. package/src/admin/ui/src/components/Dialog.tsx +8 -2
  161. package/src/admin/ui/src/lib/scopes.test.ts +19 -0
  162. package/src/admin/ui/src/lib/scopes.ts +12 -0
  163. package/src/admin/ui/src/routes/api-keys.tsx +128 -27
  164. package/src/admin/ui.generated.ts +33 -33
  165. package/src/apps/composition.test.ts +77 -0
  166. package/src/apps/data/App.test.ts +354 -0
  167. package/src/apps/data/App.ts +178 -91
  168. package/src/apps/data/FundingQuoteProviders.test.ts +577 -0
  169. package/src/apps/data/FundingQuoteProviders.ts +633 -0
  170. package/src/apps/data/index.ts +1 -1
  171. package/src/apps/data/routes/balances.test.ts +64 -18
  172. package/src/apps/data/routes/balances.ts +76 -177
  173. package/src/apps/data/routes/blocks.ts +3 -5
  174. package/src/apps/data/routes/coingecko.ts +3 -8
  175. package/src/apps/data/routes/funding.test.ts +304 -192
  176. package/src/apps/data/routes/funding.ts +166 -286
  177. package/src/apps/data/routes/indexer.test.ts +173 -15
  178. package/src/apps/data/routes/indexer.ts +8 -2
  179. package/src/apps/data/routes/rpc.test.ts +219 -0
  180. package/src/apps/data/routes/rpc.ts +92 -17
  181. package/src/apps/data/routes/webhooks.test.ts +21 -0
  182. package/src/apps/data/routes/webhooks.ts +13 -1
  183. package/src/apps/index.ts +1 -1
  184. package/src/apps/management/App.ts +4 -0
  185. package/src/apps/management/Billing.test.ts +2 -2
  186. package/src/apps/management/routes/api-keys.test.ts +47 -3
  187. package/src/apps/management/routes/api-keys.ts +2 -2
  188. package/src/apps/management/routes/invite-links.test.ts +385 -0
  189. package/src/apps/management/routes/invite-links.ts +570 -0
  190. package/src/apps/management/routes/scopes.test.ts +3 -2
  191. package/src/apps/management/routes/scopes.ts +4 -2
  192. package/src/apps/mcp.test.ts +18 -0
  193. package/src/apps/mcp.ts +2 -2
  194. package/src/apps/relay/App.test.ts +328 -7
  195. package/src/apps/relay/App.ts +42 -6
  196. package/src/apps/relay/Sponsorships.test.ts +2 -2
  197. package/src/db/Db.test.ts +5 -5
  198. package/src/db/Db.ts +65 -0
  199. package/src/db/Schema.ts +39 -0
  200. package/src/db/tables/billingSettings.test.ts +2 -2
  201. package/src/db/tables/inviteLinks.ts +187 -0
  202. package/src/db/tables/organizations.test.ts +2 -2
  203. package/src/db/tables/organizations.ts +2 -0
  204. package/src/db/tables/sponsoredTransactions.test.ts +19 -2
  205. package/src/db/tables/sponsoredTransactions.ts +21 -14
  206. package/src/db/tables/stripeCustomers.test.ts +2 -2
  207. package/src/handlers/relay.ts +16 -4
  208. package/src/internal/Auth.test.ts +132 -22
  209. package/src/internal/Auth.ts +181 -14
  210. package/src/internal/EdgeCache.test.ts +24 -3
  211. package/src/internal/EdgeCache.ts +18 -2
  212. package/src/internal/FundingQuotes.test.ts +268 -0
  213. package/src/internal/{FundingRoutes.ts → FundingQuotes.ts} +216 -277
  214. package/src/internal/Log.ts +21 -14
  215. package/src/internal/Tidx.test.ts +48 -0
  216. package/src/internal/Tidx.ts +21 -7
  217. package/src/internal/Viem.test.ts +46 -0
  218. package/src/internal/Viem.ts +48 -6
  219. package/src/internal/index.test.ts +1 -1
  220. package/src/internal/index.ts +1 -1
  221. package/dist/apps/data/FundingRouteProviders.d.ts +0 -36
  222. package/dist/apps/data/FundingRouteProviders.d.ts.map +0 -1
  223. package/dist/apps/data/FundingRouteProviders.js +0 -245
  224. package/dist/apps/data/FundingRouteProviders.js.map +0 -1
  225. package/dist/internal/FundingRoutes.d.ts.map +0 -1
  226. package/dist/internal/FundingRoutes.js.map +0 -1
  227. package/src/apps/data/FundingRouteProviders.test.ts +0 -225
  228. package/src/apps/data/FundingRouteProviders.ts +0 -312
  229. package/src/internal/FundingRoutes.test.ts +0 -213
@@ -4,18 +4,19 @@ 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
+ import * as FundingQuoteProviders from '../FundingQuoteProviders.js'
11
12
 
12
- /** Zod schemas owned by the funding routes resource. */
13
+ /** Zod schemas owned by funding quote resources. */
13
14
  export namespace schema {
14
15
  /** Source or destination chain reference. */
15
16
  export const Chain = Schema.describe(
16
17
  z.object({
17
18
  addressFormat: z
18
- .enum(['evm', 'solana', 'tron'])
19
+ .enum(['base58', 'base58check', 'evm'])
19
20
  .check(
20
21
  z.describe('Address family used by accounts and token identifiers on this chain.'),
21
22
  z.meta({ examples: ['evm'] }),
@@ -24,7 +25,7 @@ export namespace schema {
24
25
  .string()
25
26
  .check(
26
27
  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.',
28
+ 'Stable chain id. Uses CAIP-2 where standardized and a Tempo-defined compatible id otherwise.',
28
29
  ),
29
30
  z.meta({ examples: ['eip155:8453'] }),
30
31
  ),
@@ -40,11 +41,11 @@ export namespace schema {
40
41
  providerIds: z
41
42
  .optional(z.record(z.string(), z.string()))
42
43
  .check(
43
- z.describe('Provider-specific chain ids Tempo uses when querying route providers.'),
44
- z.meta({ examples: [{ bridge: 'base', relay: '8453' }] }),
44
+ z.describe('Provider-specific chain ids Tempo uses when requesting quotes.'),
45
+ z.meta({ examples: [{ across: '8453', relay: '8453', rhino: 'BASE' }] }),
45
46
  ),
46
47
  }),
47
- 'A normalized chain reference for funding routes.',
48
+ 'A normalized chain reference for funding quotes.',
48
49
  )
49
50
 
50
51
  /** Source or destination token reference. */
@@ -88,14 +89,14 @@ export namespace schema {
88
89
  verified: z
89
90
  .boolean()
90
91
  .check(
91
- z.describe('Whether Tempo recognizes this token in its funding route inventory.'),
92
+ z.describe('Whether Tempo recognizes this token in its funding quote inventory.'),
92
93
  z.meta({ examples: [true] }),
93
94
  ),
94
95
  }),
95
- 'A normalized token reference for funding routes.',
96
+ 'A normalized token reference for funding quotes.',
96
97
  )
97
98
 
98
- /** Source amount echoed by a funding route response. */
99
+ /** Source amount echoed by a funding quote response. */
99
100
  export const TokenAmount = Schema.describe(
100
101
  z.object({
101
102
  amount: Schema.DecimalString.check(
@@ -109,25 +110,21 @@ export namespace schema {
109
110
  ),
110
111
  z.meta({ examples: ['1'] }),
111
112
  ),
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
113
  }),
119
114
  'The requested source amount in provider-safe base units and display form.',
120
115
  )
121
116
 
122
- /** Provider summary embedded in a route candidate. */
117
+ /** Provider summary embedded in a funding quote. */
123
118
  export const ProviderRef = Schema.describe(
124
119
  z.object({
125
- id: z.string().check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
120
+ id: z
121
+ .enum(['across', 'relay', 'rhino'])
122
+ .check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
126
123
  kind: z
127
124
  .string()
128
125
  .check(
129
- z.describe('Provider category, such as an intent bridge, solver network, or aggregator.'),
130
- z.meta({ examples: ['intentBridge'] }),
126
+ z.describe('Provider category, such as a solver network or aggregator.'),
127
+ z.meta({ examples: ['solverNetwork'] }),
131
128
  ),
132
129
  name: z
133
130
  .string()
@@ -136,124 +133,71 @@ export namespace schema {
136
133
  .boolean()
137
134
  .check(
138
135
  z.describe('Whether Tempo needs provider credentials to query or use this provider.'),
139
- z.meta({ examples: [true] }),
136
+ z.meta({ examples: [false] }),
140
137
  ),
141
138
  }),
142
- 'Provider metadata embedded in a route candidate.',
139
+ 'Provider metadata embedded in a funding quote.',
143
140
  )
144
141
 
145
- /** Route quality signals exposed directly instead of implied by list order. */
142
+ /** Quote quality signals exposed directly instead of implied by list order. */
146
143
  export const Quality = Schema.describe(
147
144
  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
145
  estimatedSeconds: z
155
- .nullable(z.number().check(z.int(), z.nonnegative()))
146
+ .optional(z.number().check(z.int(), z.nonnegative()))
156
147
  .check(
157
148
  z.describe('Estimated settlement time in seconds, when known.'),
158
149
  z.meta({ examples: [2] }),
159
150
  ),
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
151
  liquiditySource: z
179
152
  .string()
180
153
  .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] }),
154
+ z.describe('Provider source for the live quote quality signal.'),
155
+ z.meta({ examples: ['providerQuote'] }),
189
156
  ),
190
157
  sourceDetail: z
191
- .nullable(z.string())
158
+ .optional(z.string())
192
159
  .check(
193
160
  z.describe('Provider-specific source or endpoint detail for the quality signal.'),
194
161
  z.meta({ examples: ['providerEndpoint'] }),
195
162
  ),
196
163
  tier: z
197
- .enum(['liquid', 'thin', 'unknown', 'unavailable', 'error'])
164
+ .enum(['liquid', 'thin'])
198
165
  .check(
199
- z.describe('Machine-readable route quality tier.'),
200
- z.meta({ examples: ['unknown'] }),
166
+ z.describe('Machine-readable quality tier for a successful quote.'),
167
+ z.meta({ examples: ['liquid'] }),
201
168
  ),
202
169
  }),
203
- 'Machine-readable liquidity, fee, and source signals for a route candidate.',
170
+ 'Machine-readable liquidity, fee, and source signals for a successful quote.',
204
171
  )
205
172
 
206
- /** Provider-derived quote data for a route candidate. */
207
- export const RouteQuote = Schema.describe(
173
+ /** Provider-derived output, limits, and freshness data. */
174
+ export const QuoteDetails = Schema.describe(
208
175
  z.object({
209
176
  expiresAt: z
210
- .nullable(z.iso.datetime())
177
+ .optional(z.iso.datetime())
211
178
  .check(
212
- z.describe('Provider quote expiry timestamp.'),
213
- z.meta({ examples: ['2026-01-01T00:00:30Z'] }),
179
+ z.describe('Timestamp after which the provider quote is no longer valid.'),
180
+ z.meta({ examples: ['2026-01-01T00:01:00Z'] }),
214
181
  ),
215
182
  inputAmount: Schema.DecimalString.check(
216
183
  z.describe('Source amount sent to the provider in base units.'),
217
184
  z.meta({ examples: ['1000000'] }),
218
185
  ),
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
186
  minimumOutputAmount: z
244
- .nullable(Schema.DecimalString)
187
+ .optional(Schema.DecimalString)
245
188
  .check(
246
189
  z.describe('Slippage-adjusted minimum destination amount in base units.'),
247
190
  z.meta({ examples: ['988000'] }),
248
191
  ),
249
192
  outputAmount: z
250
- .nullable(Schema.DecimalString)
193
+ .string()
194
+ .check(z.regex(/^\d+$/))
251
195
  .check(
252
196
  z.describe('Expected destination amount in base units.'),
253
197
  z.meta({ examples: ['989102'] }),
254
198
  ),
255
199
  outputAmountFormatted: z
256
- .nullable(z.string())
200
+ .string()
257
201
  .check(
258
202
  z.describe('Expected destination amount rendered with destination token decimals.'),
259
203
  z.meta({ examples: ['0.989102'] }),
@@ -261,58 +205,40 @@ export namespace schema {
261
205
  sampledAt: z.iso
262
206
  .datetime()
263
207
  .check(
264
- z.describe('Timestamp for the live quote or route probe.'),
208
+ z.describe('Timestamp for the live quote probe.'),
265
209
  z.meta({ examples: ['2026-01-01T00:00:00Z'] }),
266
210
  ),
267
211
  }),
268
- 'Provider-derived quote, limit, and freshness data for a route candidate.',
212
+ 'Provider-derived output, limits, and freshness data for a funding quote.',
269
213
  )
270
214
 
271
- /** Static or live funding route candidate. */
272
- export const RouteCandidate = Schema.describe(
215
+ /** Successful live funding quote. */
216
+ export const FundingQuote = Schema.describe(
273
217
  z.object({
274
218
  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
- ),
219
+ destinationToken: Token.check(z.describe('Tempo token expected from this quote.')),
282
220
  id: z
283
221
  .string()
284
222
  .check(
285
- z.describe('Stable deterministic route candidate id.'),
223
+ z.describe('Stable deterministic funding quote id.'),
286
224
  z.meta({ examples: ['base-usdc-tempo-usdce-relay'] }),
287
225
  ),
288
226
  provider: ProviderRef,
289
227
  quality: Quality,
290
- quote: z
291
- .nullable(RouteQuote)
292
- .check(z.describe('Provider-derived quote data, when a live route probe succeeds.')),
228
+ quote: QuoteDetails,
293
229
  sourceAmount: TokenAmount,
294
230
  sourceChain: Chain.check(z.describe('Chain where the caller currently holds funds.')),
295
231
  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
232
  }),
303
- 'One provider-specific funding route candidate.',
233
+ 'One successful provider-specific funding quote.',
304
234
  )
305
235
 
306
- /** Generic provider catalog entry. */
236
+ /** Funding quote provider catalog entry. */
307
237
  export const Provider = Schema.describe(
308
238
  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'] })),
239
+ id: z
240
+ .enum(['across', 'relay', 'rhino'])
241
+ .check(z.describe('Stable provider id.'), z.meta({ examples: ['relay'] })),
316
242
  kind: z
317
243
  .string()
318
244
  .check(z.describe('Provider category.'), z.meta({ examples: ['solverNetwork'] })),
@@ -326,15 +252,15 @@ export namespace schema {
326
252
  z.meta({ examples: [false] }),
327
253
  ),
328
254
  status: z
329
- .enum(['configured', 'inventoryOnly', 'planned'])
255
+ .enum(['configured', 'unconfigured'])
330
256
  .check(
331
257
  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.',
258
+ '`configured` means live quotes are enabled for this deployment. `unconfigured` means the provider is supported but unavailable here.',
333
259
  ),
334
- z.meta({ examples: ['inventoryOnly'] }),
260
+ z.meta({ examples: ['configured', 'unconfigured'] }),
335
261
  ),
336
262
  }),
337
- 'One provider in the generic provider catalog.',
263
+ 'One funding quote provider.',
338
264
  )
339
265
 
340
266
  /** Chain inventory entry returned by the funding chains endpoint. */
@@ -345,9 +271,9 @@ export namespace schema {
345
271
  'One source chain and its known stablecoin inventory.',
346
272
  )
347
273
 
348
- /** Schemas for the listFundingRoutes operation. */
349
- export namespace listFundingRoutes {
350
- /** Query parameters for funding route discovery. */
274
+ /** Schemas for the quoteFunding operation. */
275
+ export namespace quoteFunding {
276
+ /** Query parameters for live funding quotes. */
351
277
  export const Query = z
352
278
  .strictObject({
353
279
  destinationToken: z
@@ -358,26 +284,21 @@ export namespace schema {
358
284
  ),
359
285
  z.meta({ examples: ['USDC.e'] }),
360
286
  ),
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
287
  provider: z
369
- .optional(z.string())
288
+ .optional(z.enum(['across', 'relay', 'rhino']))
370
289
  .check(
371
290
  z.describe(
372
- 'Only return candidates from this provider id, such as `relay`, `bridge`, or `bungee`. Planned providers can return an empty list.',
291
+ 'Only request a quote from this provider. Supported ids are `across`, `relay`, and `rhino`; omit it to query every configured provider.',
373
292
  ),
374
- z.meta({ examples: ['relay', 'bridge'] }),
293
+ z.meta({ examples: ['relay'] }),
375
294
  ),
376
295
  sourceAmount: z
377
296
  .string()
378
297
  .check(
379
- z.minLength(1),
380
- z.describe('Source token amount. Base units by default, so 1 USDC is `1000000`.'),
298
+ z.regex(/^(?=.*[1-9])\d+(\.\d+)?$/),
299
+ z.describe(
300
+ 'Positive source token amount. Base units by default, so 1 USDC is `1000000`.',
301
+ ),
381
302
  z.meta({ examples: ['1000000'] }),
382
303
  ),
383
304
  sourceAmountUnits: z
@@ -391,34 +312,28 @@ export namespace schema {
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 chain alias or stable id, such as `base`, `solana`, or `eip155:8453`.',
395
316
  ),
396
- z.meta({ examples: ['base', 'solana', 'tron'] }),
317
+ z.meta({ examples: ['base', 'eip155:8453'] }),
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.',
319
+ sourceToken: z
320
+ .string()
321
+ .check(
322
+ z.minLength(1),
323
+ z.describe(
324
+ 'Source token symbol, contract address, or Tempo token key. Lookup is scoped to `sourceChain`; non-EVM addresses are case-sensitive. An unknown token returns an empty list.',
325
+ ),
326
+ z.meta({ examples: ['USDC', '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'] }),
402
327
  ),
403
- z.meta({
404
- examples: [
405
- 'USDC',
406
- 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
407
- 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',
408
- ],
409
- }),
410
- ),
411
328
  })
412
- .check(z.describe('Query parameters for discovering funding routes into Tempo.'))
329
+ .check(z.describe('Query parameters for live funding quotes into Tempo.'))
413
330
 
414
- /** Non-paginated list of funding route candidates. */
331
+ /** Non-paginated list of successful funding quotes. */
415
332
  export const Response = Schema.describe(
416
333
  z.object({
417
- data: z
418
- .array(RouteCandidate)
419
- .check(z.describe('Funding route candidates matching the request.')),
334
+ data: z.array(FundingQuote).check(z.describe('Successful live funding quotes.')),
420
335
  }),
421
- 'A non-paginated list of funding route candidates.',
336
+ 'A non-paginated list of successful live funding quotes.',
422
337
  )
423
338
  }
424
339
 
@@ -429,7 +344,7 @@ export namespace schema {
429
344
  z.object({
430
345
  data: z
431
346
  .array(ChainInventory)
432
- .check(z.describe('Source chains and stablecoins known to the funding route API.')),
347
+ .check(z.describe('Source chains and stablecoins supported by funding quotes.')),
433
348
  }),
434
349
  'A non-paginated list of source chains and stablecoin inventory.',
435
350
  )
@@ -437,118 +352,90 @@ export namespace schema {
437
352
 
438
353
  /** Schemas for the listProviders operation. */
439
354
  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. */
355
+ /** Non-paginated funding quote provider catalog. */
453
356
  export const Response = Schema.describe(
454
357
  z.object({
455
- data: z.array(Provider).check(z.describe("Providers in Tempo's generic provider catalog.")),
358
+ data: z.array(Provider).check(z.describe("Providers in Tempo's funding quote catalog.")),
456
359
  }),
457
- 'A non-paginated list of providers.',
360
+ 'A non-paginated list of funding quote providers.',
458
361
  )
459
362
  }
460
363
  }
461
364
 
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']
365
+ const fundingQuoteResponseExample = (() => {
366
+ const [candidate] = FundingQuotes.listQuoteCandidates({
367
+ provider: 'relay',
368
+ sourceAmount: '1000000',
369
+ sourceAmountUnits: 'baseUnits',
370
+ sourceChain: 'base',
371
+ sourceToken: 'USDC',
372
+ })
373
+ if (!candidate) throw new Error('Missing Relay funding quote example candidate')
374
+ return {
375
+ data: [
376
+ {
377
+ ...candidate,
378
+ quality: {
379
+ estimatedSeconds: 1,
380
+ liquiditySource: 'providerQuote',
381
+ sourceDetail: 'relay:quote-v2',
382
+ tier: 'liquid',
383
+ },
384
+ quote: {
385
+ inputAmount: '1000000',
386
+ minimumOutputAmount: '939242',
387
+ outputAmount: '979295',
388
+ outputAmountFormatted: '0.979295',
389
+ sampledAt: '2026-01-01T00:00:00.000Z',
390
+ },
391
+ },
392
+ ],
393
+ }
394
+ })() satisfies z.output<typeof schema.quoteFunding.Response>
512
395
 
513
396
  const fundingChainsResponseExample = {
514
- data: FundingRoutes.listChains(),
397
+ data: FundingQuotes.listChains(),
515
398
  } satisfies z.output<typeof schema.listFundingChains.Response>
516
399
 
517
400
  const providersResponseExample = {
518
- data: FundingRoutes.listProviders(),
401
+ data: FundingQuotes.listProviders().map((provider) => ({
402
+ ...provider,
403
+ status: 'configured' as const,
404
+ })),
519
405
  } satisfies z.output<typeof schema.listProviders.Response>
520
406
 
521
- /** Mounts funding route discovery and generic provider inventory endpoints. */
407
+ /** Mounts live funding quotes and their supporting inventory endpoints. */
522
408
  export function funding(options: funding.Options = {}) {
523
409
  return new Hono<App.Environment>()
524
410
  .get(
525
- '/v1/funding/routes',
411
+ '/v1/funding/quotes',
526
412
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
527
- OpenApi.validate('query', schema.listFundingRoutes.Query, {
413
+ OpenApi.validate('query', schema.quoteFunding.Query, {
528
414
  code: 'query_invalid',
529
415
  message: 'Invalid query parameters',
530
416
  }),
531
417
  OpenApi.describeRoute({
532
418
  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',
419
+ 'Returns live quotes for funding Tempo with a stablecoin. Omit `provider` to query all configured providers. This endpoint does not execute a transfer.',
420
+ operationId: 'quoteFunding',
535
421
  responses: OpenApi.responses({
536
- errors: { 400: { codes: ['query_invalid'] } },
422
+ errors: {
423
+ 400: { codes: ['query_invalid'] },
424
+ 502: {
425
+ codes: ['upstream_error'],
426
+ description:
427
+ 'No quote succeeded and at least one matching provider failed unexpectedly.',
428
+ },
429
+ },
537
430
  success: {
538
- description:
539
- 'Discovery-only funding route candidates for the requested source chain and token.',
540
- examples: fundingRouteResponseExamples,
541
- schema: schema.listFundingRoutes.Response,
431
+ description: 'Live funding quotes. An empty list means no provider returned a quote.',
432
+ example: fundingQuoteResponseExample,
433
+ schema: schema.quoteFunding.Response,
542
434
  },
543
435
  }),
544
- summary: 'List funding routes',
436
+ summary: 'Get funding quotes',
545
437
  tags: ['Funding'],
546
438
  }),
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
439
  async (c) => {
553
440
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
554
441
  if (OpenApi.narrowValidation)
@@ -559,16 +446,14 @@ export function funding(options: funding.Options = {}) {
559
446
 
560
447
  const query = c.req.valid('query')
561
448
  try {
562
- const include = FundingRoutes.parseInclude(query.include)
449
+ c.header('Cache-Control', 'no-store')
563
450
  return c.json(
564
- Response.validated(schema.listFundingRoutes.Response, {
565
- data: await FundingRoutes.listRoutes({
451
+ Response.validated(schema.quoteFunding.Response, {
452
+ data: await FundingQuotes.listQuotes({
566
453
  adapters: options.adapters,
567
454
  adapterTimeoutMs: options.adapterTimeoutMs,
568
455
  cache: { bypass: cacheBypass(c.req.raw) },
569
456
  destinationToken: query.destinationToken,
570
- include,
571
- limit: query.limit,
572
457
  provider: query.provider,
573
458
  sourceAmount: query.sourceAmount,
574
459
  sourceAmountUnits: query.sourceAmountUnits,
@@ -581,6 +466,17 @@ export function funding(options: funding.Options = {}) {
581
466
  } catch (cause) {
582
467
  const message = requestErrorMessage(cause)
583
468
  if (message) return Response.error(c, { code: 'query_invalid', message, status: 400 })
469
+ if (cause instanceof FundingQuotes.ProviderQuoteError) {
470
+ const failures = cause.failures.map(FundingQuoteProviders.providerFailure)
471
+ const failure = failures[0]
472
+ if (failure) c.set('providerFailure', failure)
473
+ if (failures.length > 1) c.set('providerFailures', failures)
474
+ return Response.error(c, {
475
+ code: 'upstream_error',
476
+ message: 'Quote providers could not complete the request.',
477
+ status: 502,
478
+ })
479
+ }
584
480
  throw cause
585
481
  }
586
482
  },
@@ -590,11 +486,11 @@ export function funding(options: funding.Options = {}) {
590
486
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
591
487
  OpenApi.describeRoute({
592
488
  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.',
489
+ 'Lists the source chains and stablecoins you can use when requesting a funding quote.',
594
490
  operationId: 'listFundingChains',
595
491
  responses: OpenApi.responses({
596
492
  success: {
597
- description: 'Source-chain and stablecoin inventory for funding route discovery.',
493
+ description: 'Supported source chains and stablecoins.',
598
494
  example: fundingChainsResponseExample,
599
495
  schema: schema.listFundingChains.Response,
600
496
  },
@@ -611,54 +507,39 @@ export function funding(options: funding.Options = {}) {
611
507
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
612
508
  return c.json(
613
509
  Response.validated(schema.listFundingChains.Response, {
614
- data: FundingRoutes.listChains(),
510
+ data: FundingQuotes.listChains(),
615
511
  }),
616
512
  200,
617
513
  )
618
514
  },
619
515
  )
620
516
  .get(
621
- '/v1/providers',
517
+ '/v1/funding/providers',
622
518
  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
519
  OpenApi.describeRoute({
628
520
  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',
521
+ 'Lists funding quote providers and whether live quoting is configured for this deployment.',
522
+ operationId: 'listFundingProviders',
631
523
  responses: OpenApi.responses({
632
- errors: { 400: { codes: ['query_invalid'] } },
633
524
  success: {
634
- description: 'Providers known to Tempo.',
525
+ description: 'Funding quote providers supported by Tempo.',
635
526
  example: providersResponseExample,
636
527
  schema: schema.listProviders.Response,
637
528
  },
638
529
  }),
639
- summary: 'List providers',
640
- tags: ['Providers'],
530
+ summary: 'List funding providers',
531
+ tags: ['Funding'],
641
532
  }),
642
533
  Cache.response<App.Environment>({
643
534
  cacheControl: Cache.policies.stable,
644
- name: 'tempo-api:providers:v1',
645
- key: (c) => Cache.urlKey(c, schema.listProviders.Query),
535
+ name: 'tempo-api:funding-providers:v1',
536
+ key: (c) => c.req.url,
646
537
  }),
647
538
  (c) => {
648
539
  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
540
  return c.json(
657
541
  Response.validated(schema.listProviders.Response, {
658
- data: FundingRoutes.listProviders({
659
- adapters: options.adapters,
660
- capability: query.capability,
661
- }),
542
+ data: FundingQuotes.listProviders({ adapters: options.adapters }),
662
543
  }),
663
544
  200,
664
545
  )
@@ -667,10 +548,10 @@ export function funding(options: funding.Options = {}) {
667
548
  }
668
549
 
669
550
  export declare namespace funding {
670
- /** Options for funding route discovery. */
551
+ /** Options for live funding quotes. */
671
552
  type Options = {
672
- /** Provider adapters used to enrich static inventory with live data. */
673
- adapters?: FundingRoutes.ProviderAdapters | undefined
553
+ /** Provider adapters used to request live quotes. */
554
+ adapters?: FundingQuotes.ProviderAdapters | undefined
674
555
  /** Per-provider quote timeout in milliseconds. */
675
556
  adapterTimeoutMs?: number | undefined
676
557
  }
@@ -678,12 +559,11 @@ export declare namespace funding {
678
559
 
679
560
  // Maps caller-input errors to a specific 400 message; anything else rethrows.
680
561
  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)
562
+ if (cause instanceof FundingQuotes.InvalidAmountError) return 'Invalid `sourceAmount`.'
563
+ if (cause instanceof FundingQuotes.UnsupportedDestinationTokenError)
684
564
  return 'Unsupported `destinationToken`.'
685
- if (cause instanceof FundingRoutes.UnsupportedProviderError) return 'Unsupported `provider`.'
686
- if (cause instanceof FundingRoutes.UnsupportedSourceChainError)
565
+ if (cause instanceof FundingQuotes.UnsupportedProviderError) return 'Unsupported `provider`.'
566
+ if (cause instanceof FundingQuotes.UnsupportedSourceChainError)
687
567
  return 'Unsupported `sourceChain`.'
688
568
  return undefined
689
569
  }