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
@@ -0,0 +1,153 @@
1
+ import { Value as core_Value } from 'ox'
2
+
3
+ import * as Ttl from '../../internal/Ttl.js'
4
+
5
+ /** A pluggable fiat FX rate oracle consumed by the valuation endpoint. */
6
+ export type Oracle = {
7
+ /** Oracle identifier, surfaced as the valuation's `pricing.source` (e.g. `ecb`). */
8
+ name: string
9
+ /** Fetches the oracle's current rate set. */
10
+ rates: () => Promise<RateSet>
11
+ /** Cache lifetime for a fetched rate set, in milliseconds. */
12
+ ttl: number
13
+ }
14
+
15
+ /** One oracle-published set of exchange rates quoted against a base currency. */
16
+ export type RateSet = {
17
+ /** Publication date of the rate set as an ISO 8601 timestamp. */
18
+ asOf: string
19
+ /** Currency the rates are quoted against (e.g. `EUR`). */
20
+ base: string
21
+ /** Currency code to units of that currency per one `base` unit, as decimal strings. */
22
+ rates: Record<string, string>
23
+ }
24
+
25
+ /** Fixed-point scale (decimal places) of cross rates returned by {@link rate}. */
26
+ export const precision = 18
27
+
28
+ /** Canonical ECB daily reference-rate feed (public, no key required). */
29
+ export const ecbUrl = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'
30
+
31
+ /**
32
+ * Normalizes an oracle definition into an {@link Oracle}: applies the default
33
+ * `ttl` and rethrows `rates()` failures as {@link RatesError}.
34
+ */
35
+ export function from(oracle: from.Value): Oracle {
36
+ return {
37
+ name: oracle.name,
38
+ rates: async () => {
39
+ try {
40
+ return await oracle.rates()
41
+ } catch (cause) {
42
+ throw new RatesError(oracle.name, { cause })
43
+ }
44
+ },
45
+ ttl: oracle.ttl ?? Ttl.hours(1),
46
+ }
47
+ }
48
+
49
+ export declare namespace from {
50
+ /** Oracle definition accepted by {@link from}. */
51
+ type Value = Pick<Oracle, 'name' | 'rates'> & {
52
+ /** Cache lifetime for a fetched rate set, in milliseconds. @default `Ttl.hours(1)` */
53
+ ttl?: number | undefined
54
+ }
55
+ }
56
+
57
+ /**
58
+ * European Central Bank euro reference rates: one EUR-based set covering ~30
59
+ * currencies, published once per working day.
60
+ */
61
+ export function ecb(options: ecb.Options = {}): Oracle {
62
+ const { fetch = globalThis.fetch, url = ecbUrl } = options
63
+ return from({
64
+ name: 'ecb',
65
+ rates: async () => {
66
+ const response = await fetch(url, {
67
+ headers: { accept: 'application/xml' },
68
+ signal: AbortSignal.timeout(10_000),
69
+ })
70
+ if (!response.ok) throw new ResponseError(response.status)
71
+ const text = await response.text()
72
+
73
+ // The daily file is a flat, stable XML shape; extract the `Cube`
74
+ // attributes directly rather than pulling in an XML parser.
75
+ const asOf = text.match(/<Cube time=['"](\d{4}-\d{2}-\d{2})['"]/)?.[1]
76
+ const rates: Record<string, string> = {}
77
+ for (const match of text.matchAll(
78
+ /<Cube currency=['"]([A-Z]{3})['"] rate=['"]([^'"]*)['"]/g,
79
+ )) {
80
+ const [, code, value] = match
81
+ if (
82
+ !code ||
83
+ !value ||
84
+ !/^\d+(?:\.\d+)?$/.test(value) ||
85
+ core_Value.from(value, precision) <= 0n
86
+ )
87
+ throw new ParseError()
88
+ rates[code] = value
89
+ }
90
+ if (!asOf || rates['USD'] === undefined) throw new ParseError()
91
+ return { asOf: `${asOf}T00:00:00.000Z`, base: 'EUR', rates }
92
+ },
93
+ })
94
+ }
95
+
96
+ export declare namespace ecb {
97
+ /** Options for the ECB oracle. */
98
+ type Options = {
99
+ /** Fetch implementation used to retrieve the feed. @default `globalThis.fetch` */
100
+ fetch?: typeof globalThis.fetch | undefined
101
+ /** Feed URL. @default {@link ecbUrl} */
102
+ url?: string | undefined
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Derives the cross rate from one currency to another through the set's base,
108
+ * scaled to {@link precision} decimal places. Returns `undefined` when the set
109
+ * prices neither leg of a currency.
110
+ */
111
+ export function rate(set: RateSet, options: rate.Options): bigint | undefined {
112
+ const scaled = (code: string) => {
113
+ if (code === set.base) return 10n ** BigInt(precision)
114
+ const value = set.rates[code]
115
+ return value === undefined ? undefined : core_Value.from(value, precision)
116
+ }
117
+ const source = scaled(options.from)
118
+ const target = scaled(options.to)
119
+ if (source === undefined || target === undefined || source === 0n) return undefined
120
+ return (target * 10n ** BigInt(precision)) / source
121
+ }
122
+
123
+ export declare namespace rate {
124
+ /** Options for deriving a cross rate. */
125
+ type Options = {
126
+ /** Currency code to convert from. */
127
+ from: string
128
+ /** Currency code to convert to. */
129
+ to: string
130
+ }
131
+ }
132
+
133
+ /** Thrown when an oracle fails to produce its rate set. */
134
+ export class RatesError extends Error {
135
+ override name = 'FxOracle.RatesError'
136
+ constructor(oracle: string, options: { cause: unknown }) {
137
+ super(`FX oracle "${oracle}" failed to produce rates`, options)
138
+ }
139
+ }
140
+
141
+ class ParseError extends Error {
142
+ override name = 'FxOracle.ParseError'
143
+ constructor() {
144
+ super('Rate feed returned an unrecognized payload')
145
+ }
146
+ }
147
+
148
+ class ResponseError extends Error {
149
+ override name = 'FxOracle.ResponseError'
150
+ constructor(status: number) {
151
+ super(`Rate feed request failed with status ${status}`)
152
+ }
153
+ }
@@ -1,3 +1,4 @@
1
1
  export { data } from './App.js'
2
2
  export * as FundingQuoteProviders from './FundingQuoteProviders.js'
3
+ export * as FxOracle from './FxOracle.js'
3
4
  export * as Sponsorships from '../relay/Sponsorships.js'
@@ -1,12 +1,24 @@
1
- import { Address, Hex } from 'ox'
1
+ import { Address, Hex, Value as core_Value } from 'ox'
2
+ import { FxOracle } from 'tapimo/apps'
2
3
  import { encodeAbiParameters, encodeEventTopics } from 'viem'
3
4
  import { Abis } from 'viem/tempo'
4
5
 
5
6
  import * as TestApp from '../../../../test/App.js'
6
7
  import * as Runtime from '../../../../test/runtime.js'
8
+ import * as Cursor from '../../../internal/Cursor.js'
7
9
  import * as Store from '../../../internal/Store.js'
8
10
  import * as Activities from './activities.js'
9
11
 
12
+ // Deterministic EUR-based rate set so conversion math is exact in assertions.
13
+ const fixed = FxOracle.from({
14
+ name: 'fixed',
15
+ rates: async () => ({
16
+ asOf: '2026-01-01T00:00:00.000Z',
17
+ base: 'EUR',
18
+ rates: { AUD: '1.6', USD: '1.0' },
19
+ }),
20
+ })
21
+
10
22
  /**
11
23
  * Real Tempo (Moderato) accounts, each exercising specific activity types.
12
24
  * Discovered by scanning indexed `logs` for the event each type classifies
@@ -102,6 +114,32 @@ function find(items: readonly Activities.Entry[], type: string): Activities.Entr
102
114
  }
103
115
 
104
116
  describe('GET /addresses/:address/activities', () => {
117
+ test('parses granular token includes for both activity endpoints', () => {
118
+ expect(
119
+ Activities.schema.getAddressActivities.Query.parse({
120
+ include: 'token.logoUri,token.verified',
121
+ }).include,
122
+ ).toMatchInlineSnapshot(`
123
+ [
124
+ "token.logoUri",
125
+ "token.verified",
126
+ ]
127
+ `)
128
+ expect(
129
+ Activities.schema.getTransactionActivities.Query.parse({
130
+ include: 'token.logoUri,token.verified',
131
+ }).include,
132
+ ).toMatchInlineSnapshot(`
133
+ [
134
+ "token.logoUri",
135
+ "token.verified",
136
+ ]
137
+ `)
138
+ expect(
139
+ Activities.schema.getAddressActivities.Query.safeParse({ include: 'token' }).success,
140
+ ).toBe(false)
141
+ })
142
+
105
143
  test('returns a newest-first, schema-valid feed with timing', async () => {
106
144
  const response = await request(accounts.keychain, { limit: '10' })
107
145
  expect(response.status).toBe(200)
@@ -130,7 +168,31 @@ describe('GET /addresses/:address/activities', () => {
130
168
  expect(transfer.data.transactionHash).toMatch(/^0x[0-9a-f]{64}$/)
131
169
  expect(typeof transfer.data.blockNumber).toBe('number')
132
170
  expect(transfer.data.sourceToken.address).toMatch(/^0x[0-9a-f]{40}$/)
133
- expect(transfer.data.sourceToken.amount).toMatch(/^\d+$/)
171
+ expect(transfer.data.sourceToken).not.toHaveProperty('amount')
172
+ expect(typeof transfer.data.sourceToken.currency).toBe('string')
173
+ expect(typeof transfer.data.sourceToken.decimals).toBe('number')
174
+ expect(typeof transfer.data.sourceToken.name).toBe('string')
175
+ expect(typeof transfer.data.sourceToken.symbol).toBe('string')
176
+ expect(transfer.data.sourceAmount.baseUnits).toMatch(/^\d+$/)
177
+ expect(transfer.data.sourceAmount.currency).toBe(transfer.data.sourceToken.currency)
178
+ expect(transfer.data.sourceAmount.decimals).toBe(transfer.data.sourceToken.decimals)
179
+ expect(transfer.data.sourceAmount.formatted).toMatch(/^\d+(\.\d+)?$/)
180
+ expect(transfer.data.sourceToken.logoUri).toBeUndefined()
181
+ expect(transfer.data.sourceToken.verified).toBeUndefined()
182
+ })
183
+
184
+ test('includes requested token verification', async () => {
185
+ const transfer = find(
186
+ (
187
+ await activities(accounts.creator, {
188
+ include: 'token.logoUri,token.verified',
189
+ })
190
+ ).data,
191
+ 'transfer',
192
+ )
193
+ expect(transfer?.type).toBe('transfer')
194
+ if (transfer?.type !== 'transfer') return
195
+ expect(typeof transfer.data.sourceToken.verified).toBe('boolean')
134
196
  })
135
197
 
136
198
  test.skipIf(runtime.mode === 'localnet')('swap data carries both sides of the swap', async () => {
@@ -139,8 +201,30 @@ describe('GET /addresses/:address/activities', () => {
139
201
  if (swap?.type !== 'swap') return
140
202
  expect(swap.data.sourceToken.address).toMatch(/^0x[0-9a-f]{40}$/)
141
203
  expect(swap.data.destinationToken.address).toMatch(/^0x[0-9a-f]{40}$/)
204
+ expect(swap.data.sourceToken).not.toHaveProperty('amount')
205
+ expect(swap.data.destinationToken).not.toHaveProperty('amount')
206
+ expect(swap.data.sourceAmount.baseUnits).toMatch(/^\d+$/)
207
+ expect(swap.data.destinationAmount.baseUnits).toMatch(/^\d+$/)
142
208
  })
143
209
 
210
+ test.skipIf(runtime.mode === 'localnet')(
211
+ 'adds a structured refund amount when a session closes with a refund',
212
+ async () => {
213
+ const session = find((await activities(accounts.channel)).data, 'session-closed')
214
+ expect(session?.type).toBe('session-closed')
215
+ if (session?.type !== 'session-closed') return
216
+ if (!session.data.refund) {
217
+ expect(session.data.refundAmount).toBeUndefined()
218
+ return
219
+ }
220
+ expect(session.data.refundAmount).toBeDefined()
221
+ expect(session.data.refund).not.toHaveProperty('amount')
222
+ expect(session.data.refundAmount?.baseUnits).toMatch(/^\d+$/)
223
+ expect(session.data.refundAmount?.currency).toBe(session.data.refund.currency)
224
+ expect(session.data.refundAmount?.decimals).toBe(session.data.refund.decimals)
225
+ },
226
+ )
227
+
144
228
  test.skipIf(runtime.mode !== 'localnet')(
145
229
  'surfaces a cross-token transfer as outgoing in the sender feed',
146
230
  async () => {
@@ -162,6 +246,10 @@ describe('GET /addresses/:address/activities', () => {
162
246
  expect(transfer.data.recipient).toBe(crossToken.recipient)
163
247
  expect(transfer.data.sourceToken.address).toBe(crossToken.sourceToken)
164
248
  expect(transfer.data.destinationToken?.address).toBe(crossToken.destinationToken)
249
+ expect(transfer.data.sourceToken).not.toHaveProperty('amount')
250
+ expect(transfer.data.destinationToken).not.toHaveProperty('amount')
251
+ expect(transfer.data.sourceAmount.baseUnits).toMatch(/^\d+$/)
252
+ expect(transfer.data.destinationAmount?.baseUnits).toMatch(/^\d+$/)
165
253
  },
166
254
  )
167
255
 
@@ -202,6 +290,39 @@ describe('GET /addresses/:address/activities', () => {
202
290
  },
203
291
  )
204
292
 
293
+ test.skipIf(runtime.mode !== 'localnet')('values curated activity amounts', async () => {
294
+ const db = TestApp.database()
295
+ await TestApp.verifiedSeed(db, runtime.chainId)
296
+ const client = TestApp.client({ db, fx: { oracle: fixed } })
297
+ const hash = runtime.fixtures!.faucetTransactionHashes[0]!
298
+
299
+ const response = await client.v1.transactions[':transactionHash'].activities.$get(
300
+ { param: { transactionHash: hash }, query: { denomination: 'AUD' } },
301
+ TestApp.auth,
302
+ )
303
+ const body = await TestApp.json(response, Activities.schema.getTransactionActivities.Response)
304
+ expect(response.status).toBe(200)
305
+
306
+ // The faucet transaction moves curated USD tokens; their amounts value at
307
+ // the fixed 1.6 USD -> AUD rate.
308
+ const amounts = body.data.flatMap((item) =>
309
+ item.type === 'transfer' || item.type === 'mint' ? [item.data.sourceAmount] : [],
310
+ )
311
+ expect(amounts.length).toBeGreaterThan(0)
312
+ for (const amount of amounts)
313
+ expect(amount.valuation).toEqual({
314
+ amount: core_Value.format((BigInt(amount.baseUnits) * 16n) / 10n, 6),
315
+ currency: 'AUD',
316
+ })
317
+ expect(body.meta?.pricing).toMatchInlineSnapshot(`
318
+ {
319
+ "asOf": "2026-01-01T00:00:00.000Z",
320
+ "basis": "nominal",
321
+ "source": "fixed",
322
+ }
323
+ `)
324
+ })
325
+
205
326
  test('returns every item at the root by default (no group entries)', async () => {
206
327
  const body = await activities(accounts.channel)
207
328
  expect(body.data.every((entry) => entry.type !== 'group')).toBe(true)
@@ -210,9 +331,34 @@ describe('GET /addresses/:address/activities', () => {
210
331
  test('paginates with an opaque cursor', async () => {
211
332
  const first = await activities(accounts.keychain, { limit: '5' })
212
333
  if (!first.nextCursor) return
213
- const second = await activities(accounts.keychain, { limit: '5', cursor: first.nextCursor })
334
+ const response = await request(accounts.keychain, { limit: '5', cursor: first.nextCursor })
335
+ expect(response.headers.get('cache-control')).toMatchInlineSnapshot(
336
+ `"private, max-age=60, stale-while-revalidate=300"`,
337
+ )
338
+ const second = await TestApp.json(response, Activities.schema.getAddressActivities.Response)
214
339
  expect(Array.isArray(second.data)).toBe(true)
215
340
  })
341
+
342
+ test('validates denominations on empty feeds', async () => {
343
+ const client = TestApp.client({ fx: { oracle: fixed } })
344
+ const cursor = Cursor.encode([0, 0])
345
+ const emptyResponse = await client.v1.addresses[':address'].activities.$get(
346
+ { param: { address: accounts.keychain }, query: { cursor, limit: '5' } },
347
+ TestApp.auth,
348
+ )
349
+ const empty = await TestApp.json(emptyResponse, Activities.schema.getAddressActivities.Response)
350
+ expect(emptyResponse.status).toBe(200)
351
+ expect(empty.data).toMatchInlineSnapshot(`[]`)
352
+
353
+ const response = await client.v1.addresses[':address'].activities.$get(
354
+ {
355
+ param: { address: accounts.keychain },
356
+ query: { cursor, denomination: 'JPY', limit: '5' },
357
+ },
358
+ TestApp.auth,
359
+ )
360
+ expect(response.status).toBe(400)
361
+ })
216
362
  })
217
363
 
218
364
  /** Resolves a real transaction hash from an address's (non-grouped) activity feed. */
@@ -239,6 +385,9 @@ describe('GET /transactions/:transactionHash/activities', () => {
239
385
 
240
386
  const response = await transactionActivitiesRequest(transactionHash)
241
387
  expect(response.status).toBe(200)
388
+ expect(response.headers.get('cache-control')).toMatchInlineSnapshot(
389
+ `"private, max-age=60, stale-while-revalidate=300"`,
390
+ )
242
391
  expect(response.headers.get('server-timing')?.includes('transaction_activities;dur=')).toBe(
243
392
  true,
244
393
  )
@@ -262,6 +411,27 @@ describe('GET /transactions/:transactionHash/activities', () => {
262
411
  )
263
412
  })
264
413
 
414
+ test('supports requested token verification', async () => {
415
+ const address = await activities(accounts.creator)
416
+ const entry = address.data.find((item) => item.type !== 'group' && 'sourceToken' in item.data)
417
+ expect(entry?.type).not.toBe('group')
418
+ if (!entry || entry.type === 'group') return
419
+
420
+ const body = await TestApp.json(
421
+ await transactionActivitiesRequest(entry.transactionHash, {
422
+ include: 'token.verified',
423
+ }),
424
+ Activities.schema.getTransactionActivities.Response,
425
+ )
426
+ const item = body.data.find((item) => 'sourceToken' in item.data)
427
+ expect(item).toBeDefined()
428
+ if (!item || !('sourceToken' in item.data) || !item.data.sourceToken || !item.data.sourceAmount)
429
+ return
430
+ expect(typeof item.data.sourceToken.verified).toBe('boolean')
431
+ expect(item.data.sourceToken).not.toHaveProperty('amount')
432
+ expect(item.data.sourceAmount.baseUnits).toMatch(/^\d+$/)
433
+ })
434
+
265
435
  test.skipIf(runtime.mode !== 'localnet')(
266
436
  'classifies a seeded cross-token transfer with both source and destination tokens',
267
437
  async () => {
@@ -283,6 +453,10 @@ describe('GET /transactions/:transactionHash/activities', () => {
283
453
  expect(transfer.data.recipient).toBe(crossToken.recipient)
284
454
  expect(transfer.data.sourceToken.address).toBe(crossToken.sourceToken)
285
455
  expect(transfer.data.destinationToken?.address).toBe(crossToken.destinationToken)
456
+ expect(transfer.data.sourceToken).not.toHaveProperty('amount')
457
+ expect(transfer.data.destinationToken).not.toHaveProperty('amount')
458
+ expect(transfer.data.sourceAmount.baseUnits).toMatch(/^\d+$/)
459
+ expect(transfer.data.destinationAmount?.baseUnits).toMatch(/^\d+$/)
286
460
  },
287
461
  )
288
462