tapimo 0.4.3 → 0.4.4

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 (77) hide show
  1. package/dist/App.d.ts +2491 -2861
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/admin/apps/verified-tokens.d.ts +57 -57
  4. package/dist/apps/data/App.d.ts +2354 -2724
  5. package/dist/apps/data/App.d.ts.map +1 -1
  6. package/dist/apps/data/FundingRouteProviders.d.ts +3 -110
  7. package/dist/apps/data/FundingRouteProviders.d.ts.map +1 -1
  8. package/dist/apps/data/FundingRouteProviders.js +1 -302
  9. package/dist/apps/data/FundingRouteProviders.js.map +1 -1
  10. package/dist/apps/data/routes/exchanges.d.ts +455 -455
  11. package/dist/apps/data/routes/fee-amm.d.ts +92 -92
  12. package/dist/apps/data/routes/funding.d.ts +138 -730
  13. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  14. package/dist/apps/data/routes/funding.js +7 -241
  15. package/dist/apps/data/routes/funding.js.map +1 -1
  16. package/dist/apps/data/routes/tokenlist.d.ts +12 -12
  17. package/dist/apps/data/routes/transactions.d.ts +281 -281
  18. package/dist/apps/data/routes/transfers.d.ts +58 -58
  19. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  20. package/dist/apps/management/App.d.ts +855 -855
  21. package/dist/apps/management/routes/api-keys.d.ts +40 -40
  22. package/dist/apps/management/routes/billing.d.ts +207 -207
  23. package/dist/apps/management/routes/me.d.ts +6 -6
  24. package/dist/apps/management/routes/members.d.ts +30 -30
  25. package/dist/apps/management/routes/orgs.d.ts +92 -92
  26. package/dist/apps/management/routes/projects.d.ts +28 -28
  27. package/dist/apps/management/routes/usage.d.ts +24 -24
  28. package/dist/apps/mcp.d.ts.map +1 -1
  29. package/dist/apps/mcp.js +3 -1
  30. package/dist/apps/mcp.js.map +1 -1
  31. package/dist/cloudflare.d.ts +2 -0
  32. package/dist/cloudflare.d.ts.map +1 -1
  33. package/dist/cloudflare.js +4 -0
  34. package/dist/cloudflare.js.map +1 -1
  35. package/dist/internal/Auth.d.ts +33 -22
  36. package/dist/internal/Auth.d.ts.map +1 -1
  37. package/dist/internal/Auth.js +40 -11
  38. package/dist/internal/Auth.js.map +1 -1
  39. package/dist/internal/Errors.d.ts +6 -0
  40. package/dist/internal/Errors.d.ts.map +1 -0
  41. package/dist/internal/Errors.js +16 -0
  42. package/dist/internal/Errors.js.map +1 -0
  43. package/dist/internal/FundingRoutes.d.ts +15 -213
  44. package/dist/internal/FundingRoutes.d.ts.map +1 -1
  45. package/dist/internal/FundingRoutes.js +1 -72
  46. package/dist/internal/FundingRoutes.js.map +1 -1
  47. package/dist/internal/Store.d.ts +61 -16
  48. package/dist/internal/Store.d.ts.map +1 -1
  49. package/dist/internal/Store.js +72 -17
  50. package/dist/internal/Store.js.map +1 -1
  51. package/dist/internal/Viem.d.ts +1 -1
  52. package/dist/internal/index.d.ts +27 -0
  53. package/dist/internal/index.d.ts.map +1 -0
  54. package/dist/internal/index.js +27 -0
  55. package/dist/internal/index.js.map +1 -0
  56. package/package.json +8 -3
  57. package/src/App.test.ts +60 -4
  58. package/src/Client.test-d.ts +0 -47
  59. package/src/apps/data/FundingRouteProviders.test.ts +37 -297
  60. package/src/apps/data/FundingRouteProviders.ts +3 -435
  61. package/src/apps/data/routes/funding.test.ts +7 -109
  62. package/src/apps/data/routes/funding.ts +8 -323
  63. package/src/apps/data/routes/indexer.test.ts +2 -2
  64. package/src/apps/data/routes/webhooks.test.ts +2 -2
  65. package/src/apps/mcp.test.ts +55 -14
  66. package/src/apps/mcp.ts +3 -1
  67. package/src/cloudflare.ts +5 -0
  68. package/src/internal/Auth.test.ts +397 -16
  69. package/src/internal/Auth.ts +76 -32
  70. package/src/internal/FundingRoutes.test.ts +8 -34
  71. package/src/internal/FundingRoutes.ts +1 -174
  72. package/src/internal/Log.test.ts +4 -4
  73. package/src/internal/Store.test-d.ts +15 -0
  74. package/src/internal/Store.test.ts +153 -2
  75. package/src/internal/Store.ts +157 -41
  76. package/src/internal/index.test.ts +34 -0
  77. package/src/internal/index.ts +26 -0
