tapimo 0.5.3 → 0.7.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 (376) hide show
  1. package/dist/App.d.ts +15830 -7220
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +9 -1
  4. package/dist/App.js.map +1 -1
  5. package/dist/Scope.d.ts +4 -0
  6. package/dist/Scope.d.ts.map +1 -1
  7. package/dist/Scope.js +5 -0
  8. package/dist/Scope.js.map +1 -1
  9. package/dist/admin/App.d.ts +1011 -412
  10. package/dist/admin/App.d.ts.map +1 -1
  11. package/dist/admin/App.js +4 -0
  12. package/dist/admin/App.js.map +1 -1
  13. package/dist/admin/apps/api-keys.d.ts +2 -1
  14. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  15. package/dist/admin/apps/early-access.d.ts +148 -0
  16. package/dist/admin/apps/early-access.d.ts.map +1 -0
  17. package/dist/admin/apps/early-access.js +133 -0
  18. package/dist/admin/apps/early-access.js.map +1 -0
  19. package/dist/admin/apps/organizations.d.ts +124 -1
  20. package/dist/admin/apps/organizations.d.ts.map +1 -1
  21. package/dist/admin/apps/organizations.js +97 -6
  22. package/dist/admin/apps/organizations.js.map +1 -1
  23. package/dist/admin/apps/verified-tokens.d.ts +526 -1
  24. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  25. package/dist/admin/apps/verified-tokens.js +214 -1
  26. package/dist/admin/apps/verified-tokens.js.map +1 -1
  27. package/dist/admin/ui.generated.d.ts +1 -1
  28. package/dist/admin/ui.generated.d.ts.map +1 -1
  29. package/dist/admin/ui.generated.js +95 -75
  30. package/dist/admin/ui.generated.js.map +1 -1
  31. package/dist/analytics/Analytics.d.ts.map +1 -1
  32. package/dist/analytics/Analytics.js +20 -0
  33. package/dist/analytics/Analytics.js.map +1 -1
  34. package/dist/analytics/tables/requestEvents.d.ts +18 -0
  35. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  36. package/dist/analytics/tables/requestEvents.js +36 -7
  37. package/dist/analytics/tables/requestEvents.js.map +1 -1
  38. package/dist/apps/data/App.d.ts +6260 -4924
  39. package/dist/apps/data/App.d.ts.map +1 -1
  40. package/dist/apps/data/App.js +11 -6
  41. package/dist/apps/data/App.js.map +1 -1
  42. package/dist/apps/data/FundingQuoteProviders.d.ts +34 -1
  43. package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -1
  44. package/dist/apps/data/FundingQuoteProviders.js +194 -16
  45. package/dist/apps/data/FundingQuoteProviders.js.map +1 -1
  46. package/dist/apps/data/FxOracle.d.ts +71 -0
  47. package/dist/apps/data/FxOracle.d.ts.map +1 -0
  48. package/dist/apps/data/FxOracle.js +97 -0
  49. package/dist/apps/data/FxOracle.js.map +1 -0
  50. package/dist/apps/data/index.d.ts +1 -0
  51. package/dist/apps/data/index.d.ts.map +1 -1
  52. package/dist/apps/data/index.js +1 -0
  53. package/dist/apps/data/index.js.map +1 -1
  54. package/dist/apps/data/routes/activities.d.ts +3599 -1382
  55. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  56. package/dist/apps/data/routes/activities.js +250 -88
  57. package/dist/apps/data/routes/activities.js.map +1 -1
  58. package/dist/apps/data/routes/addresses.d.ts +872 -251
  59. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  60. package/dist/apps/data/routes/addresses.js +11 -9
  61. package/dist/apps/data/routes/addresses.js.map +1 -1
  62. package/dist/apps/data/routes/balances.d.ts +77 -26
  63. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  64. package/dist/apps/data/routes/balances.js +88 -45
  65. package/dist/apps/data/routes/balances.js.map +1 -1
  66. package/dist/apps/data/routes/blocks.d.ts +39 -39
  67. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  68. package/dist/apps/data/routes/exchanges.d.ts +856 -105
  69. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  70. package/dist/apps/data/routes/exchanges.js +518 -76
  71. package/dist/apps/data/routes/exchanges.js.map +1 -1
  72. package/dist/apps/data/routes/fee-amm.d.ts +81 -67
  73. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  74. package/dist/apps/data/routes/fee-amm.js +76 -91
  75. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  76. package/dist/apps/data/routes/funding.d.ts +80 -36
  77. package/dist/apps/data/routes/funding.d.ts.map +1 -1
  78. package/dist/apps/data/routes/funding.js +65 -31
  79. package/dist/apps/data/routes/funding.js.map +1 -1
  80. package/dist/apps/data/routes/receipts.d.ts +392 -315
  81. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  82. package/dist/apps/data/routes/receipts.js +152 -77
  83. package/dist/apps/data/routes/receipts.js.map +1 -1
  84. package/dist/apps/data/routes/tokens.d.ts +167 -174
  85. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  86. package/dist/apps/data/routes/tokens.js +15 -13
  87. package/dist/apps/data/routes/tokens.js.map +1 -1
  88. package/dist/apps/data/routes/transactions.d.ts +277 -536
  89. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  90. package/dist/apps/data/routes/transactions.js +96 -77
  91. package/dist/apps/data/routes/transactions.js.map +1 -1
  92. package/dist/apps/data/routes/transfers.d.ts +157 -81
  93. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  94. package/dist/apps/data/routes/transfers.js +272 -130
  95. package/dist/apps/data/routes/transfers.js.map +1 -1
  96. package/dist/apps/data/routes/valuation.d.ts +307 -0
  97. package/dist/apps/data/routes/valuation.d.ts.map +1 -0
  98. package/dist/apps/data/routes/valuation.js +292 -0
  99. package/dist/apps/data/routes/valuation.js.map +1 -0
  100. package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
  101. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
  102. package/dist/apps/data/routes/verified-tokens.js +7 -5
  103. package/dist/apps/data/routes/verified-tokens.js.map +1 -1
  104. package/dist/apps/data/routes/webhooks.d.ts +103 -123
  105. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  106. package/dist/apps/data/routes/webhooks.js +124 -25
  107. package/dist/apps/data/routes/webhooks.js.map +1 -1
  108. package/dist/apps/index.d.ts +2 -1
  109. package/dist/apps/index.d.ts.map +1 -1
  110. package/dist/apps/index.js +2 -1
  111. package/dist/apps/index.js.map +1 -1
  112. package/dist/apps/management/App.d.ts +8554 -1692
  113. package/dist/apps/management/App.d.ts.map +1 -1
  114. package/dist/apps/management/App.js +12 -1
  115. package/dist/apps/management/App.js.map +1 -1
  116. package/dist/apps/management/routes/api-keys.d.ts +7 -0
  117. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  118. package/dist/apps/management/routes/api-keys.js +17 -3
  119. package/dist/apps/management/routes/api-keys.js.map +1 -1
  120. package/dist/apps/management/routes/billing.d.ts +157 -162
  121. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  122. package/dist/apps/management/routes/billing.js +31 -23
  123. package/dist/apps/management/routes/billing.js.map +1 -1
  124. package/dist/apps/management/routes/faucet.d.ts +232 -0
  125. package/dist/apps/management/routes/faucet.d.ts.map +1 -0
  126. package/dist/apps/management/routes/faucet.js +154 -0
  127. package/dist/apps/management/routes/faucet.js.map +1 -0
  128. package/dist/apps/management/routes/invitations.d.ts +60 -60
  129. package/dist/apps/management/routes/invite-links.d.ts +49 -20
  130. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  131. package/dist/apps/management/routes/invite-links.js +26 -1
  132. package/dist/apps/management/routes/invite-links.js.map +1 -1
  133. package/dist/apps/management/routes/me.d.ts +6 -6
  134. package/dist/apps/management/routes/members.d.ts +6 -6
  135. package/dist/apps/management/routes/orgs.d.ts +42 -42
  136. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  137. package/dist/apps/management/routes/orgs.js +5 -0
  138. package/dist/apps/management/routes/orgs.js.map +1 -1
  139. package/dist/apps/management/routes/projects.d.ts +44 -44
  140. package/dist/apps/management/routes/usage.d.ts +3 -0
  141. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  142. package/dist/apps/management/routes/usage.js +4 -0
  143. package/dist/apps/management/routes/usage.js.map +1 -1
  144. package/dist/apps/management/routes/verified-token-requests.d.ts +697 -0
  145. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -0
  146. package/dist/apps/management/routes/verified-token-requests.js +271 -0
  147. package/dist/apps/management/routes/verified-token-requests.js.map +1 -0
  148. package/dist/apps/management/routes/webhooks.d.ts +6977 -0
  149. package/dist/apps/management/routes/webhooks.d.ts.map +1 -0
  150. package/dist/apps/management/routes/webhooks.js +573 -0
  151. package/dist/apps/management/routes/webhooks.js.map +1 -0
  152. package/dist/apps/mpp/App.d.ts +363 -0
  153. package/dist/apps/mpp/App.d.ts.map +1 -0
  154. package/dist/apps/mpp/App.js +72 -0
  155. package/dist/apps/mpp/App.js.map +1 -0
  156. package/dist/apps/mpp/Mpp.d.ts +178 -0
  157. package/dist/apps/mpp/Mpp.d.ts.map +1 -0
  158. package/dist/apps/mpp/Mpp.js +183 -0
  159. package/dist/apps/mpp/Mpp.js.map +1 -0
  160. package/dist/apps/mpp/index.d.ts +3 -0
  161. package/dist/apps/mpp/index.d.ts.map +1 -0
  162. package/dist/apps/mpp/index.js +3 -0
  163. package/dist/apps/mpp/index.js.map +1 -0
  164. package/dist/apps/relay/App.d.ts.map +1 -1
  165. package/dist/apps/relay/App.js +56 -9
  166. package/dist/apps/relay/App.js.map +1 -1
  167. package/dist/db/Db.d.ts +6 -0
  168. package/dist/db/Db.d.ts.map +1 -1
  169. package/dist/db/Db.js +110 -0
  170. package/dist/db/Db.js.map +1 -1
  171. package/dist/db/Schema.d.ts +53 -0
  172. package/dist/db/Schema.d.ts.map +1 -1
  173. package/dist/db/Schema.js +56 -0
  174. package/dist/db/Schema.js.map +1 -1
  175. package/dist/db/tables/earlyAccess.d.ts +50 -0
  176. package/dist/db/tables/earlyAccess.d.ts.map +1 -0
  177. package/dist/db/tables/earlyAccess.js +63 -0
  178. package/dist/db/tables/earlyAccess.js.map +1 -0
  179. package/dist/db/tables/enabledBillingSources.d.ts +73 -0
  180. package/dist/db/tables/enabledBillingSources.d.ts.map +1 -0
  181. package/dist/db/tables/enabledBillingSources.js +69 -0
  182. package/dist/db/tables/enabledBillingSources.js.map +1 -0
  183. package/dist/db/tables/invitations.d.ts.map +1 -1
  184. package/dist/db/tables/invitations.js +3 -0
  185. package/dist/db/tables/invitations.js.map +1 -1
  186. package/dist/db/tables/inviteLinks.d.ts +10 -2
  187. package/dist/db/tables/inviteLinks.d.ts.map +1 -1
  188. package/dist/db/tables/inviteLinks.js +10 -1
  189. package/dist/db/tables/inviteLinks.js.map +1 -1
  190. package/dist/db/tables/organizations.d.ts +5 -2
  191. package/dist/db/tables/organizations.d.ts.map +1 -1
  192. package/dist/db/tables/organizations.js +13 -2
  193. package/dist/db/tables/organizations.js.map +1 -1
  194. package/dist/db/tables/sponsoredTransactions.d.ts +2 -0
  195. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  196. package/dist/db/tables/sponsoredTransactions.js +2 -0
  197. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  198. package/dist/db/tables/verifiedTokenRequests.d.ts +94 -0
  199. package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -0
  200. package/dist/db/tables/verifiedTokenRequests.js +120 -0
  201. package/dist/db/tables/verifiedTokenRequests.js.map +1 -0
  202. package/dist/db/tables/webhookSubscriptions.d.ts +14 -0
  203. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  204. package/dist/db/tables/webhookSubscriptions.js +16 -0
  205. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  206. package/dist/handlers/internal/utils.d.ts +1 -16
  207. package/dist/handlers/internal/utils.d.ts.map +1 -1
  208. package/dist/handlers/internal/utils.js +17 -6
  209. package/dist/handlers/internal/utils.js.map +1 -1
  210. package/dist/handlers/relay.d.ts.map +1 -1
  211. package/dist/handlers/relay.js +37 -5
  212. package/dist/handlers/relay.js.map +1 -1
  213. package/dist/internal/Auth.d.ts +11 -2
  214. package/dist/internal/Auth.d.ts.map +1 -1
  215. package/dist/internal/Auth.js +14 -47
  216. package/dist/internal/Auth.js.map +1 -1
  217. package/dist/internal/FundingQuotes.d.ts +147 -47
  218. package/dist/internal/FundingQuotes.d.ts.map +1 -1
  219. package/dist/internal/FundingQuotes.js +119 -33
  220. package/dist/internal/FundingQuotes.js.map +1 -1
  221. package/dist/internal/Log.d.ts +37 -5
  222. package/dist/internal/Log.d.ts.map +1 -1
  223. package/dist/internal/Log.js +52 -3
  224. package/dist/internal/Log.js.map +1 -1
  225. package/dist/internal/MetricSink.d.ts.map +1 -1
  226. package/dist/internal/MetricSink.js +24 -0
  227. package/dist/internal/MetricSink.js.map +1 -1
  228. package/dist/internal/OpenApi.d.ts +2 -2
  229. package/dist/internal/OpenApi.d.ts.map +1 -1
  230. package/dist/internal/OpenApi.js +3 -0
  231. package/dist/internal/OpenApi.js.map +1 -1
  232. package/dist/internal/Response.d.ts +2 -2
  233. package/dist/internal/Response.d.ts.map +1 -1
  234. package/dist/internal/Response.js +12 -4
  235. package/dist/internal/Response.js.map +1 -1
  236. package/dist/internal/Schema.d.ts +14 -5
  237. package/dist/internal/Schema.d.ts.map +1 -1
  238. package/dist/internal/Schema.js +23 -5
  239. package/dist/internal/Schema.js.map +1 -1
  240. package/dist/internal/Value.d.ts +18 -0
  241. package/dist/internal/Value.d.ts.map +1 -1
  242. package/dist/internal/Value.js +11 -1
  243. package/dist/internal/Value.js.map +1 -1
  244. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  245. package/dist/internal/VerifiedTokens.js +10 -1
  246. package/dist/internal/VerifiedTokens.js.map +1 -1
  247. package/dist/internal/Webhooks.d.ts +24 -3
  248. package/dist/internal/Webhooks.d.ts.map +1 -1
  249. package/dist/internal/Webhooks.js +34 -8
  250. package/dist/internal/Webhooks.js.map +1 -1
  251. package/package.json +7 -2
  252. package/src/App.test.ts +9 -4
  253. package/src/App.ts +23 -3
  254. package/src/Client.test-d.ts +733 -20
  255. package/src/Scope.ts +5 -0
  256. package/src/admin/App.test.ts +4 -0
  257. package/src/admin/App.ts +4 -0
  258. package/src/admin/apps/early-access.test.ts +125 -0
  259. package/src/admin/apps/early-access.ts +176 -0
  260. package/src/admin/apps/organizations.test.ts +86 -2
  261. package/src/admin/apps/organizations.ts +155 -31
  262. package/src/admin/apps/scopes.test.ts +5 -0
  263. package/src/admin/apps/verified-tokens.test.ts +201 -0
  264. package/src/admin/apps/verified-tokens.ts +532 -286
  265. package/src/admin/ui/plugin.ts +2 -1
  266. package/src/admin/ui/src/lib/early-access.ts +63 -0
  267. package/src/admin/ui/src/lib/organizations.test.ts +81 -1
  268. package/src/admin/ui/src/lib/organizations.ts +92 -0
  269. package/src/admin/ui/src/lib/verified-tokens.ts +79 -0
  270. package/src/admin/ui/src/routeTree.gen.ts +33 -2
  271. package/src/admin/ui/src/routes/__root.tsx +2 -1
  272. package/src/admin/ui/src/routes/api-keys.tsx +1 -1
  273. package/src/admin/ui/src/routes/early-access.tsx +162 -0
  274. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +103 -0
  275. package/src/admin/ui/src/routes/verified-tokens.tsx +230 -19
  276. package/src/admin/ui.generated.ts +95 -94
  277. package/src/analytics/Analytics.test.ts +83 -0
  278. package/src/analytics/Analytics.ts +20 -0
  279. package/src/analytics/tables/requestEvents.ts +60 -7
  280. package/src/apps/composition.test.ts +11 -2
  281. package/src/apps/data/App.test.ts +1 -1
  282. package/src/apps/data/App.ts +22 -14
  283. package/src/apps/data/FundingQuoteProviders.test.ts +297 -4
  284. package/src/apps/data/FundingQuoteProviders.ts +255 -29
  285. package/src/apps/data/FxOracle.test.ts +118 -0
  286. package/src/apps/data/FxOracle.ts +153 -0
  287. package/src/apps/data/index.ts +1 -0
  288. package/src/apps/data/routes/activities.test.ts +177 -3
  289. package/src/apps/data/routes/activities.ts +441 -132
  290. package/src/apps/data/routes/addresses.ts +19 -9
  291. package/src/apps/data/routes/balances.test.ts +148 -11
  292. package/src/apps/data/routes/balances.ts +140 -51
  293. package/src/apps/data/routes/exchanges.test.ts +544 -9
  294. package/src/apps/data/routes/exchanges.ts +690 -103
  295. package/src/apps/data/routes/fee-amm.test.ts +47 -23
  296. package/src/apps/data/routes/fee-amm.ts +98 -119
  297. package/src/apps/data/routes/funding.test.ts +113 -8
  298. package/src/apps/data/routes/funding.ts +77 -51
  299. package/src/apps/data/routes/receipts.test.ts +129 -23
  300. package/src/apps/data/routes/receipts.ts +205 -100
  301. package/src/apps/data/routes/tokens.test.ts +43 -0
  302. package/src/apps/data/routes/tokens.ts +28 -13
  303. package/src/apps/data/routes/transactions.test.ts +72 -19
  304. package/src/apps/data/routes/transactions.ts +162 -92
  305. package/src/apps/data/routes/transfers.test.ts +341 -31
  306. package/src/apps/data/routes/transfers.ts +358 -158
  307. package/src/apps/data/routes/valuation.test.ts +437 -0
  308. package/src/apps/data/routes/valuation.ts +423 -0
  309. package/src/apps/data/routes/verified-tokens.ts +14 -2
  310. package/src/apps/data/routes/webhooks.test.ts +56 -8
  311. package/src/apps/data/routes/webhooks.ts +144 -27
  312. package/src/apps/index.ts +2 -1
  313. package/src/apps/management/App.ts +13 -0
  314. package/src/apps/management/routes/api-keys.test.ts +14 -0
  315. package/src/apps/management/routes/api-keys.ts +27 -3
  316. package/src/apps/management/routes/billing.test.ts +152 -20
  317. package/src/apps/management/routes/billing.ts +34 -18
  318. package/src/apps/management/routes/faucet.test.ts +87 -0
  319. package/src/apps/management/routes/faucet.ts +201 -0
  320. package/src/apps/management/routes/invite-links.test.ts +117 -0
  321. package/src/apps/management/routes/invite-links.ts +43 -1
  322. package/src/apps/management/routes/me.test.ts +9 -99
  323. package/src/apps/management/routes/orgs.test.ts +45 -2
  324. package/src/apps/management/routes/orgs.ts +6 -0
  325. package/src/apps/management/routes/scopes.test.ts +1 -0
  326. package/src/apps/management/routes/usage.test.ts +6 -0
  327. package/src/apps/management/routes/usage.ts +7 -0
  328. package/src/apps/management/routes/verified-token-requests.test.ts +377 -0
  329. package/src/apps/management/routes/verified-token-requests.ts +397 -0
  330. package/src/apps/management/routes/webhooks.test.ts +426 -0
  331. package/src/apps/management/routes/webhooks.ts +672 -0
  332. package/src/apps/mpp/App.ts +86 -0
  333. package/src/apps/mpp/Mpp.test.ts +193 -0
  334. package/src/apps/mpp/Mpp.ts +353 -0
  335. package/src/apps/mpp/index.ts +2 -0
  336. package/src/apps/mpp/internal/Adapter.ts +11 -0
  337. package/src/apps/mpp/internal/Error.ts +9 -0
  338. package/src/apps/mpp/internal/Idempotency.ts +7 -0
  339. package/src/apps/mpp/internal/Screening.ts +10 -0
  340. package/src/apps/relay/App.test.ts +88 -6
  341. package/src/apps/relay/App.ts +61 -9
  342. package/src/db/Db.test.ts +19 -0
  343. package/src/db/Db.ts +125 -0
  344. package/src/db/Schema.ts +68 -0
  345. package/src/db/tables/earlyAccess.ts +86 -0
  346. package/src/db/tables/enabledBillingSources.test.ts +303 -0
  347. package/src/db/tables/enabledBillingSources.ts +118 -0
  348. package/src/db/tables/invitations.ts +3 -0
  349. package/src/db/tables/inviteLinks.ts +22 -3
  350. package/src/db/tables/organizations.test.ts +103 -0
  351. package/src/db/tables/organizations.ts +18 -2
  352. package/src/db/tables/sponsoredTransactions.ts +4 -0
  353. package/src/db/tables/verifiedTokenRequests.test.ts +200 -0
  354. package/src/db/tables/verifiedTokenRequests.ts +182 -0
  355. package/src/db/tables/webhookSubscriptions.ts +31 -0
  356. package/src/handlers/internal/utils.ts +22 -6
  357. package/src/handlers/relay.errors.test.ts +153 -0
  358. package/src/handlers/relay.ts +42 -7
  359. package/src/internal/Auth.test.ts +3 -3
  360. package/src/internal/Auth.ts +15 -47
  361. package/src/internal/FundingQuotes.test.ts +161 -6
  362. package/src/internal/FundingQuotes.ts +141 -39
  363. package/src/internal/Log.test-d.ts +21 -0
  364. package/src/internal/Log.test.ts +141 -0
  365. package/src/internal/Log.ts +93 -6
  366. package/src/internal/MetricSink.test.ts +215 -0
  367. package/src/internal/MetricSink.ts +24 -0
  368. package/src/internal/OpenApi.ts +3 -0
  369. package/src/internal/Response.test.ts +28 -0
  370. package/src/internal/Response.ts +12 -4
  371. package/src/internal/Schema.ts +50 -5
  372. package/src/internal/Value.test.ts +20 -0
  373. package/src/internal/Value.ts +24 -1
  374. package/src/internal/VerifiedTokens.ts +9 -1
  375. package/src/internal/Webhooks.test.ts +140 -0
  376. package/src/internal/Webhooks.ts +53 -9
