tapimo 0.7.2 → 0.9.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 (300) hide show
  1. package/README.md +10 -7
  2. package/dist/ApiKey.d.ts +3 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +10 -0
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +7 -3
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +9 -2
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +20117 -19183
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +61 -4
  13. package/dist/App.js.map +1 -1
  14. package/dist/admin/App.d.ts +84 -74
  15. package/dist/admin/App.d.ts.map +1 -1
  16. package/dist/admin/apps/api-keys.d.ts +14 -1
  17. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  18. package/dist/admin/apps/api-keys.js +6 -2
  19. package/dist/admin/apps/api-keys.js.map +1 -1
  20. package/dist/admin/apps/organizations.d.ts +2 -0
  21. package/dist/admin/apps/organizations.d.ts.map +1 -1
  22. package/dist/admin/apps/verified-tokens.d.ts +11 -11
  23. package/dist/admin/ui.generated.d.ts +1 -1
  24. package/dist/admin/ui.generated.js +67 -67
  25. package/dist/admin/ui.generated.js.map +1 -1
  26. package/dist/analytics/Analytics.d.ts +2 -0
  27. package/dist/analytics/Analytics.d.ts.map +1 -1
  28. package/dist/analytics/Analytics.js +3 -0
  29. package/dist/analytics/Analytics.js.map +1 -1
  30. package/dist/apps/data/App.d.ts +11696 -13937
  31. package/dist/apps/data/App.d.ts.map +1 -1
  32. package/dist/apps/data/App.js +4 -8
  33. package/dist/apps/data/App.js.map +1 -1
  34. package/dist/apps/data/routes/activities.d.ts +271 -271
  35. package/dist/apps/data/routes/addresses.d.ts +398 -167
  36. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  37. package/dist/apps/data/routes/balances.d.ts +278 -8
  38. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  39. package/dist/apps/data/routes/balances.js +114 -2
  40. package/dist/apps/data/routes/balances.js.map +1 -1
  41. package/dist/apps/data/routes/blocks.d.ts +123 -123
  42. package/dist/apps/data/routes/coingecko.d.ts +170 -170
  43. package/dist/apps/data/routes/earn.d.ts +498 -6
  44. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  45. package/dist/apps/data/routes/earn.js +876 -4
  46. package/dist/apps/data/routes/earn.js.map +1 -1
  47. package/dist/apps/data/routes/exchanges.d.ts +10 -10
  48. package/dist/apps/data/routes/fee-amm.d.ts +2 -2
  49. package/dist/apps/data/routes/indexer.d.ts +6 -6
  50. package/dist/apps/data/routes/indexer.js +4 -1
  51. package/dist/apps/data/routes/indexer.js.map +1 -1
  52. package/dist/apps/data/routes/receipts.d.ts +235 -235
  53. package/dist/apps/data/routes/rpc.d.ts +31 -31
  54. package/dist/apps/data/routes/rpc.js +4 -1
  55. package/dist/apps/data/routes/rpc.js.map +1 -1
  56. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  57. package/dist/apps/data/routes/tokens.d.ts +449 -449
  58. package/dist/apps/data/routes/transactions.d.ts +2 -2
  59. package/dist/apps/data/routes/transfers.d.ts +81 -81
  60. package/dist/apps/data/routes/valuation.d.ts +1 -1
  61. package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
  62. package/dist/apps/data/routes/webhooks.d.ts +9 -9
  63. package/dist/apps/data/routes/zones.d.ts +14 -14
  64. package/dist/apps/funding/Access.d.ts +16 -0
  65. package/dist/apps/funding/Access.d.ts.map +1 -0
  66. package/dist/apps/funding/Access.js +22 -0
  67. package/dist/apps/funding/Access.js.map +1 -0
  68. package/dist/apps/{data/routes/funding.d.ts → funding/App.d.ts} +1640 -3217
  69. package/dist/apps/funding/App.d.ts.map +1 -0
  70. package/dist/apps/funding/App.js +61 -0
  71. package/dist/apps/funding/App.js.map +1 -0
  72. package/dist/apps/funding/Inventory.d.ts +5 -0
  73. package/dist/apps/funding/Inventory.d.ts.map +1 -0
  74. package/dist/apps/funding/Inventory.js +25 -0
  75. package/dist/apps/funding/Inventory.js.map +1 -0
  76. package/dist/apps/funding/ProviderAttempts.d.ts +5 -0
  77. package/dist/apps/funding/ProviderAttempts.d.ts.map +1 -0
  78. package/dist/apps/funding/ProviderAttempts.js +24 -0
  79. package/dist/apps/funding/ProviderAttempts.js.map +1 -0
  80. package/dist/apps/funding/index.d.ts +2 -0
  81. package/dist/apps/funding/index.d.ts.map +1 -0
  82. package/dist/apps/funding/index.js +2 -0
  83. package/dist/apps/funding/index.js.map +1 -0
  84. package/dist/apps/funding/routes/chains.d.ts +169 -0
  85. package/dist/apps/funding/routes/chains.d.ts.map +1 -0
  86. package/dist/apps/funding/routes/chains.js +80 -0
  87. package/dist/apps/funding/routes/chains.js.map +1 -0
  88. package/dist/apps/funding/routes/deposit-addresses.d.ts +1997 -0
  89. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -0
  90. package/dist/apps/funding/routes/deposit-addresses.js +778 -0
  91. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -0
  92. package/dist/apps/funding/routes/providers.d.ts +91 -0
  93. package/dist/apps/funding/routes/providers.d.ts.map +1 -0
  94. package/dist/apps/funding/routes/providers.js +56 -0
  95. package/dist/apps/funding/routes/providers.js.map +1 -0
  96. package/dist/apps/funding/routes/quotes.d.ts +426 -0
  97. package/dist/apps/funding/routes/quotes.d.ts.map +1 -0
  98. package/dist/apps/funding/routes/quotes.js +188 -0
  99. package/dist/apps/funding/routes/quotes.js.map +1 -0
  100. package/dist/apps/funding/routes/transfers.d.ts +1999 -0
  101. package/dist/apps/funding/routes/transfers.d.ts.map +1 -0
  102. package/dist/apps/funding/routes/transfers.js +614 -0
  103. package/dist/apps/funding/routes/transfers.js.map +1 -0
  104. package/dist/apps/index.d.ts +1 -0
  105. package/dist/apps/index.d.ts.map +1 -1
  106. package/dist/apps/index.js +1 -0
  107. package/dist/apps/index.js.map +1 -1
  108. package/dist/apps/management/App.d.ts +430 -165
  109. package/dist/apps/management/App.d.ts.map +1 -1
  110. package/dist/apps/management/routes/api-keys.d.ts +298 -21
  111. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  112. package/dist/apps/management/routes/api-keys.js +75 -1
  113. package/dist/apps/management/routes/api-keys.js.map +1 -1
  114. package/dist/apps/management/routes/billing.d.ts +6 -6
  115. package/dist/apps/management/routes/faucet.d.ts +35 -35
  116. package/dist/apps/management/routes/invitations.d.ts +122 -122
  117. package/dist/apps/management/routes/invite-links.d.ts +38 -38
  118. package/dist/apps/management/routes/members.d.ts +69 -69
  119. package/dist/apps/management/routes/orgs.d.ts +99 -99
  120. package/dist/apps/management/routes/projects.d.ts +25 -25
  121. package/dist/apps/management/routes/scopes.d.ts +1 -1
  122. package/dist/apps/management/routes/usage.d.ts +72 -72
  123. package/dist/apps/management/routes/verified-token-requests.d.ts +77 -77
  124. package/dist/apps/management/routes/webhooks.d.ts +128 -128
  125. package/dist/apps/mcp.d.ts +2 -3
  126. package/dist/apps/mcp.d.ts.map +1 -1
  127. package/dist/apps/mcp.js +16 -14
  128. package/dist/apps/mcp.js.map +1 -1
  129. package/dist/apps/metadata.d.ts +4 -0
  130. package/dist/apps/metadata.d.ts.map +1 -1
  131. package/dist/apps/metadata.js +10 -0
  132. package/dist/apps/metadata.js.map +1 -1
  133. package/dist/apps/mpp/App.d.ts +44 -44
  134. package/dist/cloudflare.d.ts +50 -0
  135. package/dist/cloudflare.d.ts.map +1 -1
  136. package/dist/cloudflare.js +178 -0
  137. package/dist/cloudflare.js.map +1 -1
  138. package/dist/db/Db.d.ts +2 -0
  139. package/dist/db/Db.d.ts.map +1 -1
  140. package/dist/db/Db.js +45 -0
  141. package/dist/db/Db.js.map +1 -1
  142. package/dist/db/Schema.d.ts +12 -0
  143. package/dist/db/Schema.d.ts.map +1 -1
  144. package/dist/db/Schema.js +20 -0
  145. package/dist/db/Schema.js.map +1 -1
  146. package/dist/db/tables/fundingDepositAddresses.d.ts +13 -0
  147. package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -1
  148. package/dist/db/tables/fundingDepositAddresses.js +12 -0
  149. package/dist/db/tables/fundingDepositAddresses.js.map +1 -1
  150. package/dist/db/tables/fundingDepositRequestObservations.d.ts +45 -0
  151. package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +1 -0
  152. package/dist/db/tables/fundingDepositRequestObservations.js +46 -0
  153. package/dist/db/tables/fundingDepositRequestObservations.js.map +1 -0
  154. package/dist/db/tables/fundingDeposits.d.ts +74 -1
  155. package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
  156. package/dist/db/tables/fundingDeposits.js +126 -0
  157. package/dist/db/tables/fundingDeposits.js.map +1 -1
  158. package/dist/internal/Auth.d.ts +15 -11
  159. package/dist/internal/Auth.d.ts.map +1 -1
  160. package/dist/internal/Auth.js +52 -17
  161. package/dist/internal/Auth.js.map +1 -1
  162. package/dist/internal/Cache.js +1 -1
  163. package/dist/internal/Cache.js.map +1 -1
  164. package/dist/internal/EdgeCache.d.ts +2 -2
  165. package/dist/internal/EdgeCache.d.ts.map +1 -1
  166. package/dist/internal/EdgeCache.js +10 -4
  167. package/dist/internal/EdgeCache.js.map +1 -1
  168. package/dist/internal/IpAllowlist.d.ts +15 -0
  169. package/dist/internal/IpAllowlist.d.ts.map +1 -0
  170. package/dist/internal/IpAllowlist.js +27 -0
  171. package/dist/internal/IpAllowlist.js.map +1 -0
  172. package/dist/internal/OpenApi.d.ts +1 -1
  173. package/dist/internal/OpenApi.js +1 -1
  174. package/dist/internal/OpenApi.js.map +1 -1
  175. package/dist/internal/Tidx.d.ts +6 -0
  176. package/dist/internal/Tidx.d.ts.map +1 -1
  177. package/dist/internal/Tidx.js +13 -3
  178. package/dist/internal/Tidx.js.map +1 -1
  179. package/dist/internal/Viem.d.ts +8 -0
  180. package/dist/internal/Viem.d.ts.map +1 -1
  181. package/dist/internal/Viem.js +12 -5
  182. package/dist/internal/Viem.js.map +1 -1
  183. package/dist/internal/funding/Deposit.d.ts +42 -0
  184. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  185. package/dist/internal/funding/Deposit.js +37 -5
  186. package/dist/internal/funding/Deposit.js.map +1 -1
  187. package/dist/internal/funding/Evidence.d.ts +1 -5
  188. package/dist/internal/funding/Evidence.d.ts.map +1 -1
  189. package/dist/internal/funding/Evidence.js +4 -3
  190. package/dist/internal/funding/Evidence.js.map +1 -1
  191. package/dist/internal/funding/Provider.d.ts +102 -0
  192. package/dist/internal/funding/Provider.d.ts.map +1 -1
  193. package/dist/internal/funding/Provider.js +5 -0
  194. package/dist/internal/funding/Provider.js.map +1 -1
  195. package/dist/internal/funding/Reconciliation.d.ts +16 -2
  196. package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
  197. package/dist/internal/funding/Reconciliation.js +348 -54
  198. package/dist/internal/funding/Reconciliation.js.map +1 -1
  199. package/dist/internal/funding/SourceObservation.d.ts +108 -0
  200. package/dist/internal/funding/SourceObservation.d.ts.map +1 -0
  201. package/dist/internal/funding/SourceObservation.js +143 -0
  202. package/dist/internal/funding/SourceObservation.js.map +1 -0
  203. package/dist/internal/funding/Subsidy.d.ts +2 -2
  204. package/dist/internal/funding/Subsidy.d.ts.map +1 -1
  205. package/dist/internal/funding/Subsidy.js +1 -1
  206. package/dist/internal/funding/Subsidy.js.map +1 -1
  207. package/dist/internal/funding/index.d.ts +1 -0
  208. package/dist/internal/funding/index.d.ts.map +1 -1
  209. package/dist/internal/funding/index.js +1 -0
  210. package/dist/internal/funding/index.js.map +1 -1
  211. package/dist/internal/funding/providers/relay.d.ts +43 -1
  212. package/dist/internal/funding/providers/relay.d.ts.map +1 -1
  213. package/dist/internal/funding/providers/relay.js +438 -27
  214. package/dist/internal/funding/providers/relay.js.map +1 -1
  215. package/package.json +3 -3
  216. package/src/ApiKey.test.ts +35 -0
  217. package/src/ApiKey.ts +27 -0
  218. package/src/ApiKeys.test.ts +29 -0
  219. package/src/ApiKeys.ts +11 -3
  220. package/src/App.test.ts +55 -5
  221. package/src/App.ts +79 -5
  222. package/src/Client.test-d.ts +203 -28
  223. package/src/admin/apps/api-keys.test.ts +25 -1
  224. package/src/admin/apps/api-keys.ts +6 -2
  225. package/src/admin/ui.generated.ts +67 -67
  226. package/src/analytics/Analytics.ts +4 -0
  227. package/src/apps/composition.test.ts +130 -3
  228. package/src/apps/data/App.test.ts +0 -12
  229. package/src/apps/data/App.ts +4 -8
  230. package/src/apps/data/routes/balances.test.ts +42 -0
  231. package/src/apps/data/routes/balances.ts +218 -85
  232. package/src/apps/data/routes/earn.test.ts +363 -0
  233. package/src/apps/data/routes/earn.ts +1141 -3
  234. package/src/apps/data/routes/indexer.ts +2 -1
  235. package/src/apps/data/routes/rpc.ts +2 -0
  236. package/src/apps/data/routes/tokens.test.ts +6 -8
  237. package/src/apps/funding/Access.ts +26 -0
  238. package/src/apps/funding/App.test.ts +78 -0
  239. package/src/apps/funding/App.ts +78 -0
  240. package/src/apps/funding/Inventory.ts +30 -0
  241. package/src/apps/funding/ProviderAttempts.ts +26 -0
  242. package/src/apps/funding/index.ts +1 -0
  243. package/src/apps/funding/routes/chains.test.ts +78 -0
  244. package/src/apps/funding/routes/chains.ts +101 -0
  245. package/src/apps/funding/routes/deposit-addresses.test.ts +1649 -0
  246. package/src/apps/funding/routes/deposit-addresses.ts +932 -0
  247. package/src/apps/funding/routes/providers.test.ts +165 -0
  248. package/src/apps/funding/routes/providers.ts +73 -0
  249. package/src/apps/funding/routes/quotes.test.ts +511 -0
  250. package/src/apps/funding/routes/quotes.ts +205 -0
  251. package/src/apps/funding/routes/transfers.test.ts +1236 -0
  252. package/src/apps/funding/routes/transfers.ts +704 -0
  253. package/src/apps/index.ts +1 -0
  254. package/src/apps/management/routes/api-keys.test.ts +98 -0
  255. package/src/apps/management/routes/api-keys.ts +96 -1
  256. package/src/apps/mcp.test.ts +17 -2
  257. package/src/apps/mcp.ts +18 -13
  258. package/src/apps/metadata.ts +12 -0
  259. package/src/apps/mpp/internal/Policy.test.ts +7 -1
  260. package/src/cloudflare.ts +279 -0
  261. package/src/db/Db.ts +71 -0
  262. package/src/db/Schema.ts +24 -0
  263. package/src/db/tables/fundingDepositAddresses.ts +28 -0
  264. package/src/db/tables/fundingDepositRequestObservations.test.ts +106 -0
  265. package/src/db/tables/fundingDepositRequestObservations.ts +99 -0
  266. package/src/db/tables/fundingDeposits.test.ts +239 -0
  267. package/src/db/tables/fundingDeposits.ts +214 -1
  268. package/src/internal/Auth.test.ts +205 -5
  269. package/src/internal/Auth.ts +63 -19
  270. package/src/internal/Cache.test.ts +37 -3
  271. package/src/internal/Cache.ts +1 -1
  272. package/src/internal/EdgeCache.test.ts +7 -7
  273. package/src/internal/EdgeCache.ts +13 -4
  274. package/src/internal/IpAllowlist.test.ts +52 -0
  275. package/src/internal/IpAllowlist.ts +39 -0
  276. package/src/internal/Log.test.ts +7 -1
  277. package/src/internal/OpenApi.ts +1 -1
  278. package/src/internal/Tidx.test.ts +28 -0
  279. package/src/internal/Tidx.ts +19 -3
  280. package/src/internal/Viem.test.ts +28 -0
  281. package/src/internal/Viem.ts +21 -5
  282. package/src/internal/funding/Deposit.ts +74 -5
  283. package/src/internal/funding/Evidence.test.ts +2 -2
  284. package/src/internal/funding/Evidence.ts +4 -9
  285. package/src/internal/funding/Provider.ts +115 -0
  286. package/src/internal/funding/Reconciliation.local.test.ts +7 -0
  287. package/src/internal/funding/Reconciliation.test.ts +1364 -109
  288. package/src/internal/funding/Reconciliation.ts +467 -88
  289. package/src/internal/funding/SourceObservation.test.ts +301 -0
  290. package/src/internal/funding/SourceObservation.ts +267 -0
  291. package/src/internal/funding/Subsidy.ts +2 -2
  292. package/src/internal/funding/index.test.ts +1 -0
  293. package/src/internal/funding/index.ts +1 -0
  294. package/src/internal/funding/providers/relay.test.ts +94 -4
  295. package/src/internal/funding/providers/relay.ts +533 -27
  296. package/dist/apps/data/routes/funding.d.ts.map +0 -1
  297. package/dist/apps/data/routes/funding.js +0 -1557
  298. package/dist/apps/data/routes/funding.js.map +0 -1
  299. package/src/apps/data/routes/funding.test.ts +0 -2994
  300. package/src/apps/data/routes/funding.ts +0 -1821