@@ -9,6 +9,7 @@ import { findTargetHandler } from 'hono/utils/handler'
9
9
  import { decodeJwt } from 'jose'
10
10
  import { Credential, type Method } from 'mppx'
11
11
  import { Mppx, tempo } from 'mppx/hono'
12
+ import { Addresses } from 'viem/tempo'
12
13
  import * as z from 'zod/mini'
13
14
 
14
15
  import type * as App from '../App.js'
@@ -30,6 +31,7 @@ import * as Users from '../db/tables/users.js'
30
31
  import * as Viem from './Viem.js'
31
32
 
32
33
  const policySymbol = Symbol('tempo-api.auth.policy')
34
+ const defaultMppRateLimit = { perMinute: 100 } satisfies RateLimit.Limit
33
35
 
34
36
  /** Auth context consumed by Tempo API handlers. */
35
37
  export type Context = {
@@ -47,7 +49,7 @@ export type Context = {
47
49
  }
48
50
  | undefined
49
51
  /** MPP payment configuration. */
50
- mpp?: Mpp | undefined
52
+ mpp?: MppHandler | undefined
51
53
  /**
52
54
  * Configured default anonymous public quota. Used as the throttle ceiling for
53
55
  * sandbox keys without active billing on routes that expose no public lane
@@ -89,22 +91,27 @@ export type Payment = {
89
91
  type: 'mpp'
90
92
  }
91
93
 
92
- /** MPP charge options used by route access policies. */
93
- export type Charge = Method.RequestDefaults<ReturnType<typeof tempo.charge>> & {
94
- /** Optional human-readable payment description. */
95
- description?: string | undefined
96
- /** Optional challenge expiration timestamp or date. */
97
- expires?: Date | string | undefined
98
- /** Optional server-defined correlation data. */
99
- meta?: Record<string, string> | undefined
100
- /** Optional route/resource scope bound to the challenge. */
101
- scope?: string | undefined
94
+ /** MPP route-policy types. Distinct from the SIWE {@link Session} capability. */
95
+ export declare namespace Mpp {
96
+ /** MPP Session request options used by route access policies. */
97
+ type Session = Method.RequestDefaults<ReturnType<typeof tempo.session>> & {
98
+ /** Optional human-readable payment description. */
99
+ description?: string | undefined
100
+ /** Optional challenge expiration timestamp or date. */
101
+ expires?: Date | string | undefined
102
+ /** Optional server-defined correlation data. */
103
+ meta?: Record<string, string> | undefined
104
+ /** Optional route/resource scope bound to the challenge. */
105
+ scope?: string | undefined
106
+ }
102
107
  }
103
108
 
104
109
  /** MPP payment handler consumed by auth policies. */
105
- type Mpp = {
106
- /** Creates a Hono middleware for a Tempo charge. */
107
- charge(options: Charge): MiddlewareHandler
110
+ type MppHandler = {
111
+ /** Paid-request quota per access principal. */
112
+ rateLimit?: RateLimit.Limit | undefined
113
+ /** Creates a Hono middleware for a Tempo Session payment. */
114
+ session(options: Mpp.Session): MiddlewareHandler
108
115
  }
109
116
 
110
117
  /**
@@ -127,11 +134,13 @@ export type PolicyOverride = {
127
134
  }
128
135
  | boolean
129
136
  | undefined
130
- /** MPP paid lane: object to override the charge, or boolean to enable/disable. */
137
+ /** MPP paid lane: object to override the Session request, or boolean to enable/disable. */
131
138
  mpp?:
132
139
  | {
133
- /** Tempo charge override for this route. */
134
- charge?: Charge | undefined
140
+ /** Paid-request quota override for this route (a protective per-route cap). */
141
+ rateLimit?: RateLimit.Limit | undefined
142
+ /** Tempo Session request override for this route. */
143
+ session?: Mpp.Session | undefined
135
144
  }
136
145
  | boolean
137
146
  | undefined
@@ -465,7 +474,11 @@ export function middleware<
465
474
  endpoint extends string = string,
466
475
  environment extends Environment = Environment,
467
476
  >(options: middleware.Options<endpoint>): MiddlewareHandler<environment> {
468
- const { charge = {}, ...mpp } = options.mpp === false ? {} : (options.mpp ?? {})
477
+ const {
478
+ rateLimit: mppRateLimit = defaultMppRateLimit,
479
+ session: session_ = {},
480
+ ...mpp
481
+ } = options.mpp === false ? {} : (options.mpp ?? {})
469
482
  const defaults = laneDefaults(options)
470
483
  // Default-deny: no lanes open until a route grants them via `policy`.
471
484
  // Otherwise the `super_admin` principal bypasses lane checks entirely.
@@ -503,11 +516,23 @@ export function middleware<
503
516
  ...(options.mpp === false
504
517
  ? {}
505
518
  : {
506
- mpp: Mppx.create({
507
- ...mpp,
508
- methods: [tempo.charge({ amount: '0.001', ...charge })],
509
- secretKey: mpp.secretKey ?? crypto.randomUUID(),
510
- }),
519
+ mpp: {
520
+ rateLimit: mppRateLimit,
521
+ session: Mppx.create({
522
+ ...mpp,
523
+ // Defaults only; global `session` options may override, including
524
+ // enabling same-route HEAD bootstrap.
525
+ methods: [
526
+ tempo.session({
527
+ amount: '0.0001',
528
+ bootstrap: false,
529
+ currency: Addresses.pathUsd,
530
+ unitType: 'request',
531
+ ...session_,
532
+ }),
533
+ ],
534
+ }).session,
535
+ },
511
536
  }),
512
537
  rateLimit: RateLimit.memory(options.rateLimit),
513
538
  ...(options.session ? { session: options.session } : {}),
@@ -600,8 +625,10 @@ export declare namespace middleware {
600
625
 
601
626
  /** MPP payment options used by auth middleware. */
602
627
  type MppOptions = Omit<NonNullable<Parameters<typeof Mppx.create>[0]>, 'methods'> & {
603
- /** Global Tempo charge options passed to the MPP method instantiator. */
604
- charge?: NonNullable<Parameters<typeof tempo.charge>[0]> | undefined
628
+ /** Paid-request quota per access principal. Defaults to 100 per minute. */
629
+ rateLimit?: RateLimit.Limit | undefined
630
+ /** Global Tempo Session options passed to the MPP method instantiator. */
631
+ session?: NonNullable<Parameters<typeof tempo.session>[0]> | undefined
605
632
  }
606
633
  }
607
634
 
@@ -1043,7 +1070,7 @@ function laneDefaults(options: middleware.Options): LaneDefaults {
1043
1070
  // catalog scopes via `Auth.policy`.
1044
1071
  scopes: apiKey?.scopes ?? [Scope.wildcard],
1045
1072
  },
1046
- mpp: { charge: {} },
1073
+ mpp: { session: {} },
1047
1074
  public: { rateLimit: public_?.rateLimit ?? { perMinute: 60 } },
1048
1075
  session: true,
1049
1076
  }
@@ -1072,8 +1099,8 @@ function resolvePolicy(
1072
1099
  // The OpenAPI summary/description rides along as the payment-challenge
1073
1100
  // description. It is metadata, not a policy override, so it only applies when
1074
1101
  // the paid lane is actually enabled and has no explicit description already.
1075
- if (mpp && description !== undefined && mpp.charge.description === undefined)
1076
- mpp = { charge: { ...mpp.charge, description } }
1102
+ if (mpp && description !== undefined && mpp.session.description === undefined)
1103
+ mpp = { ...mpp, session: { ...mpp.session, description } }
1077
1104
 
1078
1105
  // A lane-less policy stays enforced for super admin; only an explicit
1079
1106
  // `false` override opts a route out of auth entirely.
@@ -1109,7 +1136,10 @@ function resolveMppLane(
1109
1136
  if (override === false) return undefined
1110
1137
  if (override === true) return current ?? default_
1111
1138
  const base = current ?? default_
1112
- return { charge: { ...base.charge, ...override.charge } }
1139
+ return {
1140
+ rateLimit: override.rateLimit ?? base.rateLimit,
1141
+ session: { ...base.session, ...override.session },
1142
+ }
1113
1143
  }
1114
1144
 
1115
1145
  function resolvePublicLane(
@@ -1483,8 +1513,10 @@ export declare namespace require {
1483
1513
  /** MPP payment access policy. */
1484
1514
  mpp?:
1485
1515
  | {
1486
- /** Tempo charge policy. */
1487
- charge: Charge
1516
+ /** Paid-request quota override for this route (a protective per-route cap). */
1517
+ rateLimit?: RateLimit.Limit | undefined
1518
+ /** Tempo Session request policy. */
1519
+ session: Mpp.Session
1488
1520
  }
1489
1521
  | undefined
1490
1522
  /** Public access policy. */
@@ -1729,7 +1761,19 @@ async function requirePayment<environment extends Environment>(
1729
1761
  next: () => Promise<void>,
1730
1762
  options: PaymentAccess,
1731
1763
  ) {
1732
- const middleware = options.auth.mpp?.charge(options.policy.mpp?.charge ?? {})
1764
+ if (hasPaymentCredential(c)) {
1765
+ const result = await consumeRateLimit(options.auth, {
1766
+ key: `mpp:${options.principal.type}:${options.principal.id}`,
1767
+ limit: options.policy.mpp?.rateLimit ?? options.auth.mpp?.rateLimit ?? defaultMppRateLimit,
1768
+ })
1769
+ if (result) {
1770
+ setRateLimitHeaders(c, result)
1771
+ c.header('RateLimit-Scope', 'mpp')
1772
+ if (!result.allowed) return rateLimitExceeded(c, result)
1773
+ }
1774
+ }
1775
+
1776
+ const middleware = options.auth.mpp?.session(options.policy.mpp?.session ?? {})
1733
1777
  if (!middleware)
1734
1778
  return jsonError(c, {
1735
1779
  code: 'payment_required',
@@ -2,16 +2,7 @@ import * as FundingRoutes from './FundingRoutes.js'
2
2
 
3
3
  const baseUsdcRequest = {
4
4
  limit: 10,
5
- provider: 'across',
6
- sourceAmount: '1000000',
7
- sourceAmountUnits: 'baseUnits',
8
- sourceChain: 'base',
9
- sourceToken: 'USDC',
10
- } as const
11
-
12
- const baseAcrossQuoteRequest = {
13
- depositor: '0x1111111111111111111111111111111111111111',
14
- provider: 'across',
5
+ provider: 'relay',
15
6
  sourceAmount: '1000000',
16
7
  sourceAmountUnits: 'baseUnits',
17
8
  sourceChain: 'base',
@@ -24,7 +15,7 @@ describe('listRoutes', () => {
24
15
  const routes = await FundingRoutes.listRoutes({
25
16
  ...baseUsdcRequest,
26
17
  adapters: {
27
- across: {
18
+ relay: {
28
19
  async probeQuote(input, signal) {
29
20
  seen = input
30
21
  expect(signal.aborted).toBe(false)
@@ -62,14 +53,14 @@ describe('listRoutes', () => {
62
53
  },
63
54
  })
64
55
 
65
- expect(seen?.route.id).toBe('base-usdc-tempo-usdce-across')
56
+ expect(seen?.route.id).toBe('base-usdc-tempo-usdce-relay')
66
57
  expect(seen?.sourceAmount.amount).toBe('1000000')
67
58
  expect(seen?.sourceChain.id).toBe('eip155:8453')
68
59
  expect(seen?.sourceToken.symbol).toBe('USDC')
69
60
  expect(routes).toHaveLength(1)
70
61
  expect(routes[0]).toMatchObject({
71
62
  errorCode: null,
72
- id: 'base-usdc-tempo-usdce-across',
63
+ id: 'base-usdc-tempo-usdce-relay',
73
64
  quality: {
74
65
  availableVolumeUsd: '1000.00',
75
66
  estimatedSeconds: 4,
@@ -103,7 +94,7 @@ describe('listRoutes', () => {
103
94
  const routes = await FundingRoutes.listRoutes({
104
95
  ...baseUsdcRequest,
105
96
  adapters: {
106
- relay: {
97
+ bridge: {
107
98
  async probeQuote() {
108
99
  calls += 1
109
100
  throw new Error('unexpected call')
@@ -128,7 +119,7 @@ describe('listRoutes', () => {
128
119
  const routes = await FundingRoutes.listRoutes({
129
120
  ...baseUsdcRequest,
130
121
  adapters: {
131
- across: {
122
+ relay: {
132
123
  async probeQuote() {
133
124
  throw new Error('upstream unavailable')
134
125
  },
@@ -154,7 +145,7 @@ describe('listRoutes', () => {
154
145
  ...baseUsdcRequest,
155
146
  adapterTimeoutMs: 1,
156
147
  adapters: {
157
- across: {
148
+ relay: {
158
149
  probeQuote(_input, signal) {
159
150
  signal.addEventListener('abort', () => {
160
151
  aborted = true
@@ -183,7 +174,7 @@ describe('listRoutes', () => {
183
174
  const routes = await FundingRoutes.listRoutes({
184
175
  ...baseUsdcRequest,
185
176
  adapters: {
186
- across: {
177
+ relay: {
187
178
  async probeQuote(input) {
188
179
  seen = input
189
180
  return {
@@ -209,23 +200,6 @@ describe('listRoutes', () => {
209
200
  })
210
201
  })
211
202
 
212
- describe('quoteRoute', () => {
213
- test('rejects requests without a configured quote capability', async () => {
214
- await expect(FundingRoutes.quoteRoute(baseAcrossQuoteRequest)).rejects.toBeInstanceOf(
215
- FundingRoutes.ProviderNotConfiguredError,
216
- )
217
- })
218
-
219
- test('rejects requests outside curated inventory', async () => {
220
- await expect(
221
- FundingRoutes.quoteRoute({
222
- ...baseAcrossQuoteRequest,
223
- sourceToken: 'USDT',
224
- }),
225
- ).rejects.toBeInstanceOf(FundingRoutes.FundingRouteNotFoundError)
226
- })
227
- })
228
-
229
203
  describe('parseInclude', () => {
230
204
  test('parses comma-separated include values', () => {
231
205
  expect(FundingRoutes.parseInclude('quotes,quotes')).toEqual(['quotes'])
@@ -18,7 +18,6 @@ const sourceChains = [
18
18
  kind: 'evm',
19
19
  name: 'Ethereum',
20
20
  providerIds: {
21
- across: '1',
22
21
  bridge: 'ethereum',
23
22
  bungee: '1',
24
23
  lifi: '1',
@@ -75,7 +74,6 @@ const sourceChains = [
75
74
  kind: 'evm',
76
75
  name: 'Base',
77
76
  providerIds: {
78
- across: '8453',
79
77
  bridge: 'base',
80
78
  bungee: '8453',
81
79
  lifi: '8453',
@@ -116,7 +114,6 @@ const sourceChains = [
116
114
  kind: 'evm',
117
115
  name: 'BNB Smart Chain',
118
116
  providerIds: {
119
- across: '56',
120
117
  bungee: '56',
121
118
  lifi: '56',
122
119
  relay: '56',
@@ -241,14 +238,6 @@ const destinationTokens = [
241
238
 
242
239
  /** Providers exposed by the generic provider catalog. */
243
240
  const providers = [
244
- {
245
- capabilities: ['fundingRoutes'],
246
- id: 'across',
247
- kind: 'intentBridge',
248
- name: 'Across',
249
- requiresApiKey: true,
250
- status: 'inventoryOnly',
251
- },
252
241
  {
253
242
  capabilities: ['fundingRoutes'],
254
243
  id: 'relay',
@@ -413,64 +402,6 @@ export type QuoteProbeResult = {
413
402
  }
414
403
  }
415
404
 
416
- /** Token reference attached to a normalized provider fee. */
417
- export type ProviderQuoteFeeToken = {
418
- /** Token contract address on its chain. */
419
- address: string
420
- /** CAIP-2 chain id for the fee token. */
421
- chainId: string
422
- /** Number of decimal places used by the fee token. */
423
- decimals: number
424
- /** Fee token ticker symbol. */
425
- symbol: string
426
- }
427
-
428
- /** Normalized fee amount returned by a provider quote. */
429
- export type ProviderQuoteFee = {
430
- /** Fee amount in the fee token's base units. */
431
- amount: string
432
- /** Provider-estimated USD value of the fee. */
433
- amountUsd: string | null
434
- /** Fee as basis points of the quoted input, when available. */
435
- bps: number | null
436
- /** Token in which the fee amount is denominated. */
437
- token: ProviderQuoteFeeToken
438
- }
439
-
440
- /** Input passed to a provider for one explicit, depositor-specific quote. */
441
- export type ProviderQuoteInput = {
442
- /** Address that would submit the funding transaction. */
443
- depositor: string
444
- /** Optional destination recipient; providers default it to the depositor. */
445
- recipient?: string | undefined
446
- /** Curated route selected by the caller. */
447
- route: RouteCandidate
448
- }
449
-
450
- /** Dynamic data returned by an explicit provider quote. */
451
- export type ProviderQuoteResult = {
452
- /** Estimated settlement time in seconds. */
453
- estimatedSeconds: number | null
454
- /** Provider quote expiry timestamp. */
455
- expiresAt: string
456
- /** Current and maximum fee summaries. */
457
- fees: {
458
- /** Current estimated total fee. */
459
- total: ProviderQuoteFee
460
- /** Maximum total fee allowed by the quote. */
461
- totalMax: ProviderQuoteFee
462
- }
463
- /** Slippage-adjusted minimum destination amount in base units. */
464
- minimumOutputAmount: string
465
- /** Expected destination amount in base units. */
466
- outputAmount: string
467
- /** Timestamp when Tempo sampled the quote. */
468
- sampledAt: string
469
- }
470
-
471
- /** A normalized explicit funding quote returned to callers. */
472
- export type FundingQuote = ReturnType<typeof formatFundingQuote>
473
-
474
405
  /** Adapter used to enrich a static route candidate with live provider information. */
475
406
  export type ProviderAdapter = {
476
407
  /** Probes provider-backed quote information for one static candidate. */
@@ -480,15 +411,8 @@ export type ProviderAdapter = {
480
411
  /** Provider adapter registry, keyed by provider id. Missing adapters leave routes static. */
481
412
  export type ProviderAdapters = Partial<Record<ProviderId, ProviderAdapter>>
482
413
 
483
- /** Gets a depositor-specific quote without exposing provider execution payloads. */
484
- export type ProviderQuote = (
485
- input: ProviderQuoteInput,
486
- signal: AbortSignal,
487
- ) => Promise<ProviderQuoteResult>
488
-
489
414
  /** Static provider support rows used until live quote adapters are configured. */
490
415
  const inventory: readonly InventoryEntry[] = [
491
- { destinationToken: 'usdce', provider: 'across', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC'] }, // prettier-ignore
492
416
  { destinationToken: 'usdce', provider: 'relay', sourceChains: ['ethereum', 'base', 'bnb'], sourceTokens: ['USDC', 'USDT'] }, // prettier-ignore
493
417
  { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'base', 'solana'], sourceTokens: ['USDC'] }, // prettier-ignore
494
418
  { destinationToken: 'usdce', provider: 'bridge', sourceChains: ['ethereum', 'solana', 'tron'], sourceTokens: ['USDT'] }, // prettier-ignore
@@ -503,7 +427,6 @@ type InventoryEntry = {
503
427
  }
504
428
 
505
429
  const defaultAdapterTimeoutMs = 750
506
- const defaultQuoteTimeoutMs = 5_000
507
430
  const includes = ['quotes'] as const
508
431
 
509
432
  /** Lists normalized chains and source tokens that can fund Tempo. */
@@ -522,10 +445,7 @@ export function listProviders(options: listProviders.Options = {}) {
522
445
  )
523
446
  .map((provider) => ({
524
447
  ...formatProvider(provider),
525
- status:
526
- options.adapters?.[provider.id] || options.configuredProviders?.includes(provider.id)
527
- ? ('configured' as const)
528
- : provider.status,
448
+ status: options.adapters?.[provider.id] ? ('configured' as const) : provider.status,
529
449
  }))
530
450
  }
531
451
 
@@ -534,8 +454,6 @@ export declare namespace listProviders {
534
454
  type Options = {
535
455
  /** Provider adapters configured for this deployment. */
536
456
  adapters?: ProviderAdapters | undefined
537
- /** Providers configured through capabilities outside discovery adapters. */
538
- configuredProviders?: readonly ProviderId[] | undefined
539
457
  /** Provider capability to require. */
540
458
  capability?: Capability | undefined
541
459
  }
@@ -581,55 +499,6 @@ export async function listRoutes(options: listRoutes.Options) {
581
499
  )
582
500
  }
583
501
 
584
- /** Gets a depositor-specific quote for one curated funding route. */
585
- export async function quoteRoute(options: quoteRoute.Options): Promise<FundingQuote> {
586
- const [route] = listStaticRoutes({
587
- destinationToken: options.destinationToken,
588
- limit: 1,
589
- provider: options.provider,
590
- sourceAmount: options.sourceAmount,
591
- sourceAmountUnits: options.sourceAmountUnits,
592
- sourceChain: options.sourceChain,
593
- sourceToken: options.sourceToken,
594
- })
595
- if (!route) throw new FundingRouteNotFoundError()
596
-
597
- const quote = options.quote
598
- if (!quote) throw new ProviderNotConfiguredError()
599
-
600
- return formatFundingQuote(
601
- route,
602
- await runWithTimeout(
603
- (signal) =>
604
- quote(
605
- {
606
- depositor: options.depositor,
607
- ...(options.recipient === undefined ? {} : { recipient: options.recipient }),
608
- route,
609
- },
610
- signal,
611
- ),
612
- options.quoteTimeoutMs ?? defaultQuoteTimeoutMs,
613
- ),
614
- )
615
- }
616
-
617
- export declare namespace quoteRoute {
618
- /** Options for resolving and quoting one curated funding route. */
619
- type Options = Omit<listStaticRoutes.Options, 'limit' | 'provider'> & {
620
- /** Address that would submit the funding transaction. */
621
- depositor: string
622
- /** Configured provider quote capability. */
623
- quote?: ProviderQuote | undefined
624
- /** Provider selected for the quote. */
625
- provider: 'across'
626
- /** Maximum time allowed for the live provider request. */
627
- quoteTimeoutMs?: number | undefined
628
- /** Optional destination recipient; defaults to the depositor. */
629
- recipient?: string | undefined
630
- }
631
- }
632
-
633
502
  /** Lists static funding route candidates for a normalized caller request. */
634
503
  export function listStaticRoutes(options: listStaticRoutes.Options) {
635
504
  const sourceChain = resolveSourceChain(options.sourceChain)
@@ -881,28 +750,6 @@ function formatRouteQuote(route: RouteCandidate, quote: QuoteProbeResult) {
881
750
  } as const
882
751
  }
883
752
 
884
- function formatFundingQuote(route: RouteCandidate, quote: ProviderQuoteResult) {
885
- return {
886
- destinationChain: route.destinationChain,
887
- destinationToken: route.destinationToken,
888
- estimatedSeconds: quote.estimatedSeconds,
889
- expiresAt: quote.expiresAt,
890
- fees: quote.fees,
891
- inputAmount: route.sourceAmount.amount,
892
- minimumOutputAmount: quote.minimumOutputAmount,
893
- outputAmount: quote.outputAmount,
894
- outputAmountFormatted: decimalFromBaseUnits(
895
- quote.outputAmount,
896
- route.destinationToken.decimals,
897
- ),
898
- provider: route.provider,
899
- routeId: route.id,
900
- sampledAt: quote.sampledAt,
901
- sourceChain: route.sourceChain,
902
- sourceToken: route.sourceToken,
903
- } as const
904
- }
905
-
906
753
  function markRouteError(route: RouteCandidate, errorCode: string) {
907
754
  return {
908
755
  ...route,
@@ -1026,31 +873,11 @@ export class InvalidAmountError extends Error {
1026
873
  override name = 'FundingRoutes.InvalidAmountError'
1027
874
  }
1028
875
 
1029
- /** Error thrown when no curated route matches an explicit quote request. */
1030
- export class FundingRouteNotFoundError extends Error {
1031
- override name = 'FundingRoutes.FundingRouteNotFoundError'
1032
- }
1033
-
1034
876
  /** Error thrown internally when a provider adapter exceeds its route quote timeout. */
1035
877
  export class ProviderAdapterTimeoutError extends Error {
1036
878
  override name = 'FundingRoutes.ProviderAdapterTimeoutError'
1037
879
  }
1038
880
 
1039
- /** Error thrown when a requested provider quote is temporarily unavailable. */
1040
- export class ProviderQuoteUnavailableError extends Error {
1041
- override name = 'FundingRoutes.ProviderQuoteUnavailableError'
1042
- }
1043
-
1044
- /** Error thrown when a provider rate-limits a quote request. */
1045
- export class ProviderRateLimitError extends Error {
1046
- override name = 'FundingRoutes.ProviderRateLimitError'
1047
- }
1048
-
1049
- /** Error thrown when a route provider lacks explicit quote capability. */
1050
- export class ProviderNotConfiguredError extends Error {
1051
- override name = 'FundingRoutes.ProviderNotConfiguredError'
1052
- }
1053
-
1054
881
  /** Error thrown when the caller filters to an unknown provider. */
1055
882
  export class UnsupportedProviderError extends Error {
1056
883
  override name = 'FundingRoutes.UnsupportedProviderError'
@@ -145,8 +145,8 @@ describe('middleware', () => {
145
145
  c.set('providerFailure', {
146
146
  code: 'UNAUTHORIZED',
147
147
  failure: 'http',
148
- id: 'across',
149
- operation: 'swap/approval',
148
+ id: 'relay',
149
+ operation: 'quote/v2',
150
150
  status: 401,
151
151
  })
152
152
  return Response.error(c, {
@@ -167,8 +167,8 @@ describe('middleware', () => {
167
167
  "provider": {
168
168
  "code": "UNAUTHORIZED",
169
169
  "failure": "http",
170
- "id": "across",
171
- "operation": "swap/approval",
170
+ "id": "relay",
171
+ "operation": "quote/v2",
172
172
  "status": 401,
173
173
  },
174
174
  "route": "/provider",
@@ -0,0 +1,15 @@
1
+ import type { Store as MppStore } from 'mppx'
2
+ import { Store } from 'tapimo'
3
+
4
+ declare const namespace: Store.durableObject.Namespace
5
+
6
+ type Items = {
7
+ channel: { spent: bigint }
8
+ }
9
+
10
+ describe('durableObject', () => {
11
+ test('matches typed atomic stores', () => {
12
+ expectTypeOf(Store.durableObject(namespace)).toExtend<MppStore.AtomicStore<Items>>()
13
+ expectTypeOf(Store.durableObject<Items>(namespace)).toEqualTypeOf<Store.AtomicState<Items>>()
14
+ })
15
+ })