@@ -36,6 +36,9 @@ const row = {
36
36
  rate_limit_scope: null,
37
37
  request_id: 'req-1',
38
38
  route: '/v1/transactions',
39
+ rpc_error_code: null,
40
+ rpc_error_count: 0,
41
+ rpc_error_data_code: null,
39
42
  service: 'api',
40
43
  status: 200,
41
44
  timestamp: '2026-01-01 00:00:00.000',
@@ -211,6 +214,9 @@ describe('createQueueSink', () => {
211
214
  rate_limit_scope: row.rate_limit_scope,
212
215
  request_id: row.request_id,
213
216
  route: row.route,
217
+ rpc_error_code: row.rpc_error_code,
218
+ rpc_error_count: row.rpc_error_count,
219
+ rpc_error_data_code: row.rpc_error_data_code,
214
220
  service: row.service,
215
221
  status: row.status,
216
222
  timestamp: '<timestamp>',
@@ -229,6 +235,9 @@ describe('createQueueSink', () => {
229
235
  "rate_limit_scope": null,
230
236
  "request_id": "req-1",
231
237
  "route": "/v1/transactions",
238
+ "rpc_error_code": null,
239
+ "rpc_error_count": 0,
240
+ "rpc_error_data_code": null,
232
241
  "service": "api",
233
242
  "status": 200,
234
243
  "timestamp": "<timestamp>",
@@ -272,6 +281,24 @@ describe('createQueueSink', () => {
272
281
  })
273
282
  })
274
283
 
284
+ test('records JSON-RPC error metadata', async () => {
285
+ const send = vi.fn<(message: Analytics.Event) => Promise<void>>().mockResolvedValue(undefined)
286
+ const sink = Analytics.createQueueSink({ send })(context)
287
+
288
+ await sink({
289
+ ...entry,
290
+ level: 'warn',
291
+ rpc: { code: -32602, dataCode: 'billing_required', errors: 2 },
292
+ })
293
+
294
+ expect(send.mock.calls[0]![0]).toMatchObject({
295
+ rpc_error_code: -32602,
296
+ rpc_error_count: 2,
297
+ rpc_error_data_code: 'billing_required',
298
+ status: 200,
299
+ })
300
+ })
301
+
275
302
  test('rethrows when the retry also fails', async () => {
276
303
  const send = vi
277
304
  .fn<(message: Analytics.Event) => Promise<void>>()
@@ -399,6 +426,7 @@ describe('readProjectUsage', () => {
399
426
  expect(query).toContain(`key_environment = 'sandbox'`)
400
427
  expect(query).not.toContain('key_id IN')
401
428
  expect(query).toContain('LIMIT 100')
429
+ expect(query).toContain('status >= 400 OR rpc_error_count > 0')
402
430
  expect(new URL(String(fetch.mock.calls[0]![0])).searchParams.get('query')).toBeNull()
403
431
  expect(usage).toMatchObject({
404
432
  from: '2026-01-01T00:00:00.000Z',
@@ -408,6 +436,29 @@ describe('readProjectUsage', () => {
408
436
  })
409
437
  })
410
438
 
439
+ test('includes JSON-RPC failures in the error breakdown', async () => {
440
+ const fetch = vi.fn<typeof globalThis.fetch>().mockResolvedValue(
441
+ new Response(JSON.stringify({ data: [{ code: 'billing_required', requests: '2' }] }), {
442
+ status: 200,
443
+ }),
444
+ )
445
+ vi.stubGlobal('fetch', fetch)
446
+
447
+ const breakdown = await RequestEvents.readErrorBreakdown(Analytics.clickhouse(clickHouse), {
448
+ attributions: [{ projectId: 'prj_1' }],
449
+ from: '2026-01-01T00:00:00.000Z',
450
+ interval: 'day',
451
+ orgId: 'org_1',
452
+ to: '2026-01-02T00:00:00.000Z',
453
+ })
454
+
455
+ expect(fetch.mock.calls[0]![1]?.body).toEqual(expect.stringContaining('rpc_error_data_code'))
456
+ expect(fetch.mock.calls[0]![1]?.body).toEqual(
457
+ expect.stringContaining('status >= 400 OR rpc_error_count > 0'),
458
+ )
459
+ expect(breakdown).toEqual([{ code: 'billing_required', requests: 2 }])
460
+ })
461
+
411
462
  test('keeps legacy rows scoped to project keys without global org filtering', async () => {
412
463
  const fetch = vi
413
464
  .fn<typeof globalThis.fetch>()
@@ -525,3 +576,35 @@ describe('readProjectUsage', () => {
525
576
  })
526
577
  })
527
578
  })
579
+
580
+ describe('readLastUsedAt', () => {
581
+ test('returns the latest request timestamp for each requested key', async () => {
582
+ const fetch = vi.fn<typeof globalThis.fetch>().mockImplementation(async (_url, init) => {
583
+ const sql = init?.body
584
+ if (typeof sql !== 'string') throw new Error('Expected a SQL request body.')
585
+ expect(sql).toContain("key_id IN ('key_1', 'key_2')")
586
+ expect(sql).toContain('max(timestamp)')
587
+ return new Response(
588
+ JSON.stringify({
589
+ data: [{ key_id: 'key_1', lastUsedAt: '2026-07-21T12:34:56.000Z' }],
590
+ }),
591
+ { status: 200 },
592
+ )
593
+ })
594
+ vi.stubGlobal('fetch', fetch)
595
+
596
+ await expect(
597
+ RequestEvents.readLastUsedAt(Analytics.clickhouse(clickHouse), ['key_1', 'key_2']),
598
+ ).resolves.toEqual([{ apiKeyId: 'key_1', lastUsedAt: '2026-07-21T12:34:56.000Z' }])
599
+ })
600
+
601
+ test('skips the analytics query when no keys are requested', async () => {
602
+ const fetch = vi.fn<typeof globalThis.fetch>()
603
+ vi.stubGlobal('fetch', fetch)
604
+
605
+ await expect(
606
+ RequestEvents.readLastUsedAt(Analytics.clickhouse(clickHouse), []),
607
+ ).resolves.toEqual([])
608
+ expect(fetch).not.toHaveBeenCalled()
609
+ })
610
+ })
@@ -131,6 +131,9 @@ export const migrations: readonly Migration[] = [
131
131
  project_id Nullable(String),
132
132
  rate_limit_scope Nullable(String),
133
133
  error_code Nullable(String),
134
+ rpc_error_code Nullable(Int32),
135
+ rpc_error_data_code Nullable(String),
136
+ rpc_error_count UInt16 DEFAULT 0,
134
137
  request_id Nullable(String),
135
138
  billing_active Nullable(UInt8)
136
139
  )
@@ -156,6 +159,23 @@ export const migrations: readonly Migration[] = [
156
159
  ADD COLUMN IF NOT EXISTS billing_active Nullable(UInt8)
157
160
  `,
158
161
  },
162
+ {
163
+ name: '0003_request_events_rpc_errors',
164
+ // Patches tables created before RPC columns entered the baseline. Fresh
165
+ // tables include them, allowing scoped preview users without ALTER to skip.
166
+ guard: `
167
+ SELECT toUInt8(count() = 3) FROM system.columns
168
+ WHERE database = currentDatabase()
169
+ AND table = 'request_events'
170
+ AND name IN ('rpc_error_code', 'rpc_error_data_code', 'rpc_error_count')
171
+ `,
172
+ sql: `
173
+ ALTER TABLE request_events
174
+ ADD COLUMN IF NOT EXISTS rpc_error_code Nullable(Int32),
175
+ ADD COLUMN IF NOT EXISTS rpc_error_data_code Nullable(String),
176
+ ADD COLUMN IF NOT EXISTS rpc_error_count UInt16 DEFAULT 0
177
+ `,
178
+ },
159
179
  ]
160
180
 
161
181
  /**
@@ -30,6 +30,12 @@ export type Table = {
30
30
  principal_type: 'api_key' | 'public' | 'session' | 'super_admin' | 'unknown'
31
31
  /** Rate-limit bucket scope, when a rate limit was applied. */
32
32
  rate_limit_scope: string | null
33
+ /** Numeric JSON-RPC error code when every failed response shares one code. */
34
+ rpc_error_code: number | null
35
+ /** Stable application error code from JSON-RPC `error.data.code`. */
36
+ rpc_error_data_code: string | null
37
+ /** Number of failed JSON-RPC responses in the request. */
38
+ rpc_error_count: number
33
39
  /** Stable per-request id (`entry.requestId`); dedups the billing count via `uniqExact`. */
34
40
  request_id: string | null
35
41
  /** Bounded matched route pattern. */
@@ -79,6 +85,14 @@ export type KeyBreakdown = {
79
85
  requests: number
80
86
  }
81
87
 
88
+ /** Latest authenticated request timestamp for one API key. */
89
+ export type LastUsedAt = {
90
+ /** API key id (`key_…`). */
91
+ apiKeyId: string
92
+ /** Latest request completion timestamp (ISO 8601). */
93
+ lastUsedAt: string
94
+ }
95
+
82
96
  /** Time bucket size for the usage series. */
83
97
  export type Interval = 'day' | 'hour'
84
98
 
@@ -227,6 +241,32 @@ export declare namespace insertMessages {
227
241
  }
228
242
  }
229
243
 
244
+ /**
245
+ * Reads the latest authenticated request timestamp for each requested API key.
246
+ * Keys with no request events are omitted.
247
+ */
248
+ export async function readLastUsedAt(
249
+ analytics: Analytics.Analytics,
250
+ apiKeyIds: readonly string[],
251
+ ): Promise<LastUsedAt[]> {
252
+ if (apiKeyIds.length === 0) return []
253
+ const rows = await analytics.query<LastUsedAtRow>(
254
+ `
255
+ SELECT
256
+ key_id,
257
+ formatDateTime(max(timestamp), '%Y-%m-%dT%H:%i:%S.000Z', 'UTC') AS lastUsedAt
258
+ FROM ${table}
259
+ WHERE principal_type = 'api_key'
260
+ AND key_id IN (${apiKeyIds.map(literal).join(', ')})
261
+ GROUP BY key_id
262
+ `,
263
+ )
264
+ return rows.map((row) => ({
265
+ apiKeyId: String(row.key_id),
266
+ lastUsedAt: String(row.lastUsedAt),
267
+ }))
268
+ }
269
+
230
270
  /**
231
271
  * Reads request usage for one project from the `request_events` table.
232
272
  *
@@ -247,7 +287,7 @@ export async function readProjectUsage(
247
287
  SELECT
248
288
  key_id,
249
289
  count() AS requests,
250
- countIf(status >= 400) AS errors,
290
+ countIf(status >= 400 OR rpc_error_count > 0) AS errors,
251
291
  ${average} AS averageDurationMs
252
292
  FROM ${table}
253
293
  WHERE ${where} AND key_id IS NOT NULL
@@ -261,7 +301,7 @@ export async function readProjectUsage(
261
301
  SELECT
262
302
  route,
263
303
  count() AS requests,
264
- countIf(status >= 400) AS errors,
304
+ countIf(status >= 400 OR rpc_error_count > 0) AS errors,
265
305
  ${average} AS averageDurationMs
266
306
  FROM ${table}
267
307
  WHERE ${where}
@@ -286,7 +326,7 @@ export async function readProjectUsage(
286
326
  SELECT
287
327
  formatDateTime(${bucket}, '%Y-%m-%dT%H:%i:%S.000Z', 'UTC') AS time,
288
328
  count() AS requests,
289
- countIf(status >= 400) AS errors
329
+ countIf(status >= 400 OR rpc_error_count > 0) AS errors
290
330
  FROM ${table}
291
331
  WHERE ${where}
292
332
  GROUP BY ${bucket}
@@ -297,7 +337,7 @@ export async function readProjectUsage(
297
337
  `
298
338
  SELECT
299
339
  count() AS requests,
300
- countIf(status >= 400) AS errors,
340
+ countIf(status >= 400 OR rpc_error_count > 0) AS errors,
301
341
  ${average} AS averageDurationMs
302
342
  FROM ${table}
303
343
  WHERE ${where}
@@ -347,11 +387,16 @@ export async function readErrorBreakdown(
347
387
  const rows = await analytics.query<ErrorRow>(
348
388
  `
349
389
  SELECT
350
- coalesce(error_code, 'unknown') AS code,
390
+ coalesce(
391
+ error_code,
392
+ rpc_error_data_code,
393
+ if(rpc_error_count > 0 AND rpc_error_code IS NOT NULL, concat('rpc_', toString(rpc_error_code)), NULL),
394
+ if(rpc_error_count > 0, 'rpc_multiple', 'unknown')
395
+ ) AS code,
351
396
  count() AS requests
352
397
  FROM ${table}
353
- WHERE ${usageWhere(options)} AND status >= 400
354
- GROUP BY error_code
398
+ WHERE ${usageWhere(options)} AND (status >= 400 OR rpc_error_count > 0)
399
+ GROUP BY code
355
400
  ORDER BY requests DESC, code ASC
356
401
  LIMIT 25
357
402
  `,
@@ -434,6 +479,11 @@ type KeyRow = {
434
479
  requests: number | string
435
480
  }
436
481
 
482
+ type LastUsedAtRow = {
483
+ key_id: string
484
+ lastUsedAt: string
485
+ }
486
+
437
487
  type ErrorRow = {
438
488
  code: string
439
489
  requests: number | string
@@ -480,6 +530,9 @@ function event(entry: Log.Entry, context: Metrics.cloudflare.Context): Table {
480
530
  rate_limit_scope: entry.rateLimit?.scope ?? null,
481
531
  request_id: entry.requestId ?? null,
482
532
  route: entry.route,
533
+ rpc_error_code: entry.rpc?.code ?? null,
534
+ rpc_error_count: entry.rpc?.errors ?? 0,
535
+ rpc_error_data_code: entry.rpc?.dataCode ?? null,
483
536
  service: context.service ?? 'unknown',
484
537
  status: entry.status,
485
538
  timestamp: timestamp(),
@@ -1,5 +1,5 @@
1
1
  import { App, Store } from 'tapimo'
2
- import { data, management, relay } from 'tapimo/apps'
2
+ import { data, management, mpp, relay } from 'tapimo/apps'
3
3
  import { Hono } from 'hono'
4
4
  import { describeRoute } from 'hono-openapi'
5
5
  import * as TestApp from '../../test/App.js'
@@ -190,7 +190,7 @@ describe('data()', () => {
190
190
  })
191
191
 
192
192
  describe('relay()', () => {
193
- test('mounts the relay after data() and stays out of the document', async () => {
193
+ test('mounts the relay after data() without documenting RPC routes', async () => {
194
194
  const composed = App.create({ db: TestApp.database() }).route('/', data()).route('/', relay())
195
195
 
196
196
  // Mounted but default-closed and hidden: unauthenticated requests are
@@ -209,6 +209,15 @@ describe('relay()', () => {
209
209
  })
210
210
  })
211
211
 
212
+ describe('mpp()', () => {
213
+ test('mounts documented MPP routes independently', async () => {
214
+ const app = App.create({ db: TestApp.database() }).route('/', mpp())
215
+
216
+ expect((await paths(app)).some((path) => path.startsWith('/v1/mpp'))).toBe(true)
217
+ expect((await app.request('/rpc/relay')).status).toBe(404)
218
+ })
219
+ })
220
+
212
221
  describe('management()', () => {
213
222
  test('mounts management routes and omits data routes', async () => {
214
223
  const app = App.create({
@@ -254,7 +254,7 @@ describe('zone chain gate', () => {
254
254
  for (const path of [
255
255
  `/v1/tokens?chainId=${zone}`,
256
256
  `/v1/addresses/0x0000000000000000000000000000000000000001/activities?chainId=${zone}`,
257
- `/v1/transfers?chainId=${zone}&include=token`,
257
+ `/v1/transfers?chainId=${zone}&include=token.verified`,
258
258
  ]) {
259
259
  const response = await app.request(path)
260
260
  const body = (await response.json()) as { error: { code: string; message: string } }
@@ -14,6 +14,7 @@ import * as Tidx from '../../internal/Tidx.js'
14
14
  import * as Viem from '../../internal/Viem.js'
15
15
  import * as Scope from '../../Scope.js'
16
16
  import * as Metadata from '../metadata.js'
17
+ import type * as FxOracle from './FxOracle.js'
17
18
 
18
19
  import { transactions as transactionActivities } from './routes/activities.js'
19
20
  import { addresses } from './routes/addresses.js'
@@ -42,6 +43,12 @@ import { schema as webhookSchema, webhooks } from './routes/webhooks.js'
42
43
  */
43
44
  export function data(options: data.Options = {}) {
44
45
  const { assets, tidx } = options
46
+ const webhook =
47
+ options.webhook === false
48
+ ? undefined
49
+ : (options.webhook ?? {
50
+ supportedChainIds: [Viem.chainId.mainnet, Viem.chainId.testnet],
51
+ })
45
52
 
46
53
  // Zone endpoints are explicit trust boundaries; the API never derives them.
47
54
  const zones = new Map((options.zones ?? []).map((zone) => [zone.chainId, zone]))
@@ -66,7 +73,7 @@ export function data(options: data.Options = {}) {
66
73
  c.set('supportedChainIds', supportedChainIds)
67
74
  c.set('tidx', tidx)
68
75
  c.set('verifiedTokens', options.verifiedTokens === false ? undefined : (options.verifiedTokens ?? {})) // prettier-ignore
69
- c.set('webhook', options.webhook === false ? undefined : (options.webhook ?? {}))
76
+ c.set('webhook', webhook)
70
77
  c.set('zones', zones)
71
78
  await next()
72
79
  })
@@ -158,18 +165,18 @@ export function data(options: data.Options = {}) {
158
165
  'Content-Type': asset.contentType,
159
166
  })
160
167
  })
161
- .route('/', addresses())
168
+ .route('/', addresses({ fx: options.fx }))
162
169
  .route('/', blocks())
163
- .route('/', exchanges())
170
+ .route('/', exchanges({ fx: options.fx }))
164
171
  .route('/', feeAmm())
165
172
  .route('/', funding(options.funding))
166
173
  .route('/', indexer())
167
- .route('/', receipts())
174
+ .route('/', receipts({ fx: options.fx }))
168
175
  .route('/', tokenlist())
169
176
  .route('/', tokens())
170
177
  .route('/', transactions())
171
- .route('/', transactionActivities())
172
- .route('/', transfers())
178
+ .route('/', transactionActivities({ fx: options.fx }))
179
+ .route('/', transfers({ fx: options.fx }))
173
180
  .route('/', verifiedTokens())
174
181
  .route('/', webhooks({ enabled: options.webhook !== false }))
175
182
  .route('/', rpc())
@@ -206,6 +213,8 @@ export declare namespace data {
206
213
  assets?: Assets.Assets | undefined
207
214
  /** Funding quote provider configuration. */
208
215
  funding?: funding.Options | undefined
216
+ /** FX configuration for the valuation endpoint. */
217
+ fx?: Fx | undefined
209
218
  /** TIDX query client options. */
210
219
  tidx?: Tidx.getClient.Tidx | undefined
211
220
  /** Verified-token feature configuration. Enabled by default (token rows live in `db`; empty until published); pass `false` to always serve an empty verified list. */
@@ -219,6 +228,12 @@ export declare namespace data {
219
228
  zones?: readonly Zone[] | undefined
220
229
  }
221
230
 
231
+ /** FX configuration for the valuation endpoint. */
232
+ type Fx = {
233
+ /** FX rate oracle backing currency conversion. Defaults to the ECB daily reference rates (`FxOracle.ecb()`). */
234
+ oracle?: FxOracle.Oracle | undefined
235
+ }
236
+
222
237
  /** One zone chain served by this deployment. */
223
238
  type Zone = {
224
239
  /** Zone chain id. Consumer-supplied literal; the API never derives zone chain ids. */
@@ -238,14 +253,7 @@ export declare namespace data {
238
253
  }
239
254
 
240
255
  /** Webhook feature configuration. */
241
- type Webhook = {
242
- /**
243
- * Maximum active subscriptions per owner; creation is rejected with
244
- * `403 limit_exceeded` once reached. Defaults to 100, bounding the spam/SSRF
245
- * and delivery-cost surface per owner.
246
- */
247
- maxPerOwner?: number | undefined
248
- }
256
+ type Webhook = App.Webhook
249
257
  }
250
258
 
251
259
  function resolveChainSelector(options: {