@@ -102,7 +102,13 @@ describe('middleware', () => {
102
102
  const api = app({ emit: (entry) => void entries.push(entry) })
103
103
  api.use('*', async (c, next) => {
104
104
  c.set('principal', {
105
- apiKey: { environment: 'production', id: 'key_1', orgId: 'org_1', scopes: ['data:read'] },
105
+ apiKey: {
106
+ allowedIps: [],
107
+ environment: 'production',
108
+ id: 'key_1',
109
+ orgId: 'org_1',
110
+ scopes: ['data:read'],
111
+ },
106
112
  environment: 'production',
107
113
  id: 'key_1',
108
114
  orgId: 'org_1',
@@ -80,7 +80,7 @@ export const errorCodes = {
80
80
  'api_key_malformed',
81
81
  ],
82
82
  401: ['api_key_missing', 'api_key_invalid', 'unauthorized'],
83
- 403: ['api_key_forbidden', 'limit_exceeded'],
83
+ 403: ['api_key_forbidden', 'api_key_ip_forbidden', 'limit_exceeded'],
84
84
  404: [
85
85
  'not_found',
86
86
  'token_not_found',
@@ -460,6 +460,34 @@ describe('getClient', () => {
460
460
  fetch.mockRestore()
461
461
  }
462
462
  })
463
+
464
+ test('sends Zone headers', async () => {
465
+ const fetch = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
466
+ new Response(JSON.stringify({ columns: [], ok: true, row_count: 0, rows: [] }), {
467
+ headers: { 'content-type': 'application/json' },
468
+ }),
469
+ )
470
+ try {
471
+ const client = Tidx.getClient({
472
+ chainId: Zones.zoneE.id,
473
+ tidx: {
474
+ baseUrl: 'https://internal.indexer',
475
+ zoneHeaders: {
476
+ 'CF-Access-Client-Id': 'client-id',
477
+ 'CF-Access-Client-Secret': 'client-secret',
478
+ },
479
+ },
480
+ zone: Zones.zoneE,
481
+ })
482
+ await client.fetch({ query: 'select 1' })
483
+
484
+ const upstream = fetch.mock.calls[0]![0] as Request
485
+ expect(upstream.headers.get('CF-Access-Client-Id')).toBe('client-id')
486
+ expect(upstream.headers.get('CF-Access-Client-Secret')).toBe('client-secret')
487
+ } finally {
488
+ fetch.mockRestore()
489
+ }
490
+ })
463
491
  })
464
492
 
465
493
  describe('createGetClient', () => {
@@ -41,6 +41,7 @@ export function resolve(
41
41
  const config = typeof tidx === 'function' ? tidx(context) : tidx
42
42
  return {
43
43
  ...Auth.resolveCredential({ chainId: context.chainId, value: config?.auth }),
44
+ ...(context.zone && config?.zoneHeaders ? { zoneHeaders: config.zoneHeaders } : {}),
44
45
  baseUrl:
45
46
  Viem.resolveUrl(config?.baseUrl, context.chainId) ??
46
47
  context.zone?.rpcUrls['tidx']?.http[0] ??
@@ -61,18 +62,25 @@ export declare namespace resolve {
61
62
  basicAuth?: string | undefined
62
63
  /** Bearer auth credential, or undefined to send no Bearer auth. */
63
64
  bearerAuth?: string | undefined
65
+ /** Headers sent to Zone indexer upstreams. */
66
+ zoneHeaders?: Viem.ZoneHeaders | undefined
64
67
  }
65
68
  }
66
69
 
67
70
  export function getClient(options: getClient.Options): Client {
68
71
  const { chainId = Viem.defaultChainId, principal = null, tidx, zone } = options
69
- const { baseUrl, basicAuth, bearerAuth } = resolve(tidx, { chainId, principal, zone })
72
+ const { baseUrl, basicAuth, bearerAuth, zoneHeaders } = resolve(tidx, {
73
+ chainId,
74
+ principal,
75
+ zone,
76
+ })
70
77
  return withTransientRetry(
71
78
  Tidx.create({
72
79
  baseUrl,
73
80
  basicAuth,
74
81
  bearerAuth,
75
82
  chainId,
83
+ headers: zoneHeaders,
76
84
  }),
77
85
  )
78
86
  }
@@ -96,8 +104,12 @@ export function createGetClient(options: createGetClient.Options = {}): GetClien
96
104
  const { principal = null, zone } = options
97
105
  // Resolve to derive the cache key; `getClient` re-resolves to build the
98
106
  // client on a miss. `resolve` is pure and cheap, so the extra call is free.
99
- const { baseUrl, basicAuth, bearerAuth } = resolve(tidx, { chainId, principal, zone })
100
- const cacheKey = `${baseUrl}|${basicAuth ?? ''}|${bearerAuth ?? ''}|${chainId}`
107
+ const { baseUrl, basicAuth, bearerAuth, zoneHeaders } = resolve(tidx, {
108
+ chainId,
109
+ principal,
110
+ zone,
111
+ })
112
+ const cacheKey = `${baseUrl}|${basicAuth ?? ''}|${bearerAuth ?? ''}|${JSON.stringify(zoneHeaders)}|${chainId}`
101
113
  const existing = clients.get(cacheKey)
102
114
  if (existing) return existing
103
115
 
@@ -312,12 +324,16 @@ export declare namespace getClient {
312
324
  auth?: Auth.ChainCredential | undefined
313
325
  /** Resolves the TIDX base URL for a Tempo chain id, or a static base URL. */
314
326
  baseUrl?: UrlResolver | undefined
327
+ /** Headers sent to Zone indexer upstreams. */
328
+ zoneHeaders?: Viem.ZoneHeaders | undefined
315
329
  }
316
330
  | ((context: Viem.resolveRpc.Context) => {
317
331
  /** Shared or per-chain TIDX credentials, or undefined for none. */
318
332
  auth?: Auth.ChainCredential | undefined
319
333
  /** TIDX base URL to use; falls back to the built-in public host when omitted. */
320
334
  baseUrl?: string | undefined
335
+ /** Headers sent to Zone indexer upstreams. */
336
+ zoneHeaders?: Viem.ZoneHeaders | undefined
321
337
  })
322
338
  }
323
339
 
@@ -265,6 +265,34 @@ describe('getClient', () => {
265
265
  fetch.mockRestore()
266
266
  }
267
267
  })
268
+
269
+ test('sends Zone headers to both internal and public Zone URLs', async () => {
270
+ const fetch = vi
271
+ .spyOn(globalThis, 'fetch')
272
+ .mockResolvedValue(Response.json({ id: 1, jsonrpc: '2.0', result: '0x1079' }))
273
+ try {
274
+ const client = Viem.getClient({
275
+ chainId: zone.id,
276
+ rpc: {
277
+ publicZoneUrl: 'https://public.zone.rpc.test',
278
+ zoneHeaders: {
279
+ 'CF-Access-Client-Id': 'client-id',
280
+ 'CF-Access-Client-Secret': 'client-secret',
281
+ },
282
+ },
283
+ zone,
284
+ zoneToken: 'zone-token',
285
+ })
286
+ await client.getChainId()
287
+
288
+ const [input, init] = fetch.mock.calls[0]!
289
+ const upstream = new Request(input, init)
290
+ expect(upstream.headers.get('CF-Access-Client-Id')).toBe('client-id')
291
+ expect(upstream.headers.get('CF-Access-Client-Secret')).toBe('client-secret')
292
+ } finally {
293
+ fetch.mockRestore()
294
+ }
295
+ })
268
296
  })
269
297
 
270
298
  describe('createGetClient', () => {
@@ -47,6 +47,9 @@ export type UrlResolver =
47
47
  | Record<number, string>
48
48
  | ((chainId: ChainId) => string | undefined)
49
49
 
50
+ /** Headers required when connecting to a Zone upstream. */
51
+ export type ZoneHeaders = Record<string, string>
52
+
50
53
  /** Returns chain ids declared by a static chain-id-to-URL map. */
51
54
  export function configuredChainIds(value: UrlResolver | undefined): number[] {
52
55
  const urls = parseUrls(value)
@@ -83,6 +86,7 @@ export function resolveRpc(
83
86
  return {
84
87
  ...auth,
85
88
  ...(publicZoneUrl ? { publicZoneUrl } : {}),
89
+ ...(context.zone && config?.zoneHeaders ? { zoneHeaders: config.zoneHeaders } : {}),
86
90
  url:
87
91
  resolveUrl(config?.url, context.chainId) ??
88
92
  context.zone?.rpcUrls['internal']?.http[0] ??
@@ -114,6 +118,8 @@ export declare namespace resolveRpc {
114
118
  bearerAuth?: string | undefined
115
119
  /** Public Zone RPC URL that accepts a caller-provided authorization token. */
116
120
  publicZoneUrl?: string | undefined
121
+ /** Headers sent to Zone RPC upstreams. */
122
+ zoneHeaders?: ZoneHeaders | undefined
117
123
  /**
118
124
  * Resolved RPC URL, or `undefined` when neither a configured `rpc` nor the
119
125
  * built-in {@link url} map covers the chain (e.g. an unconfigured localnet).
@@ -125,7 +131,7 @@ export declare namespace resolveRpc {
125
131
 
126
132
  export function getClient(options: getClient.Options): getClient.ReturnType {
127
133
  const { chainId = defaultChainId, principal = null, rpc, zone, zoneToken } = options
128
- const { basicAuth, bearerAuth, publicZoneUrl, url } = resolveRpc(rpc, {
134
+ const { basicAuth, bearerAuth, publicZoneUrl, url, zoneHeaders } = resolveRpc(rpc, {
129
135
  chainId,
130
136
  principal,
131
137
  zone,
@@ -141,9 +147,10 @@ export function getClient(options: getClient.Options): getClient.ReturnType {
141
147
  ? `Bearer ${bearerAuth}`
142
148
  : undefined
143
149
  const fetchOptions =
144
- authorization || zoneToken
150
+ authorization || zoneToken || zoneHeaders
145
151
  ? {
146
152
  headers: {
153
+ ...(zoneHeaders ? Object.fromEntries(new Headers(zoneHeaders)) : {}),
147
154
  ...(authorization ? { Authorization: authorization } : {}),
148
155
  ...(zoneToken ? { [ZoneRpcAuthentication.headerName]: zoneToken } : {}),
149
156
  },
@@ -171,18 +178,23 @@ export function createGetClient(options: createGetClient.Options = {}): createGe
171
178
  const zones = new Map((options.zones ?? []).map((zone) => [zone.id, zone]))
172
179
 
173
180
  return (chainId = defaultChainId_option, principal = null) => {
174
- const { basicAuth, bearerAuth, url } = resolveRpc(rpc, {
181
+ const { basicAuth, bearerAuth, url, zoneHeaders } = resolveRpc(rpc, {
175
182
  chainId,
176
183
  principal,
177
184
  zone: zones.get(chainId),
178
185
  })
179
- const cacheKey = JSON.stringify([url, basicAuth, bearerAuth, chainId])
186
+ const cacheKey = JSON.stringify([url, basicAuth, bearerAuth, zoneHeaders, chainId])
180
187
  const existing = clients.get(cacheKey)
181
188
  if (existing) return existing
182
189
 
183
190
  const client = getClient({
184
191
  chainId,
185
- rpc: { auth: basicAuth ?? bearerAuth, url: () => url },
192
+ rpc: {
193
+ auth: basicAuth ?? bearerAuth,
194
+ url: () => url,
195
+ ...(zoneHeaders ? { zoneHeaders } : {}),
196
+ },
197
+ zone: zones.get(chainId),
186
198
  })
187
199
  clients.set(cacheKey, client)
188
200
  return client
@@ -240,6 +252,8 @@ export declare namespace getClient {
240
252
  auth?: Auth.ChainCredential | undefined
241
253
  /** Resolves the public Zone RPC URL used with caller-provided authorization. */
242
254
  publicZoneUrl?: UrlResolver | undefined
255
+ /** Headers sent to Zone RPC upstreams. */
256
+ zoneHeaders?: ZoneHeaders | undefined
243
257
  /** Resolves the RPC URL for a Tempo chain id. */
244
258
  url?: UrlResolver | undefined
245
259
  }
@@ -248,6 +262,8 @@ export declare namespace getClient {
248
262
  auth?: Auth.ChainCredential | undefined
249
263
  /** Public Zone RPC URL used with caller-provided authorization. */
250
264
  publicZoneUrl?: string | undefined
265
+ /** Headers sent to Zone RPC upstreams. */
266
+ zoneHeaders?: ZoneHeaders | undefined
251
267
  /** RPC URL to use; falls back to the built-in public host when omitted. */
252
268
  url?: string | undefined
253
269
  })
@@ -7,6 +7,12 @@ import * as Id from '../Id.js'
7
7
  import * as Schema from '../Schema.js'
8
8
  import * as Provider from './Provider.js'
9
9
 
10
+ /** Mechanisms that can first detect a funding deposit. */
11
+ export const detectionTriggers = ['chain', 'manual', 'poll', 'webhook'] as const
12
+
13
+ /** Mechanism that first detected a funding deposit. */
14
+ export type DetectionTrigger = (typeof detectionTriggers)[number]
15
+
10
16
  /**
11
17
  * Public funding deposit statuses:
12
18
  *
@@ -95,6 +101,11 @@ export namespace schema {
95
101
  .readonly(z.array(z.string()))
96
102
  .check(z.describe(description), z.meta({ examples: [[`0x${'aa'.repeat(32)}`]] }))
97
103
 
104
+ /** Mechanism that first detected a funding deposit. */
105
+ export const DetectionTrigger = z
106
+ .enum(detectionTriggers)
107
+ .check(z.describe('How the deposit was first detected.'), z.meta({ examples: ['webhook'] }))
108
+
98
109
  /** Funding deposit lifecycle status. */
99
110
  export const Status = z
100
111
  .enum(statuses)
@@ -187,6 +198,7 @@ export namespace schema {
187
198
  z.meta({ examples: ['2026-08-04T00:01:00.000Z'] }),
188
199
  ),
189
200
  depositAddressId: Snapshot.shape.depositAddressId,
201
+ detectionTrigger: z.optional(DetectionTrigger),
190
202
  destinationAmount: Snapshot.shape.destinationAmount,
191
203
  destinationAmountRequired: Snapshot.shape.destinationAmountRequired,
192
204
  destinationChain: Snapshot.shape.destinationChain,
@@ -238,6 +250,46 @@ export type Public = z.output<typeof schema.FundingDeposit>
238
250
 
239
251
  /** Creates a durable record for one provider-observed source transaction. */
240
252
  export async function create(db: Db.Db, input: create.Input): Promise<FundingDeposits.Record> {
253
+ return FundingDeposits.insert(db, await record(db, input))
254
+ }
255
+
256
+ /** Creates or returns the deposit for one verified chain transfer. */
257
+ export async function createFromSource(
258
+ db: Db.Db,
259
+ input: createFromSource.Input,
260
+ ): Promise<FundingDeposits.insertOrGetSource.Result> {
261
+ const stored = await record(db, {
262
+ detectionTrigger: 'chain',
263
+ now: input.now,
264
+ providerRequestId: null,
265
+ snapshot: input.snapshot,
266
+ sourceTransactionHash: input.sourceTransactionHash,
267
+ sourceTransferIndex: input.sourceTransferIndex,
268
+ })
269
+ return FundingDeposits.insertOrGetSource(db, {
270
+ ...stored,
271
+ sourceTransferIndex: input.sourceTransferIndex,
272
+ })
273
+ }
274
+
275
+ export declare namespace createFromSource {
276
+ /** Verified source transfer used to create a chain-detected deposit. */
277
+ type Input = {
278
+ /** Detection time override for deterministic tests. */
279
+ now?: Date | undefined
280
+ /** Public route and verified source amount. */
281
+ snapshot: Snapshot
282
+ /** Source transaction containing the deposited transfer. */
283
+ sourceTransactionHash: string
284
+ /** Verified transfer position within the source transaction. */
285
+ sourceTransferIndex: number
286
+ }
287
+ }
288
+
289
+ async function record(
290
+ db: Db.Db,
291
+ input: Omit<create.Input, 'providerRequestId'> & { providerRequestId: string | null },
292
+ ): Promise<FundingDeposits.Record> {
241
293
  const now = input.now ?? new Date()
242
294
  const depositAddressId = schema.Snapshot.shape.depositAddressId.parse(
243
295
  input.snapshot.depositAddressId,
@@ -256,18 +308,23 @@ export async function create(db: Db.Db, input: create.Input): Promise<FundingDep
256
308
  sourceToken: address.snapshot.sourceToken,
257
309
  sourceTransactionHashes: [input.sourceTransactionHash],
258
310
  })
259
- return FundingDeposits.insert(db, {
311
+ return {
260
312
  createdAt: now.toISOString(),
261
313
  depositAddressId: snapshot.depositAddressId,
314
+ detectionTrigger: input.detectionTrigger ?? null,
262
315
  environment: address.environment,
263
316
  id: input.id ?? generateId(now),
264
317
  orgId: address.orgId,
318
+ pollObservedAt: input.pollObservedAt ?? null,
265
319
  projectId: address.projectId,
266
320
  providerOutputAmount: input.providerOutputAmount ?? null,
267
321
  providerOutputToken: address.providerOutputToken,
268
322
  providerRequestId: input.providerRequestId,
269
323
  providerRequestIds: [
270
- ...new Set([input.providerRequestId, ...(input.providerRequestIds ?? [])]),
324
+ ...new Set([
325
+ ...(input.providerRequestId === null ? [] : [input.providerRequestId]),
326
+ ...(input.providerRequestIds ?? []),
327
+ ]),
271
328
  ],
272
329
  providerState: input.providerState ?? null,
273
330
  providerTransactionHashes: input.providerTransactionHashes ?? [],
@@ -285,16 +342,21 @@ export async function create(db: Db.Db, input: create.Input): Promise<FundingDep
285
342
  tempoGasPaid: input.tempoGasPaid ?? null,
286
343
  updatedAt: now.toISOString(),
287
344
  version: 1,
288
- })
345
+ webhookReceivedAt: input.webhookReceivedAt ?? null,
346
+ }
289
347
  }
290
348
 
291
349
  export declare namespace create {
292
350
  /** Fields required to persist a provider-observed deposit. */
293
351
  type Input = {
352
+ /** Mechanism that first detected the deposit. */
353
+ detectionTrigger?: DetectionTrigger | undefined
294
354
  /** Deposit id override for deterministic tests. */
295
355
  id?: string | undefined
296
356
  /** Detection time override for deterministic tests. */
297
357
  now?: Date | undefined
358
+ /** When polling first observed the provider request. */
359
+ pollObservedAt?: string | undefined
298
360
  /** Provider output amount confirmed on Tempo. */
299
361
  providerOutputAmount?: z.output<typeof Schema.TokenAmount> | undefined
300
362
  /** Provider request that reported the source transaction. */
@@ -323,6 +385,8 @@ export declare namespace create {
323
385
  subsidyAmount?: z.output<typeof Schema.TokenAmount> | undefined
324
386
  /** Tempo gas paid for settlement, in base units. */
325
387
  tempoGasPaid?: string | undefined
388
+ /** When Tempo first received an authenticated provider webhook. */
389
+ webhookReceivedAt?: string | undefined
326
390
  }
327
391
  }
328
392
 
@@ -362,12 +426,12 @@ export async function transition(
362
426
  expectedVersion: options.expectedVersion,
363
427
  id: options.id,
364
428
  providerOutputAmount: options.providerOutputAmount ?? current.providerOutputAmount,
365
- providerRequestId: current.providerRequestId,
429
+ providerRequestId: current.providerRequestId ?? options.providerRequestId ?? null,
366
430
  providerRequestIds: options.providerRequestIds ?? current.providerRequestIds,
367
431
  providerState: options.providerState ?? current.providerState,
368
432
  providerTransactionHashes:
369
433
  options.providerTransactionHashes ?? current.providerTransactionHashes,
370
- providerTransferIndex: current.providerTransferIndex,
434
+ providerTransferIndex: options.providerTransferIndex ?? current.providerTransferIndex,
371
435
  retryState: options.retryState ?? current.retryState,
372
436
  settlementTransaction: options.settlementTransaction ?? current.settlementTransaction,
373
437
  settlementTransactionHash:
@@ -395,12 +459,16 @@ export declare namespace transition {
395
459
  id: string
396
460
  /** Provider output amount confirmed on Tempo. */
397
461
  providerOutputAmount?: z.output<typeof Schema.TokenAmount> | undefined
462
+ /** Provider request attached after chain-first detection. */
463
+ providerRequestId?: string | undefined
398
464
  /** Private provider request identifiers. */
399
465
  providerRequestIds?: readonly string[] | undefined
400
466
  /** Bounded private provider state. */
401
467
  providerState?: PrivateState | undefined
402
468
  /** Provider-leg transaction references. */
403
469
  providerTransactionHashes?: readonly string[] | undefined
470
+ /** Deposit position within the attached provider request. */
471
+ providerTransferIndex?: number | undefined
404
472
  /** Bounded private retry state. */
405
473
  retryState?: PrivateState | undefined
406
474
  /** Persisted settlement transaction bytes for exactly-once rebroadcast. */
@@ -434,6 +502,7 @@ export function toPublic(record: FundingDeposits.Record): Public {
434
502
  return schema.FundingDeposit.parse({
435
503
  ...record.snapshot,
436
504
  createdAt: record.createdAt,
505
+ ...(record.detectionTrigger === null ? {} : { detectionTrigger: record.detectionTrigger }),
437
506
  id: record.id,
438
507
  ...(record.sourceTransferIndex === null
439
508
  ? {}
@@ -83,7 +83,7 @@ describe('resolveRpcUrls', () => {
83
83
  })
84
84
 
85
85
  describe('createVerifier', () => {
86
- test('verifies finalized Solana and Tron token transfers', async () => {
86
+ test('verifies finalized Solana and one-confirmation Tron token transfers', async () => {
87
87
  const tron = TestFunding.depositAddressSnapshot()
88
88
  const solana = TestFunding.transferSnapshot({
89
89
  sourceChain: {
@@ -118,7 +118,7 @@ describe('createVerifier', () => {
118
118
  return
119
119
  }
120
120
  const result = request.url?.includes('getnowblock')
121
- ? { block_header: { raw_data: { number: 200 } } }
121
+ ? { block_header: { raw_data: { number: 150 } } }
122
122
  : request.url?.includes('gettransactioninfobyid')
123
123
  ? {
124
124
  blockNumber: 150,
@@ -14,6 +14,7 @@ const transferEvent = AbiEvent.from(
14
14
  )
15
15
  const transferTopic = AbiEvent.getSelector(transferEvent).slice(2)
16
16
  const catalogCacheTtlMs = 60_000
17
+ const defaultConfirmations = 1
17
18
 
18
19
  type SolanaRpcSchema = RpcSchema.From<{
19
20
  Request: {
@@ -117,7 +118,7 @@ export declare namespace resolveRpcUrls {
117
118
  }
118
119
  }
119
120
 
120
- /** Creates a finalized token-transfer verifier for EVM, Solana, and Tron chains. */
121
+ /** Creates a token-transfer verifier for EVM, Solana, and Tron chains. */
121
122
  export function createVerifier(options: createVerifier.Options): Reconciliation.VerifyTransfers {
122
123
  const fetch = options.fetch ?? globalThis.fetch
123
124
  // Delay this shared read until reconciliation releases its claim transaction.
@@ -156,15 +157,13 @@ export function createVerifier(options: createVerifier.Options): Reconciliation.
156
157
  if (!urls || urls.length === 0) throw new ChainConfigurationError(parameters.chain.id)
157
158
  if (parameters.chain.kind === 'evm')
158
159
  return verifyEvm(parameters, {
159
- confirmations:
160
- options.confirmations?.[parameters.chain.id] ?? options.defaultEvmConfirmations ?? 12,
160
+ confirmations: options.confirmations?.[parameters.chain.id] ?? defaultConfirmations,
161
161
  fetch,
162
162
  urls,
163
163
  })
164
164
  if (parameters.chain.kind === 'solana') return verifySolana(parameters, { fetch, urls })
165
165
  return verifyTron(parameters, {
166
- confirmations:
167
- options.confirmations?.[parameters.chain.id] ?? options.defaultTronConfirmations ?? 20,
166
+ confirmations: options.confirmations?.[parameters.chain.id] ?? defaultConfirmations,
168
167
  fetch,
169
168
  urls,
170
169
  })
@@ -180,10 +179,6 @@ export declare namespace createVerifier {
180
179
  db: Db.Source
181
180
  /** Tempo chain that receives a shared RPC URL override. */
182
181
  defaultChainId?: Viem.ChainId | undefined
183
- /** Default confirmation requirement for EVM chains. */
184
- defaultEvmConfirmations?: number | undefined
185
- /** Default confirmation requirement for Tron. */
186
- defaultTronConfirmations?: number | undefined
187
182
  /** Fetch implementation override for tests. */
188
183
  fetch?: typeof globalThis.fetch | undefined
189
184
  /** Shared or per-EVM-chain RPC URL environment value. */
@@ -249,6 +249,7 @@ export namespace schema {
249
249
  createdAt: z.iso.datetime(),
250
250
  destinationTransactionHashes: z.array(z.string()),
251
251
  id: z.string().check(z.minLength(1)),
252
+ providerState: z.optional(z.record(z.string(), z.unknown())),
252
253
  sourceTransactionHashes: z.array(z.string()),
253
254
  status: z.string().check(z.minLength(1)),
254
255
  updatedAt: z.iso.datetime(),
@@ -478,6 +479,68 @@ export declare namespace listDepositAddressRequests {
478
479
  type ReturnType = z.output<typeof schema.DepositAddressRequestsResult>
479
480
  }
480
481
 
482
+ /** Contract of the provider `observeDepositAddressRequest` method. */
483
+ export declare namespace observeDepositAddressRequest {
484
+ /** Verified source transfer used to correlate provider delivery. */
485
+ type Source = {
486
+ /** Token quantity in base units. */
487
+ amount: string
488
+ /** Verified source transaction reference. */
489
+ transactionHash: string
490
+ }
491
+
492
+ /** Input passed to a provider observing one pending reusable-address request. */
493
+ type Parameters = {
494
+ /** Provider-owned reusable deposit address. */
495
+ address: string
496
+ /** Chain that receives provider delivery. */
497
+ destinationChain: ChainRef
498
+ /** Token delivered by the provider. */
499
+ destinationToken: TokenRef
500
+ /** Bounded private provider correlation from an earlier observation. */
501
+ providerState?: Record<string, unknown> | undefined
502
+ /** Final beneficiary on the destination chain. */
503
+ recipient: string
504
+ /** Source-chain account credited by the provider deposit. */
505
+ refundAddress: string
506
+ /** Provider request, when the provider has indexed the source transfer. */
507
+ request?: listDepositAddressRequests.ReturnType['requests'][number] | undefined
508
+ /** One verified source transfer received by the deposit address. */
509
+ source: Source
510
+ /** Chain containing the source transfer. */
511
+ sourceChain: ChainRef
512
+ /** Token received by the reusable address. */
513
+ sourceToken: TokenRef
514
+ }
515
+
516
+ /** Private provider evidence shared by pending and verified observations. */
517
+ type Evidence = {
518
+ /** Bounded private provider correlation retained for reconciliation. */
519
+ providerState?: Record<string, unknown> | undefined
520
+ /** Verified provider-leg transaction references. */
521
+ providerTransactionHashes?: readonly string[] | undefined
522
+ }
523
+
524
+ /** Bounded provider delivery observation. */
525
+ type ReturnType = Evidence &
526
+ (
527
+ | {
528
+ /** No matching provider delivery has reached the destination yet. */
529
+ type: 'pending'
530
+ }
531
+ | {
532
+ /** This provider or route cannot produce authenticated delivery observations. */
533
+ type: 'unsupported'
534
+ }
535
+ | {
536
+ /** Verified destination transaction references. */
537
+ destinationTransactionHashes: readonly string[]
538
+ /** Authenticated provider delivery was observed onchain. */
539
+ type: 'verified'
540
+ }
541
+ )
542
+ }
543
+
481
544
  /** Optional webhook capability implemented by a complete funding integration. */
482
545
  export type Webhook = {
483
546
  /** Authenticates, resolves, and enqueues one provider status event. */
@@ -502,12 +565,46 @@ export declare namespace Webhook {
502
565
  type Dispatchable = {
503
566
  /** Stored funding deposit address id. */
504
567
  addressId: string
568
+ /** Bounded follow-up state for work awaiting provider or settlement confirmation. */
569
+ followUp?: FollowUp | undefined
505
570
  /** Reconciliation lease fencing token, when a scheduled poll already claimed the address. */
506
571
  pollLeaseVersion?: number | undefined
507
572
  /** Optional provider request id that triggered reconciliation. */
508
573
  requestId?: string | undefined
574
+ /** Mechanism that requested reconciliation. */
575
+ trigger: 'chain' | 'manual' | 'poll' | 'webhook'
509
576
  /** Reconciliation queue message discriminator. */
510
577
  type: 'funding:deposit-address:reconcile'
578
+ /** Authenticated provider webhook timing carried into reconciliation. */
579
+ webhookTiming?: WebhookTiming | undefined
580
+ }
581
+
582
+ /** Bounded follow-up state carried between delayed reconciliation messages. */
583
+ type FollowUp = {
584
+ /** Zero-based attempt in the current follow-up schedule. */
585
+ attempt: number
586
+ /** Work that still awaits confirmation. */
587
+ kind: 'delivery' | 'provider' | 'settlement'
588
+ }
589
+
590
+ /** Authenticated provider webhook timing used for latency measurement. */
591
+ type WebhookTiming = {
592
+ /** When Tempo sent the reconciliation message to its queue. */
593
+ enqueuedAt: string
594
+ /** Bounded provider status carried by the webhook. */
595
+ providerStatus: string
596
+ /** When the provider last changed the request status. */
597
+ providerUpdatedAt: string
598
+ /** When Tempo started processing the webhook request. */
599
+ receivedAt: string
600
+ /** When the provider sent the signed webhook. */
601
+ sentAt: string
602
+ }
603
+
604
+ /** Durable reconciliation message, including messages queued before trigger attribution. */
605
+ type Queued = Omit<Dispatchable, 'trigger'> & {
606
+ /** Mechanism that requested reconciliation, when written by a trigger-aware producer. */
607
+ trigger?: Dispatchable['trigger'] | undefined
511
608
  }
512
609
 
513
610
  /** Safe disposition of one authenticated funding provider webhook. */
@@ -526,8 +623,14 @@ export declare namespace Webhook {
526
623
  type ReturnType = {
527
624
  /** Reusable provider address, when the provider attributed one. */
528
625
  address?: string | undefined
626
+ /** Bounded provider status carried by the webhook. */
627
+ providerStatus?: string | undefined
628
+ /** When the provider last changed the request status. */
629
+ providerUpdatedAt?: string | undefined
529
630
  /** Provider request id, when included in the event. */
530
631
  requestId?: string | undefined
632
+ /** When the provider sent the signed webhook. */
633
+ sentAt?: string | undefined
531
634
  }
532
635
  }
533
636
  }
@@ -546,6 +649,11 @@ export type Provider<id extends string = string> = core_Provider.Provider<id, 'f
546
649
  input: listDepositAddressRequests.Parameters,
547
650
  signal: AbortSignal,
548
651
  ): Promise<listDepositAddressRequests.ReturnType>
652
+ /** Observes authenticated delivery for a verified reusable-address transfer, when supported. */
653
+ observeDepositAddressRequest?(
654
+ input: observeDepositAddressRequest.Parameters,
655
+ signal: AbortSignal,
656
+ ): Promise<observeDepositAddressRequest.ReturnType>
549
657
  /** Prepares an executable funding transfer, when the provider supports it. */
550
658
  prepareTransfer?(
551
659
  input: prepareTransfer.Parameters,
@@ -595,6 +703,13 @@ export function canListDepositAddressRequests(provider: Provider): provider is P
595
703
  return typeof provider.listDepositAddressRequests === 'function'
596
704
  }
597
705
 
706
+ /** Narrows a funding provider to one that observes reusable-address delivery onchain. */
707
+ export function canObserveDepositAddressRequest(provider: Provider): provider is Provider & {
708
+ observeDepositAddressRequest: NonNullable<Provider['observeDepositAddressRequest']>
709
+ } {
710
+ return typeof provider.observeDepositAddressRequest === 'function'
711
+ }
712
+
598
713
  /** Narrows a funding provider to one with authenticated webhook receipt. */
599
714
  export function canReceiveWebhook(provider: Provider): provider is Provider & {
600
715
  webhook: Webhook