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,426 @@
1
+ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
2
+
3
+ import * as App from '../../../App.js'
4
+ import * as Memberships from '../../../db/tables/memberships.js'
5
+ import * as core_Webhooks from '../../../internal/Webhooks.js'
6
+ import * as TestApp from '../../../../test/App.js'
7
+ import { management } from '../App.js'
8
+ import * as Orgs from './orgs.js'
9
+ import * as Webhooks from './webhooks.js'
10
+
11
+ const origin = 'http://localhost'
12
+ const webhook = { supportedChainIds: [4217, 42431] } satisfies App.Webhook
13
+
14
+ function json(method: 'PATCH' | 'POST', cookie: string, body: unknown) {
15
+ return {
16
+ body: JSON.stringify(body),
17
+ headers: { 'content-type': 'application/json', cookie },
18
+ method,
19
+ }
20
+ }
21
+
22
+ function createApp(options: createApp.Options = {}) {
23
+ return App.create({
24
+ auth: { session: { wallet: { origin } } },
25
+ db: options.db ?? TestApp.database(),
26
+ kv: { store: TestApp.kvStore() },
27
+ }).route('/', management({ webhook: options.webhook ?? webhook }))
28
+ }
29
+
30
+ declare namespace createApp {
31
+ type Options = {
32
+ db?: App.create.Options['db'] | undefined
33
+ webhook?: App.Webhook | false | undefined
34
+ }
35
+ }
36
+
37
+ async function session(app: TestApp.signIn.App) {
38
+ const account = privateKeyToAccount(generatePrivateKey())
39
+ const { cookie } = await TestApp.signIn(app, account)
40
+ return cookie!
41
+ }
42
+
43
+ async function organization(app: ReturnType<typeof createApp>, cookie: string) {
44
+ const response = await app.request('/v1/orgs', json('POST', cookie, { name: 'Acme' }))
45
+ return TestApp.json(response, Orgs.schema.Organization)
46
+ }
47
+
48
+ describe('webhooks', () => {
49
+ test('creates, lists, pauses, and deletes an organization webhook', async () => {
50
+ const app = createApp()
51
+ const cookie = await session(app)
52
+ const org = await organization(app, cookie)
53
+ const collection = `/v1/orgs/${org.id}/webhooks`
54
+
55
+ const createdResponse = await app.request(
56
+ collection,
57
+ json('POST', cookie, {
58
+ chainId: 4217,
59
+ context: { title: 'Payments' },
60
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
61
+ eventType: 'token:transfer',
62
+ filters: {},
63
+ }),
64
+ )
65
+ expect(createdResponse.status).toBe(200)
66
+ const created = await TestApp.json(createdResponse, Webhooks.schema.createWebhook.Response)
67
+ expect(created).toHaveProperty('secret', expect.stringMatching(/^whsec_/))
68
+
69
+ const listedResponse = await app.request(collection, { headers: { cookie } })
70
+ expect(listedResponse.status).toBe(200)
71
+ const listed = await TestApp.json(listedResponse, Webhooks.schema.ListResponse)
72
+ expect(listed.data).toMatchObject([
73
+ {
74
+ context: { title: 'Payments' },
75
+ id: created.id,
76
+ status: 'active',
77
+ },
78
+ ])
79
+
80
+ const item = `${collection}/${created.id}`
81
+ const pausedResponse = await app.request(item, json('PATCH', cookie, { status: 'paused' }))
82
+ expect(pausedResponse.status).toBe(200)
83
+ expect((await TestApp.json(pausedResponse, Webhooks.schema.Subscription)).status).toBe('paused')
84
+
85
+ const deletedResponse = await app.request(item, {
86
+ headers: { cookie },
87
+ method: 'DELETE',
88
+ })
89
+ expect(deletedResponse.status).toBe(200)
90
+ expect(await TestApp.json(deletedResponse, Webhooks.schema.DeleteResponse)).toEqual({
91
+ id: created.id,
92
+ })
93
+
94
+ const empty = await TestApp.json(
95
+ await app.request(collection, { headers: { cookie } }),
96
+ Webhooks.schema.ListResponse,
97
+ )
98
+ expect(empty.data).toEqual([])
99
+ })
100
+
101
+ test('lists paginated delivery history with destination credentials redacted', async () => {
102
+ const db = TestApp.database()
103
+ const app = createApp({ db })
104
+ const cookie = await session(app)
105
+ const org = await organization(app, cookie)
106
+ const subscription = await core_Webhooks.createSubscription(db, {
107
+ chainId: 4217,
108
+ destination: {
109
+ type: 'url',
110
+ url: 'https://example.com/hooks/capability?token=secret#fragment',
111
+ },
112
+ eventType: 'token:transfer',
113
+ owner: { orgId: org.id, type: 'api_key' },
114
+ })
115
+ for (let attempt = 1; attempt <= 6; attempt++) {
116
+ const createdAt = new Date(1_700_000_000_000 + attempt * 1_000).toISOString()
117
+ await core_Webhooks.recordDelivery(db, {
118
+ attempt,
119
+ createdAt,
120
+ envelope: {
121
+ chainId: 4217,
122
+ createdAt,
123
+ data: {
124
+ address: '0x20c0000000000000000000008f5425160ebe5525',
125
+ amount: String(attempt),
126
+ blockNumber: attempt,
127
+ recipient: '0x9e39034aae71fb89f66061a2602eb6efec271754',
128
+ sender: '0xe7687128b0a808c2831ff94d4f7b2fb35c65af38',
129
+ timestamp: createdAt,
130
+ transactionHash: `0x${attempt.toString(16).padStart(64, '0')}`,
131
+ },
132
+ id: `evt_${attempt}`,
133
+ subscriptionId: subscription.id,
134
+ type: 'token:transfer',
135
+ },
136
+ eventId: `evt_${attempt}`,
137
+ id: `whd_${String(1_700_000_000_000 + attempt * 1_000).padStart(15, '0')}_${'0'.repeat(16)}`,
138
+ requestUrl: subscription.destination.url,
139
+ responseMs: attempt,
140
+ responseStatus: 200,
141
+ status: 'succeeded',
142
+ subscriptionId: subscription.id,
143
+ })
144
+ }
145
+
146
+ const path = `/v1/orgs/${org.id}/webhooks/${subscription.id}/deliveries?limit=5`
147
+ const response = await app.request(path, { headers: { cookie } })
148
+ expect(response.status).toBe(200)
149
+ const body = await TestApp.json(response, Webhooks.schema.listWebhookDeliveries.Response)
150
+ expect(body.data.map((delivery) => delivery.eventId)).toEqual([
151
+ 'evt_6',
152
+ 'evt_5',
153
+ 'evt_4',
154
+ 'evt_3',
155
+ 'evt_2',
156
+ ])
157
+ expect(body.nextCursor).toBeTruthy()
158
+ expect(body.data[0]?.requestUrl).toBe('https://example.com/…')
159
+ expect(JSON.stringify(body)).not.toContain('capability')
160
+ expect(JSON.stringify(body)).not.toContain('token=secret')
161
+ expect(JSON.stringify(body)).not.toContain('amount')
162
+
163
+ const detailResponse = await app.request(`${path.split('?')[0]}/${body.data[0]!.id}`, {
164
+ headers: { cookie },
165
+ })
166
+ expect(detailResponse.status).toBe(200)
167
+ const detail = await TestApp.json(detailResponse, Webhooks.schema.getWebhookDelivery.Response)
168
+ expect(detail.envelope).toMatchObject({
169
+ data: { amount: '6' },
170
+ id: 'evt_6',
171
+ subscriptionId: subscription.id,
172
+ type: 'token:transfer',
173
+ })
174
+ expect(detail.requestUrl).toBe('https://example.com/…')
175
+ expect(JSON.stringify(detail)).not.toContain('capability')
176
+ expect(JSON.stringify(detail)).not.toContain('token=secret')
177
+ expect(JSON.stringify(detail)).not.toContain(subscription.secret)
178
+ })
179
+
180
+ test('returns delivery_not_found when loading or replaying an unknown delivery', async () => {
181
+ const db = TestApp.database()
182
+ const app = createApp({ db })
183
+ const cookie = await session(app)
184
+ const org = await organization(app, cookie)
185
+ const subscription = await core_Webhooks.createSubscription(db, {
186
+ chainId: 4217,
187
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
188
+ eventType: 'token:transfer',
189
+ owner: { orgId: org.id, type: 'api_key' },
190
+ })
191
+
192
+ const detailResponse = await app.request(
193
+ `/v1/orgs/${org.id}/webhooks/${subscription.id}/deliveries/whd_missing`,
194
+ { headers: { cookie } },
195
+ )
196
+ expect(detailResponse.status).toBe(404)
197
+ expect(await detailResponse.json()).toMatchObject({
198
+ error: { code: 'delivery_not_found' },
199
+ })
200
+
201
+ const response = await app.request(
202
+ `/v1/orgs/${org.id}/webhooks/${subscription.id}/deliveries/whd_missing/retry`,
203
+ { headers: { cookie }, method: 'POST' },
204
+ )
205
+ expect(response.status).toBe(404)
206
+ expect(await response.json()).toMatchObject({ error: { code: 'delivery_not_found' } })
207
+ })
208
+
209
+ test('hides webhooks behind foreign organizations', async () => {
210
+ const app = createApp()
211
+ const cookie = await session(app)
212
+ const org = await organization(app, cookie)
213
+ const stranger = await session(app)
214
+
215
+ const response = await app.request(`/v1/orgs/${org.id}/webhooks`, {
216
+ headers: { cookie: stranger },
217
+ })
218
+ expect(response.status).toBe(404)
219
+ })
220
+
221
+ test('rejects chains the host does not poll', async () => {
222
+ const app = createApp()
223
+ const cookie = await session(app)
224
+ const org = await organization(app, cookie)
225
+ const response = await app.request(
226
+ `/v1/orgs/${org.id}/webhooks`,
227
+ json('POST', cookie, {
228
+ chainId: 1,
229
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
230
+ eventType: 'token:transfer',
231
+ filters: {},
232
+ }),
233
+ )
234
+
235
+ expect(response.status).toBe(400)
236
+ expect(await response.json()).toMatchObject({
237
+ error: { code: 'chain_id_unsupported' },
238
+ })
239
+ })
240
+
241
+ test('requires an explicit chain id', async () => {
242
+ const app = createApp()
243
+ const cookie = await session(app)
244
+ const org = await organization(app, cookie)
245
+ const response = await app.request(
246
+ `/v1/orgs/${org.id}/webhooks`,
247
+ json('POST', cookie, {
248
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
249
+ eventType: 'token:transfer',
250
+ filters: {},
251
+ }),
252
+ )
253
+
254
+ expect(response.status).toBe(400)
255
+ expect(await response.json()).toMatchObject({ error: { code: 'body_invalid' } })
256
+ })
257
+
258
+ test('redacts managed destination credentials and only returns secrets for URLs', async () => {
259
+ const app = createApp()
260
+ const cookie = await session(app)
261
+ const org = await organization(app, cookie)
262
+ const collection = `/v1/orgs/${org.id}/webhooks`
263
+
264
+ const url = await TestApp.json(
265
+ await app.request(
266
+ collection,
267
+ json('POST', cookie, {
268
+ chainId: 4217,
269
+ destination: {
270
+ type: 'url',
271
+ url: 'https://example.com/hooks/capability?token=secret#fragment',
272
+ },
273
+ eventType: 'token:transfer',
274
+ filters: {},
275
+ }),
276
+ ),
277
+ Webhooks.schema.createWebhook.Response,
278
+ )
279
+ expect(url).toMatchObject({
280
+ destination: {
281
+ type: 'url',
282
+ url: 'https://example.com/hooks/capability?token=secret#fragment',
283
+ },
284
+ secret: expect.stringMatching(/^whsec_/),
285
+ })
286
+ const listed = await TestApp.json(
287
+ await app.request(collection, { headers: { cookie } }),
288
+ Webhooks.schema.ListResponse,
289
+ )
290
+ expect(listed.data.find(({ id }) => id === url.id)?.destination).toEqual({
291
+ type: 'url',
292
+ url: 'https://example.com/…',
293
+ })
294
+ expect(JSON.stringify(listed)).not.toContain('capability')
295
+ expect(JSON.stringify(listed)).not.toContain('token=secret')
296
+
297
+ const slack = await TestApp.json(
298
+ await app.request(
299
+ collection,
300
+ json('POST', cookie, {
301
+ chainId: 4217,
302
+ destination: {
303
+ type: 'slack',
304
+ url: 'https://hooks.slack.com/services/T000/B000/XXXXXXXX',
305
+ },
306
+ eventType: 'token:transfer',
307
+ filters: {},
308
+ }),
309
+ ),
310
+ Webhooks.schema.createWebhook.Response,
311
+ )
312
+ expect(slack).toMatchObject({
313
+ destination: { type: 'slack', url: 'https://hooks.slack.com/…' },
314
+ })
315
+ expect('secret' in slack).toBe(false)
316
+
317
+ const betterstack = await TestApp.json(
318
+ await app.request(
319
+ collection,
320
+ json('POST', cookie, {
321
+ chainId: 4217,
322
+ destination: {
323
+ token: 'source-token',
324
+ type: 'betterstack',
325
+ url: 'https://s1234567.eu-nbg-2.betterstackdata.com',
326
+ },
327
+ eventType: 'token:transfer',
328
+ filters: {},
329
+ }),
330
+ ),
331
+ Webhooks.schema.createWebhook.Response,
332
+ )
333
+ expect(betterstack).toMatchObject({
334
+ destination: {
335
+ token: '[redacted]',
336
+ type: 'betterstack',
337
+ url: 'https://s1234567.eu-nbg-2.betterstackdata.com',
338
+ },
339
+ })
340
+ expect('secret' in betterstack).toBe(false)
341
+ })
342
+
343
+ test('uses the shared per-owner limit', async () => {
344
+ const app = createApp({
345
+ webhook: { maxPerOwner: 1, supportedChainIds: webhook.supportedChainIds },
346
+ })
347
+ const cookie = await session(app)
348
+ const org = await organization(app, cookie)
349
+ const collection = `/v1/orgs/${org.id}/webhooks`
350
+ const body = {
351
+ chainId: 4217,
352
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
353
+ eventType: 'token:transfer',
354
+ filters: {},
355
+ }
356
+
357
+ expect((await app.request(collection, json('POST', cookie, body))).status).toBe(200)
358
+ const response = await app.request(collection, json('POST', cookie, body))
359
+ expect(response.status).toBe(403)
360
+ expect(await response.json()).toMatchObject({ error: { code: 'limit_exceeded' } })
361
+ })
362
+
363
+ test('lists every webhook when the creation limit is lowered', async () => {
364
+ const db = TestApp.database()
365
+ const app = createApp({
366
+ db,
367
+ webhook: { maxPerOwner: 1, supportedChainIds: webhook.supportedChainIds },
368
+ })
369
+ const cookie = await session(app)
370
+ const org = await organization(app, cookie)
371
+ const input = {
372
+ chainId: 4217,
373
+ destination: { type: 'url', url: 'https://example.com/webhooks' } as const,
374
+ eventType: 'token:transfer' as const,
375
+ owner: { orgId: org.id, type: 'api_key' as const },
376
+ }
377
+ await core_Webhooks.createSubscription(db, input)
378
+ await core_Webhooks.createSubscription(db, input)
379
+
380
+ const response = await app.request(`/v1/orgs/${org.id}/webhooks`, {
381
+ headers: { cookie },
382
+ })
383
+ expect(response.status).toBe(200)
384
+ expect((await TestApp.json(response, Webhooks.schema.ListResponse)).data).toHaveLength(2)
385
+ })
386
+
387
+ test('keeps management disabled unless the capability is supplied', async () => {
388
+ const app = createApp({ webhook: false })
389
+ const cookie = await session(app)
390
+ const org = await organization(app, cookie)
391
+ const response = await app.request(`/v1/orgs/${org.id}/webhooks`, {
392
+ headers: { cookie },
393
+ })
394
+
395
+ expect(response.status).toBe(404)
396
+ expect(await response.json()).toMatchObject({ error: { code: 'webhooks_not_enabled' } })
397
+ const spec = (await (await app.request('/openapi.json')).json()) as {
398
+ paths: Record<string, unknown>
399
+ }
400
+ expect(spec.paths[`/v1/orgs/{orgId}/webhooks`]).toBeUndefined()
401
+ })
402
+
403
+ test('requires an admin role for mutations', async () => {
404
+ const db = TestApp.database()
405
+ const app = createApp({ db })
406
+ const ownerCookie = await session(app)
407
+ const org = await organization(app, ownerCookie)
408
+ const memberAccount = privateKeyToAccount(generatePrivateKey())
409
+ const { cookie: memberCookie } = await TestApp.signIn(app, memberAccount)
410
+ const me = (await (
411
+ await app.request('/v1/me', { headers: { cookie: memberCookie! } })
412
+ ).json()) as { id: string }
413
+ await Memberships.create(db, { orgId: org.id, role: 'member', userId: me.id })
414
+
415
+ const response = await app.request(
416
+ `/v1/orgs/${org.id}/webhooks`,
417
+ json('POST', memberCookie!, {
418
+ destination: { type: 'url', url: 'https://example.com/webhooks' },
419
+ eventType: 'token:transfer',
420
+ filters: {},
421
+ }),
422
+ )
423
+ expect(response.status).toBe(403)
424
+ expect(await response.json()).toMatchObject({ error: { code: 'forbidden' } })
425
+ })
426
+ })