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
@@ -247,6 +247,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
247
247
  "data": [
248
248
  {
249
249
  "count": 2,
250
+ "failed": 0,
250
251
  "feeTotal": {
251
252
  "amount": "0.35",
252
253
  "currency": "usd",
@@ -255,6 +256,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
255
256
  },
256
257
  {
257
258
  "count": 1,
259
+ "failed": 1,
258
260
  "feeTotal": {
259
261
  "amount": "0",
260
262
  "currency": "usd",
@@ -275,6 +277,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
275
277
  "data": [
276
278
  {
277
279
  "count": 3,
280
+ "failed": 1,
278
281
  "feeTotal": {
279
282
  "amount": "0.35",
280
283
  "currency": "usd",
@@ -302,6 +305,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
302
305
  [
303
306
  {
304
307
  "count": 1,
308
+ "failed": 0,
305
309
  "feeTotal": {
306
310
  "amount": "0.5",
307
311
  "currency": "usd",
@@ -333,6 +337,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
333
337
  "data": [
334
338
  {
335
339
  "count": 1,
340
+ "failed": 0,
336
341
  "feeTotal": {
337
342
  "amount": "0.1",
338
343
  "currency": "usd",
@@ -352,6 +357,7 @@ describe('GET /orgs/:orgId/usage/sponsorships', () => {
352
357
  "data": [
353
358
  {
354
359
  "count": 1,
360
+ "failed": 0,
355
361
  "feeTotal": {
356
362
  "amount": "0.3",
357
363
  "currency": "usd",
@@ -199,6 +199,12 @@ export namespace schema {
199
199
  z.describe('Sponsored transactions recorded in the bucket, any status.'),
200
200
  z.meta({ examples: [42] }),
201
201
  ),
202
+ failed: z
203
+ .number()
204
+ .check(
205
+ z.describe('Sponsored transactions in the bucket whose status is `failed`.'),
206
+ z.meta({ examples: [3] }),
207
+ ),
202
208
  feeTotal: z
203
209
  .object({
204
210
  amount: z.string().check(
@@ -462,6 +468,7 @@ export function usage() {
462
468
  Response.validated(schema.getSponsorshipUsage.Response, {
463
469
  data: buckets.map((bucket) => ({
464
470
  count: bucket.count,
471
+ failed: bucket.failed,
465
472
  feeTotal: { amount: core_Billing.fromBaseUnits(bucket.feeTotal), currency },
466
473
  timestamp: bucket.timestamp,
467
474
  })),
@@ -0,0 +1,377 @@
1
+ import { testClient } from 'hono/testing'
2
+ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
3
+ import type * as z from 'zod/mini'
4
+
5
+ import * as TestApp from '../../../../test/App.js'
6
+ import type * as Db from '../../../db/Db.js'
7
+ import * as Memberships from '../../../db/tables/memberships.js'
8
+ import * as VerifiedTokenRequests from '../../../db/tables/verifiedTokenRequests.js'
9
+ import * as VerifiedTokens from '../../../internal/VerifiedTokens.js'
10
+ import type { schema } from './verified-token-requests.js'
11
+
12
+ /** Origin pinned for SIWE domain binding; Hono test requests use this host. */
13
+ const origin = 'http://localhost'
14
+
15
+ /** RPC request options carrying a session cookie. */
16
+ function as(cookie: string) {
17
+ return { headers: { cookie } } as const
18
+ }
19
+
20
+ function createApp(db: Db.Source = TestApp.database()) {
21
+ const app = TestApp.create({ db, session: { wallet: { origin } } })
22
+ return { app, client: testClient(app) }
23
+ }
24
+
25
+ /** Signs in a fresh scripted account and resolves its user id. */
26
+ async function session({ app, client }: ReturnType<typeof createApp>) {
27
+ const { cookie } = await TestApp.signIn(app, privateKeyToAccount(generatePrivateKey()))
28
+ if (!cookie) throw new Error('Sign-in did not establish a session')
29
+ const me = await client.v1.me.$get(undefined, as(cookie))
30
+ expect(me.status).toBe(200)
31
+ if (me.status !== 200) throw new Error(`Failed to resolve session user: ${me.status}`)
32
+ const { id: userId } = await me.json()
33
+ return { cookie, userId }
34
+ }
35
+
36
+ /** Creates an owner and organization through their public write boundaries. */
37
+ async function setup(context: ReturnType<typeof createApp>) {
38
+ const owner = await session(context)
39
+ const response = await context.client.v1.orgs.$post({ json: { name: 'Acme' } }, as(owner.cookie))
40
+ expect(response.status).toBe(200)
41
+ if (response.status !== 200) throw new Error(`Failed to create organization: ${response.status}`)
42
+ const org = await response.json()
43
+ return { org, owner }
44
+ }
45
+
46
+ const token = {
47
+ address: '0x20c00000000000000000000000000000000000aa',
48
+ chainId: 42431,
49
+ currency: 'USD',
50
+ decimals: 6,
51
+ name: 'Test USD',
52
+ symbol: 'tUSD',
53
+ } satisfies Partial<z.input<typeof schema.CreateBody>>
54
+
55
+ describe('POST /v1/orgs/:orgId/verified-token-requests', () => {
56
+ test('members submit requests', async () => {
57
+ const db = TestApp.database()
58
+ const context = createApp(db)
59
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
60
+ const { org } = await setup(context)
61
+ const member = await session(context)
62
+ await Memberships.create(db, { orgId: org.id, role: 'member', userId: member.userId })
63
+
64
+ // Checksummed input normalizes to the stored lowercase address.
65
+ const created = await requests.$post(
66
+ {
67
+ json: { ...token, address: '0x20C00000000000000000000000000000000000AA', note: 'We are the issuer.' }, // prettier-ignore
68
+ param: { orgId: org.id },
69
+ },
70
+ as(member.cookie),
71
+ )
72
+ expect(created.status).toBe(200)
73
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
74
+ const request = await created.json()
75
+ expect(request.id).toMatch(/^vtr_/)
76
+ expect(request).toMatchObject({
77
+ address: token.address,
78
+ note: 'We are the issuer.',
79
+ orgId: org.id,
80
+ requestedBy: member.userId,
81
+ reviewNote: null,
82
+ reviewedAt: null,
83
+ status: 'pending',
84
+ })
85
+ })
86
+
87
+ test('rejects tokens already on the verified list', async () => {
88
+ const db = TestApp.database()
89
+ const context = createApp(db)
90
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
91
+ const { org, owner } = await setup(context)
92
+ await VerifiedTokens.create(db, { ...token, name: 'Listed USD' })
93
+
94
+ const byAddress = await requests.$post(
95
+ { json: token, param: { orgId: org.id } },
96
+ as(owner.cookie),
97
+ )
98
+ expect(byAddress.status).toBe(409)
99
+ const addressBody = (await byAddress.json()) as { error?: { code?: string } }
100
+ expect(addressBody.error?.code).toBe('verified_token_exists')
101
+
102
+ // Same symbol (case-insensitive), different address.
103
+ const bySymbol = await requests.$post(
104
+ {
105
+ json: { ...token, address: '0x20c00000000000000000000000000000000000bb', symbol: 'TUSD' },
106
+ param: { orgId: org.id },
107
+ },
108
+ as(owner.cookie),
109
+ )
110
+ expect(bySymbol.status).toBe(409)
111
+ const symbolBody = (await bySymbol.json()) as { error?: { code?: string } }
112
+ expect(symbolBody.error?.code).toBe('verified_symbol_exists')
113
+ })
114
+
115
+ test('rejects a token with a pending request from any org', async () => {
116
+ const context = createApp()
117
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
118
+ const first = await setup(context)
119
+ const second = await setup(context)
120
+
121
+ const created = await requests.$post(
122
+ { json: token, param: { orgId: first.org.id } },
123
+ as(first.owner.cookie),
124
+ )
125
+ expect(created.status).toBe(200)
126
+
127
+ const duplicate = await requests.$post(
128
+ { json: token, param: { orgId: second.org.id } },
129
+ as(second.owner.cookie),
130
+ )
131
+ expect(duplicate.status).toBe(409)
132
+ const body = (await duplicate.json()) as { error?: { code?: string } }
133
+ expect(body.error?.code).toBe('request_pending_exists')
134
+ })
135
+
136
+ test('caps pending requests per organization', async () => {
137
+ const context = createApp()
138
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
139
+ const { org, owner } = await setup(context)
140
+
141
+ for (let index = 0; index < 10; index++) {
142
+ const created = await requests.$post(
143
+ {
144
+ json: {
145
+ ...token,
146
+ address: `0x20c${(index + 1).toString(16).padStart(37, '0')}` as `0x${string}`,
147
+ symbol: `tUSD${index}`,
148
+ },
149
+ param: { orgId: org.id },
150
+ },
151
+ as(owner.cookie),
152
+ )
153
+ expect(created.status).toBe(200)
154
+ }
155
+
156
+ const overflow = await requests.$post(
157
+ {
158
+ json: { ...token, address: `0x20c${'f'.padStart(37, '0')}` as `0x${string}`, symbol: 'tOVER' }, // prettier-ignore
159
+ param: { orgId: org.id },
160
+ },
161
+ as(owner.cookie),
162
+ )
163
+ expect(overflow.status).toBe(409)
164
+ const body = (await overflow.json()) as { error?: { code?: string } }
165
+ expect(body.error?.code).toBe('request_limit_reached')
166
+ })
167
+
168
+ test('accepts an SVG logo and echoes it back', async () => {
169
+ const context = createApp()
170
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
171
+ const { org, owner } = await setup(context)
172
+
173
+ const created = await requests.$post(
174
+ {
175
+ json: { ...token, logo: '<svg xmlns="http://www.w3.org/2000/svg"/>' },
176
+ param: { orgId: org.id },
177
+ },
178
+ as(owner.cookie),
179
+ )
180
+ expect(created.status).toBe(200)
181
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
182
+ // The org sees its own uploaded logo (the console list previews it).
183
+ expect((await created.json()).logo).toBe('<svg xmlns="http://www.w3.org/2000/svg"/>')
184
+
185
+ const invalid = await requests.$post(
186
+ {
187
+ json: { ...token, address: '0x20c00000000000000000000000000000000000bb', logo: 'not svg', symbol: 'tEUR' }, // prettier-ignore
188
+ param: { orgId: org.id },
189
+ },
190
+ as(owner.cookie),
191
+ )
192
+ expect(invalid.status).toBe(400)
193
+
194
+ const oversized = await requests.$post(
195
+ {
196
+ json: {
197
+ ...token,
198
+ address: '0x20c00000000000000000000000000000000000cc',
199
+ logo: `<svg xmlns="http://www.w3.org/2000/svg">${'a'.repeat(256 * 1024)}</svg>`,
200
+ symbol: 'tGBP',
201
+ },
202
+ param: { orgId: org.id },
203
+ },
204
+ as(owner.cookie),
205
+ )
206
+ expect(oversized.status).toBe(400)
207
+ })
208
+
209
+ test('caps free-text field lengths', async () => {
210
+ const context = createApp()
211
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
212
+ const { org, owner } = await setup(context)
213
+
214
+ const oversized = [
215
+ { name: 'x'.repeat(101) },
216
+ { note: 'x'.repeat(501) },
217
+ { symbol: 'x'.repeat(21) },
218
+ ]
219
+ for (const fields of oversized) {
220
+ const response = await requests.$post(
221
+ { json: { ...token, ...fields }, param: { orgId: org.id } },
222
+ as(owner.cookie),
223
+ )
224
+ expect(response.status).toBe(400)
225
+ const body = (await response.json()) as { error?: { code?: string } }
226
+ expect(body.error?.code).toBe('body_invalid')
227
+ }
228
+ })
229
+ })
230
+
231
+ describe('GET /v1/orgs/:orgId/verified-token-requests', () => {
232
+ test('lists only the organization requests', async () => {
233
+ const context = createApp()
234
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
235
+ const { org, owner } = await setup(context)
236
+ const foreign = await setup(context)
237
+
238
+ const created = await requests.$post(
239
+ { json: token, param: { orgId: org.id } },
240
+ as(owner.cookie),
241
+ )
242
+ expect(created.status).toBe(200)
243
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
244
+ const request = await created.json()
245
+
246
+ const listed = await requests.$get({ param: { orgId: org.id } }, as(owner.cookie))
247
+ expect(listed.status).toBe(200)
248
+ if (listed.status !== 200) throw new Error(`Failed to list requests: ${listed.status}`)
249
+ expect((await listed.json()).data.map(({ id }) => id)).toEqual([request.id])
250
+
251
+ // A non-member resolves neither the org nor its requests.
252
+ const denied = await requests.$get({ param: { orgId: org.id } }, as(foreign.owner.cookie))
253
+ expect(denied.status).toBe(404)
254
+
255
+ const empty = await requests.$get({ param: { orgId: foreign.org.id } }, as(foreign.owner.cookie)) // prettier-ignore
256
+ expect(empty.status).toBe(200)
257
+ if (empty.status !== 200) throw new Error(`Failed to list requests: ${empty.status}`)
258
+ expect((await empty.json()).data).toEqual([])
259
+ })
260
+
261
+ test('review fields surface without reviewer identity', async () => {
262
+ const db = TestApp.database()
263
+ const context = createApp(db)
264
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
265
+ const { org, owner } = await setup(context)
266
+
267
+ const created = await requests.$post(
268
+ { json: token, param: { orgId: org.id } },
269
+ as(owner.cookie),
270
+ )
271
+ expect(created.status).toBe(200)
272
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
273
+ const request = await created.json()
274
+ await VerifiedTokenRequests.review(db, request.id, {
275
+ reviewNote: 'Logo unreachable.',
276
+ reviewedBy: 'admin@tempo.xyz',
277
+ status: 'denied',
278
+ })
279
+
280
+ const listed = await requests.$get({ param: { orgId: org.id } }, as(owner.cookie))
281
+ expect(listed.status).toBe(200)
282
+ if (listed.status !== 200) throw new Error(`Failed to list requests: ${listed.status}`)
283
+ const [row] = (await listed.json()).data
284
+ expect(row).toMatchObject({ reviewNote: 'Logo unreachable.', status: 'denied' })
285
+ expect(row?.reviewedAt).toBeTruthy()
286
+ // Reviewer identity stays on the admin surface.
287
+ expect(row && 'reviewedBy' in row).toBe(false)
288
+ })
289
+
290
+ test('requires a session', async () => {
291
+ const context = createApp()
292
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
293
+ const response = await requests.$get({ param: { orgId: 'org_1a2b3c4d5e6f7g8h9j0k1m2n' } })
294
+ expect(response.status).toBe(401)
295
+ })
296
+ })
297
+
298
+ describe('DELETE /v1/orgs/:orgId/verified-token-requests/:requestId', () => {
299
+ test('members cancel pending requests', async () => {
300
+ const db = TestApp.database()
301
+ const context = createApp(db)
302
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
303
+ const { org, owner } = await setup(context)
304
+ const member = await session(context)
305
+ await Memberships.create(db, { orgId: org.id, role: 'member', userId: member.userId })
306
+
307
+ const created = await requests.$post(
308
+ { json: token, param: { orgId: org.id } },
309
+ as(owner.cookie),
310
+ )
311
+ expect(created.status).toBe(200)
312
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
313
+ const request = await created.json()
314
+
315
+ const canceled = await requests[':requestId{vtr_[A-Za-z0-9_-]+}'].$delete(
316
+ { param: { orgId: org.id, requestId: request.id } },
317
+ as(member.cookie),
318
+ )
319
+ expect(canceled.status).toBe(200)
320
+ if (canceled.status !== 200) throw new Error(`Failed to cancel request: ${canceled.status}`)
321
+ expect(await canceled.json()).toEqual({ id: request.id })
322
+
323
+ const repeat = await requests[':requestId{vtr_[A-Za-z0-9_-]+}'].$delete(
324
+ { param: { orgId: org.id, requestId: request.id } },
325
+ as(member.cookie),
326
+ )
327
+ expect(repeat.status).toBe(404)
328
+ })
329
+
330
+ test('is org-scoped', async () => {
331
+ const context = createApp()
332
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
333
+ const { org, owner } = await setup(context)
334
+ const foreign = await setup(context)
335
+
336
+ const created = await requests.$post(
337
+ { json: token, param: { orgId: org.id } },
338
+ as(owner.cookie),
339
+ )
340
+ expect(created.status).toBe(200)
341
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
342
+ const request = await created.json()
343
+
344
+ const crossCancel = await requests[':requestId{vtr_[A-Za-z0-9_-]+}'].$delete(
345
+ { param: { orgId: foreign.org.id, requestId: request.id } },
346
+ as(foreign.owner.cookie),
347
+ )
348
+ expect(crossCancel.status).toBe(404)
349
+ })
350
+
351
+ test('rejects reviewed requests with 409', async () => {
352
+ const db = TestApp.database()
353
+ const context = createApp(db)
354
+ const requests = context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['verified-token-requests']
355
+ const { org, owner } = await setup(context)
356
+
357
+ const created = await requests.$post(
358
+ { json: token, param: { orgId: org.id } },
359
+ as(owner.cookie),
360
+ )
361
+ expect(created.status).toBe(200)
362
+ if (created.status !== 200) throw new Error(`Failed to create request: ${created.status}`)
363
+ const request = await created.json()
364
+ await VerifiedTokenRequests.review(db, request.id, {
365
+ reviewedBy: 'admin@tempo.xyz',
366
+ status: 'denied',
367
+ })
368
+
369
+ const canceled = await requests[':requestId{vtr_[A-Za-z0-9_-]+}'].$delete(
370
+ { param: { orgId: org.id, requestId: request.id } },
371
+ as(owner.cookie),
372
+ )
373
+ expect(canceled.status).toBe(409)
374
+ const body = (await canceled.json()) as { error?: { code?: string } }
375
+ expect(body.error?.code).toBe('request_not_pending')
376
+ })
377
+ })