tapimo 0.10.2 → 0.12.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 (386) hide show
  1. package/dist/App.d.ts +4896 -2166
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +2 -2
  4. package/dist/App.js.map +1 -1
  5. package/dist/Assets.d.ts +15 -0
  6. package/dist/Assets.d.ts.map +1 -1
  7. package/dist/Assets.js +7 -0
  8. package/dist/Assets.js.map +1 -1
  9. package/dist/Webhooks.d.ts +0 -75
  10. package/dist/Webhooks.d.ts.map +1 -1
  11. package/dist/Webhooks.js +1 -143
  12. package/dist/Webhooks.js.map +1 -1
  13. package/dist/admin/App.d.ts +127 -78
  14. package/dist/admin/App.d.ts.map +1 -1
  15. package/dist/admin/apps/earn-vaults.d.ts +115 -1
  16. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  17. package/dist/admin/apps/earn-vaults.js +59 -6
  18. package/dist/admin/apps/earn-vaults.js.map +1 -1
  19. package/dist/admin/apps/organizations.d.ts +3 -3
  20. package/dist/admin/apps/organizations.d.ts.map +1 -1
  21. package/dist/admin/apps/organizations.js +4 -2
  22. package/dist/admin/apps/organizations.js.map +1 -1
  23. package/dist/admin/apps/verified-tokens.d.ts +83 -83
  24. package/dist/admin/ui.generated.d.ts +1 -1
  25. package/dist/admin/ui.generated.d.ts.map +1 -1
  26. package/dist/admin/ui.generated.js +151 -151
  27. package/dist/admin/ui.generated.js.map +1 -1
  28. package/dist/apps/data/App.d.ts +5924 -4310
  29. package/dist/apps/data/App.d.ts.map +1 -1
  30. package/dist/apps/data/App.js +61 -9
  31. package/dist/apps/data/App.js.map +1 -1
  32. package/dist/apps/data/ZoneSelection.d.ts +62 -0
  33. package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
  34. package/dist/apps/data/ZoneSelection.js +44 -0
  35. package/dist/apps/data/ZoneSelection.js.map +1 -0
  36. package/dist/apps/data/routes/activities.d.ts +2368 -5
  37. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  38. package/dist/apps/data/routes/activities.js +423 -114
  39. package/dist/apps/data/routes/activities.js.map +1 -1
  40. package/dist/apps/data/routes/addresses.d.ts +131 -0
  41. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  42. package/dist/apps/data/routes/balances.d.ts +25 -25
  43. package/dist/apps/data/routes/balances.js +1 -1
  44. package/dist/apps/data/routes/balances.js.map +1 -1
  45. package/dist/apps/data/routes/blocks.d.ts +1 -1
  46. package/dist/apps/data/routes/blocks.js +1 -1
  47. package/dist/apps/data/routes/blocks.js.map +1 -1
  48. package/dist/apps/data/routes/earn.d.ts +135 -10
  49. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  50. package/dist/apps/data/routes/earn.js +157 -25
  51. package/dist/apps/data/routes/earn.js.map +1 -1
  52. package/dist/apps/data/routes/exchanges.d.ts +829 -123
  53. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  54. package/dist/apps/data/routes/exchanges.js +16 -13
  55. package/dist/apps/data/routes/exchanges.js.map +1 -1
  56. package/dist/apps/data/routes/fee-amm.d.ts +26 -26
  57. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  58. package/dist/apps/data/routes/fee-amm.js +9 -11
  59. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  60. package/dist/apps/data/routes/receipts.d.ts +54 -54
  61. package/dist/apps/data/routes/receipts.js +1 -1
  62. package/dist/apps/data/routes/receipts.js.map +1 -1
  63. package/dist/apps/data/routes/rpc.js +24 -10
  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/tokenlist.d.ts.map +1 -1
  67. package/dist/apps/data/routes/tokenlist.js +16 -15
  68. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  69. package/dist/apps/data/routes/tokens.d.ts +17 -3
  70. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  71. package/dist/apps/data/routes/tokens.js +34 -15
  72. package/dist/apps/data/routes/tokens.js.map +1 -1
  73. package/dist/apps/data/routes/transactions.d.ts +1 -1
  74. package/dist/apps/data/routes/transactions.js +1 -1
  75. package/dist/apps/data/routes/transactions.js.map +1 -1
  76. package/dist/apps/data/routes/transfers.d.ts +13 -13
  77. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  78. package/dist/apps/data/routes/transfers.js +7 -9
  79. package/dist/apps/data/routes/transfers.js.map +1 -1
  80. package/dist/apps/data/routes/valuation.d.ts +21 -21
  81. package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
  82. package/dist/apps/data/routes/webhooks.d.ts +1011 -151
  83. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  84. package/dist/apps/data/routes/webhooks.js +126 -739
  85. package/dist/apps/data/routes/webhooks.js.map +1 -1
  86. package/dist/apps/data/routes/zones.d.ts +15 -15
  87. package/dist/apps/funding/App.d.ts +27 -27
  88. package/dist/apps/funding/routes/chains.d.ts.map +1 -1
  89. package/dist/apps/funding/routes/chains.js +5 -4
  90. package/dist/apps/funding/routes/chains.js.map +1 -1
  91. package/dist/apps/funding/routes/deposit-addresses.d.ts +18 -18
  92. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  93. package/dist/apps/funding/routes/deposit-addresses.js +8 -8
  94. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  95. package/dist/apps/funding/routes/providers.d.ts.map +1 -1
  96. package/dist/apps/funding/routes/providers.js +3 -2
  97. package/dist/apps/funding/routes/providers.js.map +1 -1
  98. package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
  99. package/dist/apps/funding/routes/quotes.js +2 -2
  100. package/dist/apps/funding/routes/quotes.js.map +1 -1
  101. package/dist/apps/funding/routes/transfers.d.ts +33 -33
  102. package/dist/apps/management/App.d.ts +1433 -322
  103. package/dist/apps/management/App.d.ts.map +1 -1
  104. package/dist/apps/management/Billing.d.ts.map +1 -1
  105. package/dist/apps/management/Billing.js +19 -6
  106. package/dist/apps/management/Billing.js.map +1 -1
  107. package/dist/apps/management/routes/api-keys.d.ts +154 -94
  108. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  109. package/dist/apps/management/routes/api-keys.js +76 -30
  110. package/dist/apps/management/routes/api-keys.js.map +1 -1
  111. package/dist/apps/management/routes/billing.d.ts +103 -30
  112. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  113. package/dist/apps/management/routes/billing.js +91 -32
  114. package/dist/apps/management/routes/billing.js.map +1 -1
  115. package/dist/apps/management/routes/faucet.d.ts +12 -12
  116. package/dist/apps/management/routes/faucet.d.ts.map +1 -1
  117. package/dist/apps/management/routes/faucet.js +23 -12
  118. package/dist/apps/management/routes/faucet.js.map +1 -1
  119. package/dist/apps/management/routes/invitations.d.ts +46 -13
  120. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  121. package/dist/apps/management/routes/invitations.js +79 -29
  122. package/dist/apps/management/routes/invitations.js.map +1 -1
  123. package/dist/apps/management/routes/invite-links.d.ts +128 -83
  124. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  125. package/dist/apps/management/routes/invite-links.js +100 -41
  126. package/dist/apps/management/routes/invite-links.js.map +1 -1
  127. package/dist/apps/management/routes/me.d.ts +5 -5
  128. package/dist/apps/management/routes/me.d.ts.map +1 -1
  129. package/dist/apps/management/routes/me.js +14 -10
  130. package/dist/apps/management/routes/me.js.map +1 -1
  131. package/dist/apps/management/routes/members.d.ts +68 -47
  132. package/dist/apps/management/routes/members.d.ts.map +1 -1
  133. package/dist/apps/management/routes/members.js +37 -18
  134. package/dist/apps/management/routes/members.js.map +1 -1
  135. package/dist/apps/management/routes/orgs.d.ts +48 -8
  136. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  137. package/dist/apps/management/routes/orgs.js +48 -19
  138. package/dist/apps/management/routes/orgs.js.map +1 -1
  139. package/dist/apps/management/routes/projects.d.ts +130 -68
  140. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  141. package/dist/apps/management/routes/projects.js +72 -21
  142. package/dist/apps/management/routes/projects.js.map +1 -1
  143. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  144. package/dist/apps/management/routes/scopes.js +8 -5
  145. package/dist/apps/management/routes/scopes.js.map +1 -1
  146. package/dist/apps/management/routes/usage.d.ts +38 -38
  147. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  148. package/dist/apps/management/routes/usage.js +41 -31
  149. package/dist/apps/management/routes/usage.js.map +1 -1
  150. package/dist/apps/management/routes/verified-token-requests.d.ts +34 -6
  151. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  152. package/dist/apps/management/routes/verified-token-requests.js +36 -17
  153. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  154. package/dist/apps/management/routes/webhooks.d.ts +1186 -197
  155. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  156. package/dist/apps/management/routes/webhooks.js +106 -38
  157. package/dist/apps/management/routes/webhooks.js.map +1 -1
  158. package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
  159. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  160. package/dist/apps/mpp/internal/Adapter.js +12 -0
  161. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  162. package/dist/db/Db.d.ts +2 -0
  163. package/dist/db/Db.d.ts.map +1 -1
  164. package/dist/db/Db.js +61 -0
  165. package/dist/db/Db.js.map +1 -1
  166. package/dist/db/Schema.d.ts +30 -2
  167. package/dist/db/Schema.d.ts.map +1 -1
  168. package/dist/db/Schema.js +28 -3
  169. package/dist/db/Schema.js.map +1 -1
  170. package/dist/db/tables/earnVaults.d.ts +5 -1
  171. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  172. package/dist/db/tables/earnVaults.js +5 -0
  173. package/dist/db/tables/earnVaults.js.map +1 -1
  174. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
  175. package/dist/db/tables/webhookDeliveries.js +10 -0
  176. package/dist/db/tables/webhookDeliveries.js.map +1 -1
  177. package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
  178. package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
  179. package/dist/db/tables/webhookQueueCompletions.js +32 -0
  180. package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
  181. package/dist/db/tables/webhookQueueEvents.d.ts +16 -20
  182. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  183. package/dist/db/tables/webhookQueueEvents.js +68 -43
  184. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  185. package/dist/db/tables/webhookSubscriptions.d.ts +47 -72
  186. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  187. package/dist/db/tables/webhookSubscriptions.js +92 -105
  188. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  189. package/dist/internal/Auth.d.ts +8 -1
  190. package/dist/internal/Auth.d.ts.map +1 -1
  191. package/dist/internal/Auth.js +13 -3
  192. package/dist/internal/Auth.js.map +1 -1
  193. package/dist/internal/Cache.d.ts.map +1 -1
  194. package/dist/internal/Cache.js +11 -7
  195. package/dist/internal/Cache.js.map +1 -1
  196. package/dist/internal/EarnVaults.d.ts +41 -2
  197. package/dist/internal/EarnVaults.d.ts.map +1 -1
  198. package/dist/internal/EarnVaults.js +167 -0
  199. package/dist/internal/EarnVaults.js.map +1 -1
  200. package/dist/internal/MetricSink.d.ts +35 -125
  201. package/dist/internal/MetricSink.d.ts.map +1 -1
  202. package/dist/internal/MetricSink.js +50 -121
  203. package/dist/internal/MetricSink.js.map +1 -1
  204. package/dist/internal/OpenApi.d.ts +26 -22
  205. package/dist/internal/OpenApi.d.ts.map +1 -1
  206. package/dist/internal/OpenApi.js +128 -39
  207. package/dist/internal/OpenApi.js.map +1 -1
  208. package/dist/internal/Response.d.ts +13 -8
  209. package/dist/internal/Response.d.ts.map +1 -1
  210. package/dist/internal/Response.js +16 -5
  211. package/dist/internal/Response.js.map +1 -1
  212. package/dist/internal/Schema.d.ts +8 -8
  213. package/dist/internal/Schema.d.ts.map +1 -1
  214. package/dist/internal/Schema.js +10 -9
  215. package/dist/internal/Schema.js.map +1 -1
  216. package/dist/internal/Store.d.ts +15 -6
  217. package/dist/internal/Store.d.ts.map +1 -1
  218. package/dist/internal/Store.js +45 -15
  219. package/dist/internal/Store.js.map +1 -1
  220. package/dist/internal/Tidx.d.ts +2 -0
  221. package/dist/internal/Tidx.d.ts.map +1 -1
  222. package/dist/internal/Tidx.js +16 -4
  223. package/dist/internal/Tidx.js.map +1 -1
  224. package/dist/internal/WebhookTransfer.d.ts +1 -55
  225. package/dist/internal/WebhookTransfer.d.ts.map +1 -1
  226. package/dist/internal/WebhookTransfer.js +1 -239
  227. package/dist/internal/WebhookTransfer.js.map +1 -1
  228. package/dist/internal/Webhooks.d.ts +112 -56
  229. package/dist/internal/Webhooks.d.ts.map +1 -1
  230. package/dist/internal/Webhooks.js +124 -93
  231. package/dist/internal/Webhooks.js.map +1 -1
  232. package/dist/internal/funding/Deposit.d.ts +2 -2
  233. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  234. package/dist/internal/funding/Deposit.js +9 -8
  235. package/dist/internal/funding/Deposit.js.map +1 -1
  236. package/dist/internal/funding/DepositAddress.d.ts +4 -4
  237. package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
  238. package/dist/internal/funding/DepositAddress.js +9 -8
  239. package/dist/internal/funding/DepositAddress.js.map +1 -1
  240. package/dist/internal/funding/DepositWebhook.d.ts +25 -0
  241. package/dist/internal/funding/DepositWebhook.d.ts.map +1 -0
  242. package/dist/internal/funding/DepositWebhook.js +74 -0
  243. package/dist/internal/funding/DepositWebhook.js.map +1 -0
  244. package/dist/internal/funding/Provider.d.ts.map +1 -1
  245. package/dist/internal/funding/Provider.js +13 -12
  246. package/dist/internal/funding/Provider.js.map +1 -1
  247. package/dist/internal/funding/Reconciliation.d.ts +6 -0
  248. package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
  249. package/dist/internal/funding/Reconciliation.js +42 -10
  250. package/dist/internal/funding/Reconciliation.js.map +1 -1
  251. package/dist/internal/funding/index.d.ts +1 -0
  252. package/dist/internal/funding/index.d.ts.map +1 -1
  253. package/dist/internal/funding/index.js +1 -0
  254. package/dist/internal/funding/index.js.map +1 -1
  255. package/dist/internal/funding/providers/stargate.d.ts +19 -0
  256. package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
  257. package/dist/internal/funding/providers/stargate.js +143 -0
  258. package/dist/internal/funding/providers/stargate.js.map +1 -0
  259. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
  260. package/dist/internal/webhookDestinations/slack.js +16 -0
  261. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  262. package/dist/providers/index.d.ts +7 -0
  263. package/dist/providers/index.d.ts.map +1 -1
  264. package/dist/providers/index.js +3 -0
  265. package/dist/providers/index.js.map +1 -1
  266. package/package.json +2 -2
  267. package/src/App.test.ts +48 -0
  268. package/src/App.ts +7 -2
  269. package/src/Assets.test.ts +18 -0
  270. package/src/Assets.ts +22 -0
  271. package/src/Client.test-d.ts +287 -17
  272. package/src/Webhooks.ts +1 -220
  273. package/src/admin/apps/earn-vaults.test.ts +143 -0
  274. package/src/admin/apps/earn-vaults.ts +83 -6
  275. package/src/admin/apps/organizations.ts +6 -2
  276. package/src/admin/ui/src/routes/api-keys.tsx +36 -0
  277. package/src/admin/ui.generated.ts +151 -189
  278. package/src/apps/data/App.test.ts +31 -0
  279. package/src/apps/data/App.ts +64 -10
  280. package/src/apps/data/ZoneSelection.test.ts +196 -0
  281. package/src/apps/data/ZoneSelection.ts +108 -0
  282. package/src/apps/data/routes/activities.test.ts +435 -12
  283. package/src/apps/data/routes/activities.ts +562 -125
  284. package/src/apps/data/routes/balances.ts +1 -1
  285. package/src/apps/data/routes/blocks.ts +1 -1
  286. package/src/apps/data/routes/earn.test.ts +183 -23
  287. package/src/apps/data/routes/earn.ts +225 -29
  288. package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
  289. package/src/apps/data/routes/exchanges.test.ts +31 -1
  290. package/src/apps/data/routes/exchanges.ts +19 -15
  291. package/src/apps/data/routes/fee-amm.ts +18 -11
  292. package/src/apps/data/routes/receipts.ts +1 -1
  293. package/src/apps/data/routes/rpc.test.ts +75 -0
  294. package/src/apps/data/routes/rpc.ts +23 -9
  295. package/src/apps/data/routes/tokenlist.ts +21 -18
  296. package/src/apps/data/routes/tokens.test.ts +29 -0
  297. package/src/apps/data/routes/tokens.ts +38 -15
  298. package/src/apps/data/routes/transactions.ts +1 -1
  299. package/src/apps/data/routes/transfers.test.ts +3 -3
  300. package/src/apps/data/routes/transfers.ts +12 -9
  301. package/src/apps/data/routes/webhooks.test.ts +179 -1497
  302. package/src/apps/data/routes/webhooks.ts +156 -976
  303. package/src/apps/data/routes/zones.test.ts +19 -13
  304. package/src/apps/funding/routes/chains.test.ts +211 -7
  305. package/src/apps/funding/routes/chains.ts +19 -12
  306. package/src/apps/funding/routes/deposit-addresses.test.ts +394 -0
  307. package/src/apps/funding/routes/deposit-addresses.ts +84 -72
  308. package/src/apps/funding/routes/providers.ts +9 -5
  309. package/src/apps/funding/routes/quotes.test.ts +46 -0
  310. package/src/apps/funding/routes/quotes.ts +8 -5
  311. package/src/apps/funding/routes/transfers.test.ts +35 -32
  312. package/src/apps/management/Billing.test.ts +26 -0
  313. package/src/apps/management/Billing.ts +24 -7
  314. package/src/apps/management/routes/api-keys.test.ts +178 -0
  315. package/src/apps/management/routes/api-keys.ts +203 -144
  316. package/src/apps/management/routes/billing.test.ts +209 -0
  317. package/src/apps/management/routes/billing.ts +254 -177
  318. package/src/apps/management/routes/faucet.test.ts +39 -0
  319. package/src/apps/management/routes/faucet.ts +75 -41
  320. package/src/apps/management/routes/invitations.test.ts +216 -0
  321. package/src/apps/management/routes/invitations.ts +186 -109
  322. package/src/apps/management/routes/invite-links.test.ts +263 -1
  323. package/src/apps/management/routes/invite-links.ts +295 -214
  324. package/src/apps/management/routes/me.test.ts +49 -0
  325. package/src/apps/management/routes/me.ts +42 -32
  326. package/src/apps/management/routes/members.test.ts +124 -1
  327. package/src/apps/management/routes/members.ts +81 -51
  328. package/src/apps/management/routes/orgs.test.ts +176 -0
  329. package/src/apps/management/routes/orgs.ts +101 -59
  330. package/src/apps/management/routes/projects.test.ts +183 -0
  331. package/src/apps/management/routes/projects.ts +124 -60
  332. package/src/apps/management/routes/scopes.test.ts +44 -0
  333. package/src/apps/management/routes/scopes.ts +37 -28
  334. package/src/apps/management/routes/usage.test.ts +92 -0
  335. package/src/apps/management/routes/usage.ts +186 -151
  336. package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
  337. package/src/apps/management/routes/verified-token-requests.ts +166 -133
  338. package/src/apps/management/routes/webhooks.test.ts +313 -1
  339. package/src/apps/management/routes/webhooks.ts +220 -71
  340. package/src/apps/mpp/internal/Adapter.ts +13 -1
  341. package/src/db/Db.test.ts +42 -5
  342. package/src/db/Db.ts +85 -0
  343. package/src/db/Schema.ts +41 -3
  344. package/src/db/tables/earnVaults.test.ts +22 -0
  345. package/src/db/tables/earnVaults.ts +11 -1
  346. package/src/db/tables/organizations.test.ts +5 -2
  347. package/src/db/tables/webhookDeliveries.ts +13 -0
  348. package/src/db/tables/webhookQueueCompletions.ts +55 -0
  349. package/src/db/tables/webhookQueueEvents.ts +97 -57
  350. package/src/db/tables/webhookSubscriptions.ts +134 -144
  351. package/src/internal/Auth.ts +23 -5
  352. package/src/internal/Cache.ts +14 -7
  353. package/src/internal/EarnVaults.capabilities.test.ts +33 -0
  354. package/src/internal/EarnVaults.test.ts +79 -0
  355. package/src/internal/EarnVaults.ts +277 -0
  356. package/src/internal/MetricSink.test.ts +41 -373
  357. package/src/internal/MetricSink.ts +92 -273
  358. package/src/internal/OpenApi.ts +165 -49
  359. package/src/internal/Response.test.ts +95 -0
  360. package/src/internal/Response.ts +40 -2
  361. package/src/internal/Schema.test.ts +34 -0
  362. package/src/internal/Schema.ts +20 -9
  363. package/src/internal/Store.test.ts +186 -0
  364. package/src/internal/Store.ts +57 -17
  365. package/src/internal/Tidx.test.ts +19 -0
  366. package/src/internal/Tidx.ts +16 -4
  367. package/src/internal/WebhookTransfer.ts +1 -351
  368. package/src/internal/Webhooks.test.ts +222 -145
  369. package/src/internal/Webhooks.ts +234 -135
  370. package/src/internal/funding/Deposit.ts +71 -64
  371. package/src/internal/funding/DepositAddress.ts +50 -43
  372. package/src/internal/funding/DepositWebhook.test.ts +131 -0
  373. package/src/internal/funding/DepositWebhook.ts +101 -0
  374. package/src/internal/funding/Provider.ts +164 -142
  375. package/src/internal/funding/Reconciliation.test.ts +14 -0
  376. package/src/internal/funding/Reconciliation.ts +161 -86
  377. package/src/internal/funding/index.test.ts +1 -0
  378. package/src/internal/funding/index.ts +1 -0
  379. package/src/internal/funding/providers/index.test.ts +185 -0
  380. package/src/internal/funding/providers/stargate.ts +184 -0
  381. package/src/internal/webhookDestinations/slack.ts +15 -0
  382. package/src/providers/index.test.ts +1 -0
  383. package/src/providers/index.ts +9 -0
  384. package/src/Webhooks.bench.ts +0 -714
  385. package/src/Webhooks.memory.bench.ts +0 -250
  386. package/src/Webhooks.test.ts +0 -146
@@ -149,6 +149,37 @@ describe('MPP session management', () => {
149
149
  PaymentRequest.serialize({ _mppx_scope: 'GET /v1/scopes' }),
150
150
  )
151
151
  })
152
+
153
+ test('applies POST auth overrides to QUERY aliases', async () => {
154
+ const app = TestApp.create({
155
+ auth: {
156
+ overrides: {
157
+ 'POST /v1/exchange/quotes': { mpp: false, public: false },
158
+ },
159
+ },
160
+ })
161
+
162
+ const post = await app.request('/v1/exchange/quotes', { method: 'POST' })
163
+ const query = await app.request('/v1/exchange/quotes', { method: 'QUERY' })
164
+
165
+ expect([post.status, query.status]).toEqual([401, 401])
166
+ })
167
+
168
+ test('prefers an explicit QUERY auth override', async () => {
169
+ const app = TestApp.create({
170
+ auth: {
171
+ overrides: {
172
+ 'POST /v1/exchange/quotes': { mpp: false, public: false },
173
+ 'QUERY /v1/exchange/quotes': false,
174
+ },
175
+ },
176
+ })
177
+
178
+ const post = await app.request('/v1/exchange/quotes', { method: 'POST' })
179
+ const query = await app.request('/v1/exchange/quotes', { method: 'QUERY' })
180
+
181
+ expect([post.status, query.status]).toEqual([401, 400])
182
+ })
152
183
  })
153
184
 
154
185
  describe('zone chain gate', () => {
@@ -3,7 +3,7 @@ import { matchedRoutes } from 'hono/route'
3
3
  import { ZoneRpcAuthentication } from 'ox/tempo'
4
4
  import * as z from 'zod/mini'
5
5
 
6
- import type * as Assets from '../../Assets.js'
6
+ import * as Assets from '../../Assets.js'
7
7
  import type * as App from '../../App.js'
8
8
  import * as Auth from '../../internal/Auth.js'
9
9
  import * as EdgeCache from '../../internal/EdgeCache.js'
@@ -17,6 +17,7 @@ import * as Scope from '../../Scope.js'
17
17
  import * as Metadata from '../metadata.js'
18
18
 
19
19
  import type * as FxOracle from './FxOracle.js'
20
+ import * as ZoneSelection from './ZoneSelection.js'
20
21
 
21
22
  import { transactions as transactionActivities } from './routes/activities.js'
22
23
  import { addresses } from './routes/addresses.js'
@@ -58,9 +59,17 @@ export function data(options: data.Options = {}) {
58
59
  const dataRouteHandlers = new Set<unknown>()
59
60
 
60
61
  const getTidx = Tidx.createGetClient({ tidx })
62
+ const addresses_routes = addresses({ fx: options.fx })
61
63
  const earn_routes = earn({ fx: options.fx })
62
64
  const indexer_routes = indexer()
65
+ const transactionActivities_routes = transactionActivities({ fx: options.fx })
63
66
  const indexerRouteHandlers = new Set(indexer_routes.routes.map((route) => route.handler))
67
+ const inferredZoneRouteHandlers = new Set([
68
+ ...addresses_routes.routes
69
+ .filter((route) => route.path === '/v1/addresses/:address/activities')
70
+ .map((route) => route.handler),
71
+ ...transactionActivities_routes.routes.map((route) => route.handler),
72
+ ])
64
73
  const rpcOnlyRouteHandlers = new Set(
65
74
  earn_routes.routes
66
75
  .filter((route) => route.path === '/v1/earn/vaults/:vaultId/positions/:address')
@@ -106,6 +115,7 @@ export function data(options: data.Options = {}) {
106
115
  c,
107
116
  defaultChainId,
108
117
  handlers: dataRouteHandlers,
118
+ inferredZoneHandlers: inferredZoneRouteHandlers,
109
119
  indexerHandlers: indexerRouteHandlers,
110
120
  rpcOnlyHandlers: rpcOnlyRouteHandlers,
111
121
  })
@@ -120,6 +130,30 @@ export function data(options: data.Options = {}) {
120
130
  const rpc_config = c.get('rpc')
121
131
  const tidx_config = c.get('tidx')
122
132
  const zones = c.get('zones')
133
+ if (selection.inferredZones) {
134
+ if (principal?.type !== 'api_key')
135
+ return Response.error(c, {
136
+ code: 'api_key_forbidden',
137
+ message: '`include=zones` requires an API key with readable Zone scopes.',
138
+ status: 403,
139
+ })
140
+ const zoneChainIds = ZoneSelection.readableChainIds({
141
+ parentChainId: selection.chainId,
142
+ principal,
143
+ rpc: rpc_config,
144
+ tidx: tidx_config,
145
+ zones,
146
+ })
147
+ if (zoneChainIds.length === 0)
148
+ return Response.error(c, {
149
+ code: 'api_key_forbidden',
150
+ message: 'The API key has no readable configured Zones.',
151
+ status: 403,
152
+ })
153
+ c.set('supportedChainIds', new Set(zoneChainIds))
154
+ c.set('zoneChainIds', zoneChainIds)
155
+ return next()
156
+ }
123
157
  // Raw passthroughs and RPC-only reads need only RPC; composed data routes
124
158
  // require both upstreams to avoid falling through to unrelated defaults.
125
159
  const narrowedChainIds = new Set(
@@ -147,10 +181,12 @@ export function data(options: data.Options = {}) {
147
181
  c,
148
182
  defaultChainId: c.get('chainId'),
149
183
  handlers: dataRouteHandlers,
184
+ inferredZoneHandlers: inferredZoneRouteHandlers,
150
185
  indexerHandlers: indexerRouteHandlers,
151
186
  rpcOnlyHandlers: rpcOnlyRouteHandlers,
152
187
  })
153
188
  if (!selection.matched) return next()
189
+ if (selection.inferredZones) return next()
154
190
  const chainId = c.get('chainId')
155
191
  if (!zones.has(chainId)) return next()
156
192
 
@@ -187,10 +223,12 @@ export function data(options: data.Options = {}) {
187
223
  c,
188
224
  defaultChainId: c.get('chainId'),
189
225
  handlers: dataRouteHandlers,
226
+ inferredZoneHandlers: inferredZoneRouteHandlers,
190
227
  indexerHandlers: indexerRouteHandlers,
191
228
  rpcOnlyHandlers: rpcOnlyRouteHandlers,
192
229
  })
193
- if (!selection.matched || !Viem.isMainnet(c.get('chainId'))) return next()
230
+ if (!selection.matched || selection.inferredZones || !Viem.isMainnet(c.get('chainId')))
231
+ return next()
194
232
 
195
233
  return Response.error(c, {
196
234
  code: 'api_key_forbidden',
@@ -211,7 +249,7 @@ export function data(options: data.Options = {}) {
211
249
  'Content-Type': asset.contentType,
212
250
  })
213
251
  })
214
- .route('/', addresses({ fx: options.fx }))
252
+ .route('/', addresses_routes)
215
253
  .route('/', blocks())
216
254
  .route('/', earn_routes)
217
255
  .route('/', exchanges({ fx: options.fx }))
@@ -221,10 +259,16 @@ export function data(options: data.Options = {}) {
221
259
  .route('/', tokenlist())
222
260
  .route('/', tokens())
223
261
  .route('/', transactions())
224
- .route('/', transactionActivities({ fx: options.fx }))
262
+ .route('/', transactionActivities_routes)
225
263
  .route('/', transfers({ fx: options.fx }))
226
264
  .route('/', verifiedTokens())
227
- .route('/', webhooks({ enabled: options.webhook !== false }))
265
+ .route(
266
+ '/',
267
+ webhooks({
268
+ applicationEventTypes: webhook?.applicationEventTypes ?? [],
269
+ enabled: options.webhook !== false,
270
+ }),
271
+ )
228
272
  .route('/', zones())
229
273
  .route('/', rpc())
230
274
  .route('/', coingecko())
@@ -234,14 +278,16 @@ export function data(options: data.Options = {}) {
234
278
  c,
235
279
  defaultChainId: c.get('chainId'),
236
280
  handlers: dataRouteHandlers,
281
+ inferredZoneHandlers: inferredZoneRouteHandlers,
237
282
  indexerHandlers: indexerRouteHandlers,
238
283
  rpcOnlyHandlers: rpcOnlyRouteHandlers,
239
284
  })
240
- if (selection.matched && !selection.conflict && !selection.invalid)
285
+ if (selection.matched && !selection.conflict && !selection.inferredZones && !selection.invalid)
241
286
  c.set('chainId', selection.chainId)
242
287
  return (
243
288
  selection.matched &&
244
289
  !selection.conflict &&
290
+ !selection.inferredZones &&
245
291
  !selection.invalid &&
246
292
  !c.get('zones').has(selection.chainId)
247
293
  )
@@ -296,6 +342,7 @@ function resolveChainSelector(options: {
296
342
  c: Context<App.Environment>
297
343
  defaultChainId: Viem.ChainId
298
344
  handlers: ReadonlySet<unknown>
345
+ inferredZoneHandlers: ReadonlySet<unknown>
299
346
  indexerHandlers: ReadonlySet<unknown>
300
347
  rpcOnlyHandlers: ReadonlySet<unknown>
301
348
  }) {
@@ -304,9 +351,11 @@ function resolveChainSelector(options: {
304
351
  let rpc = false
305
352
  let rpcOnly = false
306
353
  let indexer = false
354
+ let inferredZonesAllowed = false
307
355
  for (const route of matchedRoutes(options.c)) {
308
356
  if (!options.handlers.has(route.handler)) continue
309
357
  matched = true
358
+ if (options.inferredZoneHandlers.has(route.handler)) inferredZonesAllowed = true
310
359
  if (options.indexerHandlers.has(route.handler)) indexer = true
311
360
  if (options.rpcOnlyHandlers.has(route.handler)) rpcOnly = true
312
361
  const selector = pathChainSelector(route.path, options.c.req.path)
@@ -320,6 +369,7 @@ function resolveChainSelector(options: {
320
369
  return {
321
370
  chainId: options.defaultChainId,
322
371
  conflict: false,
372
+ inferredZones: false,
323
373
  indexer: false,
324
374
  invalid: false,
325
375
  matched: false,
@@ -328,6 +378,10 @@ function resolveChainSelector(options: {
328
378
  }
329
379
 
330
380
  const search = new URL(options.c.req.url).searchParams
381
+ const include = inferredZonesAllowed
382
+ ? search.getAll('include').flatMap((value) => value.split(',').map((part) => part.trim()))
383
+ : []
384
+ const inferredZones = include.includes('zones')
331
385
  const raw = [
332
386
  ...(path === undefined ? [] : [path]),
333
387
  ...(rpc ? [] : search.getAll('chainId')),
@@ -338,6 +392,7 @@ function resolveChainSelector(options: {
338
392
  return {
339
393
  chainId: chainIds[0] ?? options.defaultChainId,
340
394
  conflict: chainIds.length > 1,
395
+ inferredZones,
341
396
  indexer,
342
397
  invalid: parsed.some((result) => !result.success),
343
398
  matched: true,
@@ -445,7 +500,7 @@ function webhooksBlock() {
445
500
  'tempo-event-id',
446
501
  'A unique, stable id for this event (`evt_…`). The same event may be delivered more than once, so use this id to skip duplicates.',
447
502
  ),
448
- header('tempo-event-type', 'What happened: `token:transfer`, `transaction:included`, `log:emitted`, `block:created`, or `ping`.'), // prettier-ignore
503
+ header('tempo-event-type', 'What happened: `token:transfer`, `transaction:included`, `log:emitted`, `block:created`, `funding:deposit.updated`, or `ping`.'), // prettier-ignore
449
504
  ],
450
505
  requestBody: {
451
506
  content: { 'application/json': { schema: envelope } },
@@ -467,7 +522,6 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
467
522
  const { assets, basePath, origin } = options
468
523
  if (!assets) return () => undefined
469
524
  const getAsset: App.GetAsset = async (chainId, path) => {
470
- const pathname = Path.join(basePath, 'assets', String(chainId), path)
471
525
  // `path` may be absolute (`Path.join` returns a leading slash); strip it so
472
526
  // the key is `:chainId/:path`, not `:chainId//:path`.
473
527
  const key = `${chainId}/${path.replace(/^\/+/, '')}`
@@ -477,7 +531,7 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
477
531
  response: new globalThis.Response(asset.body, {
478
532
  headers: { 'Content-Type': asset.contentType },
479
533
  }),
480
- uri: new URL(pathname, origin).toString(),
534
+ uri: Assets.url({ basePath, chainId, origin, path }),
481
535
  }
482
536
  }
483
537
  const list = assets.list
@@ -486,7 +540,7 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
486
540
  const prefix = `${chainId}/${path.replace(/^\/+/, '')}`
487
541
  return (await list(prefix)).map((key) => ({
488
542
  key,
489
- uri: new URL(Path.join(basePath, 'assets', key), origin).toString(),
543
+ uri: Assets.url({ basePath, chainId, origin, path: key.slice(String(chainId).length + 1) }),
490
544
  }))
491
545
  }
492
546
  return getAsset
@@ -0,0 +1,196 @@
1
+ import * as ApiKey from '../../ApiKey.js'
2
+ import * as App from '../../App.js'
3
+ import * as Db from '../../db/Db.js'
4
+ import type * as Auth from '../../internal/Auth.js'
5
+ import * as Viem from '../../internal/Viem.js'
6
+ import * as Zones from '../Zones.js'
7
+
8
+ import * as Data from './App.js'
9
+ import * as ZoneSelection from './ZoneSelection.js'
10
+ import * as Activities from './routes/activities.js'
11
+
12
+ describe('transaction activity Zone query', () => {
13
+ test('accepts the Zones include with an optional parent chain', () => {
14
+ expect(
15
+ Activities.schema.getTransactionActivities.Query.parse({ include: 'zones' }).include,
16
+ ).toStrictEqual(['zones'])
17
+ expect(
18
+ Activities.schema.getTransactionActivities.Query.parse({
19
+ chainId: '4217',
20
+ include: 'zones',
21
+ }),
22
+ ).toMatchObject({ chainId: 4217, include: ['zones'] })
23
+ expect(
24
+ Activities.schema.getTransactionActivities.Query.safeParse({ includeZones: 'true' }).success,
25
+ ).toBe(false)
26
+ })
27
+
28
+ test('opts in only activity routes and accepts a parent chain', async () => {
29
+ const app = App.create({
30
+ auth: false,
31
+ db: Db.postgres({ connectionString: 'postgresql://unused@127.0.0.1:1/unused' }),
32
+ zones: [Zones.zoneModeratoInternal],
33
+ }).route('/', Data.data({ webhook: false }))
34
+ const address = '0x0000000000000000000000000000000000000001'
35
+ const hash = `0x${'00'.repeat(32)}`
36
+ const addressScoped = await app.request(
37
+ `/v1/addresses/${address}/activities?include=zones&chainId=${Viem.chainId.testnet}`,
38
+ )
39
+ const forbidden = await app.request(`/v1/transactions/${hash}/activities?include=zones`)
40
+ const scoped = await app.request(
41
+ `/v1/transactions/${hash}/activities?include=zones&chainId=${Viem.chainId.testnet}`,
42
+ )
43
+ const unsupported = await app.request('/v1/tokenlist?include=zones')
44
+
45
+ expect(forbidden.status).toBe(403)
46
+ expect(forbidden.headers.get('cache-control')).toBe('no-store')
47
+ expect(await addressScoped.json()).toMatchObject({ error: { code: 'api_key_forbidden' } })
48
+ expect(await scoped.json()).toMatchObject({ error: { code: 'api_key_forbidden' } })
49
+ expect(await unsupported.json()).toMatchObject({ error: { code: 'query_invalid' } })
50
+ })
51
+ })
52
+
53
+ describe('readableChainIds', () => {
54
+ test('intersects the parent chain, scopes, and configured routable Zones', () => {
55
+ const principal = apiKeyPrincipal({
56
+ scopes: [
57
+ 'data:read',
58
+ `zone:${Zones.zoneMainnetInternal.id}:read`,
59
+ `zone:${Zones.zoneModeratoInternal.id}:write`,
60
+ ],
61
+ })
62
+
63
+ expect(
64
+ ZoneSelection.readableChainIds({
65
+ parentChainId: Viem.chainId.testnet,
66
+ principal,
67
+ zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
68
+ }),
69
+ ).toStrictEqual([Zones.zoneModeratoInternal.id])
70
+ expect(
71
+ ZoneSelection.readableChainIds({
72
+ parentChainId: Viem.chainId.mainnet,
73
+ principal,
74
+ zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
75
+ }),
76
+ ).toStrictEqual([Zones.zoneMainnetInternal.id])
77
+ })
78
+
79
+ test('lets wildcard keys read every configured routable Zone of the parent chain', () => {
80
+ expect(
81
+ ZoneSelection.readableChainIds({
82
+ parentChainId: Viem.chainId.testnet,
83
+ principal: apiKeyPrincipal({ scopes: ['*'] }),
84
+ zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
85
+ }),
86
+ ).toStrictEqual([Zones.zoneModeratoInternal.id])
87
+ })
88
+
89
+ test('filters sandbox keys by each Zone parent chain', () => {
90
+ const principal = apiKeyPrincipal({
91
+ environment: 'sandbox',
92
+ scopes: [
93
+ 'data:read',
94
+ `zone:${Zones.zoneMainnetInternal.id}:read`,
95
+ `zone:${Zones.zoneModeratoInternal.id}:read`,
96
+ ],
97
+ })
98
+
99
+ expect(
100
+ ZoneSelection.readableChainIds({
101
+ parentChainId: Viem.chainId.testnet,
102
+ principal,
103
+ zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
104
+ }),
105
+ ).toStrictEqual([Zones.zoneModeratoInternal.id])
106
+ expect(
107
+ ZoneSelection.readableChainIds({
108
+ parentChainId: Viem.chainId.mainnet,
109
+ principal,
110
+ zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
111
+ }),
112
+ ).toStrictEqual([])
113
+ })
114
+
115
+ test('requires data read access and both upstreams', () => {
116
+ const zone = {
117
+ ...Zones.zoneModeratoInternal,
118
+ id: 1_424_310_099,
119
+ rpcUrls: { default: { http: ['https://zone.rpc.test'] } },
120
+ }
121
+ const zones = new Map([[zone.id, zone]])
122
+
123
+ expect(
124
+ ZoneSelection.readableChainIds({
125
+ parentChainId: zone.sourceId,
126
+ principal: apiKeyPrincipal({ scopes: [`zone:${zone.id}:read`] }),
127
+ zones,
128
+ }),
129
+ ).toStrictEqual([])
130
+ expect(
131
+ ZoneSelection.readableChainIds({
132
+ parentChainId: zone.sourceId,
133
+ principal: apiKeyPrincipal({ scopes: ['data:read', `zone:${zone.id}:read`] }),
134
+ zones,
135
+ }),
136
+ ).toStrictEqual([])
137
+ })
138
+ })
139
+
140
+ describe('uniqueMatch', () => {
141
+ test('selects one match after every Zone completes', () => {
142
+ expect(
143
+ ZoneSelection.uniqueMatch([
144
+ { chainId: 1, value: null },
145
+ { chainId: 2, value: 'receipt' },
146
+ ]),
147
+ ).toStrictEqual({ chainId: 2, kind: 'selected', value: 'receipt' })
148
+ })
149
+
150
+ test('distinguishes no match from ambiguous matches', () => {
151
+ expect(ZoneSelection.uniqueMatch([{ chainId: 1, value: null }])).toStrictEqual({
152
+ kind: 'not_found',
153
+ })
154
+ expect(
155
+ ZoneSelection.uniqueMatch([
156
+ { chainId: 1, value: 'first' },
157
+ { chainId: 2, value: 'second' },
158
+ ]),
159
+ ).toStrictEqual({ kind: 'ambiguous' })
160
+ })
161
+
162
+ test('fails the selection when any Zone lookup fails', () => {
163
+ const cause = new Error('unavailable')
164
+ expect(
165
+ ZoneSelection.uniqueMatch([
166
+ { chainId: 1, value: 'receipt' },
167
+ { cause, chainId: 2 },
168
+ ]),
169
+ ).toStrictEqual({ failures: [{ cause, chainId: 2 }], kind: 'failed' })
170
+ })
171
+ })
172
+
173
+ function apiKeyPrincipal(
174
+ options: apiKeyPrincipal.Options,
175
+ ): Extract<Auth.Principal, { type: 'api_key' }> {
176
+ const apiKey = ApiKey.schema.ApiKey.parse({
177
+ environment: options.environment,
178
+ id: 'key_test',
179
+ orgId: 'org_test',
180
+ scopes: options.scopes,
181
+ })
182
+ return {
183
+ apiKey,
184
+ environment: apiKey.environment,
185
+ id: apiKey.id,
186
+ orgId: apiKey.orgId,
187
+ type: 'api_key',
188
+ }
189
+ }
190
+
191
+ declare namespace apiKeyPrincipal {
192
+ type Options = {
193
+ environment?: 'production' | 'sandbox' | undefined
194
+ scopes: readonly string[]
195
+ }
196
+ }
@@ -0,0 +1,108 @@
1
+ import type { Chain } from 'viem'
2
+
3
+ import type * as Auth from '../../internal/Auth.js'
4
+ import * as Tidx from '../../internal/Tidx.js'
5
+ import * as Viem from '../../internal/Viem.js'
6
+ import * as Scope from '../../Scope.js'
7
+
8
+ /** Returns configured and routable Zones that an API key may read. */
9
+ export function readableChainIds(options: readableChainIds.Options): readonly number[] {
10
+ const { parentChainId, principal, zones } = options
11
+ const scopes = principal.apiKey.scopes
12
+ if (!scopes.includes(Scope.wildcard) && !scopes.includes('data:read')) return []
13
+
14
+ const chainIds = [...zones.values()].flatMap((zone) => {
15
+ if (zone.sourceId !== parentChainId) return []
16
+ const allowed =
17
+ scopes.includes(Scope.wildcard) ||
18
+ scopes.includes(`zone:${zone.id}:read`) ||
19
+ scopes.includes(`zone:${zone.id}:write`)
20
+ if (!allowed) return []
21
+ if (
22
+ principal.environment === 'sandbox' &&
23
+ (zone.sourceId === undefined || Viem.isMainnet(zone.sourceId))
24
+ )
25
+ return []
26
+
27
+ const context = { chainId: zone.id, principal, zone }
28
+ if (Viem.resolveRpc(options.rpc, context).url === undefined) return []
29
+ if (Tidx.resolve(options.tidx, context).baseUrl === undefined) return []
30
+ return [zone.id]
31
+ })
32
+ return chainIds.sort((a, b) => a - b)
33
+ }
34
+
35
+ export declare namespace readableChainIds {
36
+ /** Inputs for resolving the readable inferred-Zone set. */
37
+ type Options = {
38
+ /** Parent Tempo chain whose Zones may be selected. */
39
+ parentChainId: Viem.ChainId
40
+ /** Authenticated API-key principal selecting Zones. */
41
+ principal: Extract<Auth.Principal, { type: 'api_key' }>
42
+ /** RPC configuration used to exclude unroutable Zones. */
43
+ rpc?: Viem.getClient.Rpc | undefined
44
+ /** TIDX configuration used to exclude unroutable Zones. */
45
+ tidx?: Tidx.getClient.Tidx | undefined
46
+ /** Hosted Zone metadata keyed by chain id. */
47
+ zones: ReadonlyMap<number, Chain>
48
+ }
49
+ }
50
+
51
+ /** Resolves receipt probes without treating partial upstream results as complete. */
52
+ export function uniqueMatch<const value>(
53
+ probes: readonly uniqueMatch.Probe<value>[],
54
+ ): uniqueMatch.Result<value> {
55
+ const failures = probes.flatMap((probe) => ('cause' in probe ? [probe] : []))
56
+ if (failures.length > 0) return { failures, kind: 'failed' }
57
+
58
+ const matches = probes.flatMap((probe) =>
59
+ 'value' in probe && probe.value !== null
60
+ ? [{ chainId: probe.chainId, value: probe.value }]
61
+ : [],
62
+ )
63
+ if (matches.length === 0) return { kind: 'not_found' }
64
+ if (matches.length > 1) return { kind: 'ambiguous' }
65
+ return { ...matches[0]!, kind: 'selected' }
66
+ }
67
+
68
+ export declare namespace uniqueMatch {
69
+ /** One completed Zone lookup. */
70
+ type Probe<value> =
71
+ | {
72
+ /** Zone that completed the lookup. */
73
+ chainId: number
74
+ /** Matching value, or null when the Zone did not contain the resource. */
75
+ value: value | null
76
+ }
77
+ | {
78
+ /** Upstream failure from this Zone. */
79
+ cause: unknown
80
+ /** Zone that failed the lookup. */
81
+ chainId: number
82
+ }
83
+
84
+ /** Unique-match decision across every requested Zone. */
85
+ type Result<value> =
86
+ | {
87
+ /** Zone containing the unique match. */
88
+ chainId: number
89
+ /** Unique match result. */
90
+ kind: 'selected'
91
+ /** Value found in the selected Zone. */
92
+ value: value
93
+ }
94
+ | {
95
+ /** Every failed Zone lookup. */
96
+ failures: readonly Extract<Probe<value>, { cause: unknown }>[]
97
+ /** Partial failure result. */
98
+ kind: 'failed'
99
+ }
100
+ | {
101
+ /** Ambiguous match result. */
102
+ kind: 'ambiguous'
103
+ }
104
+ | {
105
+ /** No-match result. */
106
+ kind: 'not_found'
107
+ }
108
+ }