tapimo 0.0.2 → 0.2.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 (517) hide show
  1. package/README.md +38 -16
  2. package/dist/ApiKey.d.ts +14 -11
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +11 -12
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +207 -0
  7. package/dist/ApiKeys.d.ts.map +1 -0
  8. package/dist/ApiKeys.js +282 -0
  9. package/dist/ApiKeys.js.map +1 -0
  10. package/dist/App.d.ts +6771 -3819
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +145 -317
  13. package/dist/App.js.map +1 -1
  14. package/dist/Handler.d.ts +86 -0
  15. package/dist/Handler.d.ts.map +1 -0
  16. package/dist/Handler.js +83 -0
  17. package/dist/Handler.js.map +1 -0
  18. package/dist/Scope.d.ts +14 -4
  19. package/dist/Scope.d.ts.map +1 -1
  20. package/dist/Scope.js +16 -4
  21. package/dist/Scope.js.map +1 -1
  22. package/dist/Webhooks.d.ts +5 -7
  23. package/dist/Webhooks.d.ts.map +1 -1
  24. package/dist/Webhooks.js +11 -4
  25. package/dist/Webhooks.js.map +1 -1
  26. package/dist/admin/Access.d.ts +1 -3
  27. package/dist/admin/Access.d.ts.map +1 -1
  28. package/dist/admin/Access.js +1 -3
  29. package/dist/admin/Access.js.map +1 -1
  30. package/dist/admin/App.d.ts +167 -205
  31. package/dist/admin/App.d.ts.map +1 -1
  32. package/dist/admin/App.js +2 -4
  33. package/dist/admin/App.js.map +1 -1
  34. package/dist/admin/apps/api-keys.d.ts +105 -5
  35. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  36. package/dist/admin/apps/api-keys.js +75 -9
  37. package/dist/admin/apps/api-keys.js.map +1 -1
  38. package/dist/admin/apps/scopes.d.ts +6 -0
  39. package/dist/admin/apps/scopes.d.ts.map +1 -1
  40. package/dist/admin/apps/verified-tokens.d.ts +35 -149
  41. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  42. package/dist/admin/apps/verified-tokens.js +18 -39
  43. package/dist/admin/apps/verified-tokens.js.map +1 -1
  44. package/dist/admin/ui.generated.d.ts +1 -1
  45. package/dist/admin/ui.generated.js +1 -1
  46. package/dist/apps/data/App.d.ts +19176 -0
  47. package/dist/apps/data/App.d.ts.map +1 -0
  48. package/dist/apps/data/App.js +236 -0
  49. package/dist/apps/data/App.js.map +1 -0
  50. package/dist/apps/data/index.d.ts +3 -0
  51. package/dist/apps/data/index.d.ts.map +1 -0
  52. package/dist/apps/data/index.js +3 -0
  53. package/dist/apps/data/index.js.map +1 -0
  54. package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
  55. package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
  56. package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
  57. package/dist/apps/data/routes/activities.js.map +1 -0
  58. package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
  59. package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
  60. package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
  61. package/dist/apps/data/routes/addresses.js.map +1 -0
  62. package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +49 -49
  63. package/dist/apps/data/routes/balances.d.ts.map +1 -0
  64. package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
  65. package/dist/apps/data/routes/balances.js.map +1 -0
  66. package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
  67. package/dist/apps/data/routes/blocks.d.ts.map +1 -0
  68. package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
  69. package/dist/apps/data/routes/blocks.js.map +1 -0
  70. package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +183 -183
  71. package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
  72. package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
  73. package/dist/apps/data/routes/coingecko.js.map +1 -0
  74. package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +460 -460
  75. package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
  76. package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
  77. package/dist/apps/data/routes/exchanges.js.map +1 -0
  78. package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +94 -94
  79. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
  80. package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
  81. package/dist/apps/data/routes/fee-amm.js.map +1 -0
  82. package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
  83. package/dist/apps/data/routes/indexer.d.ts.map +1 -0
  84. package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
  85. package/dist/apps/data/routes/indexer.js.map +1 -0
  86. package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +6 -6
  87. package/dist/apps/data/routes/receipts.d.ts.map +1 -0
  88. package/dist/apps/{receipts.js → data/routes/receipts.js} +12 -12
  89. package/dist/apps/data/routes/receipts.js.map +1 -0
  90. package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +4 -4
  91. package/dist/apps/data/routes/rpc.d.ts.map +1 -0
  92. package/dist/apps/{rpc.js → data/routes/rpc.js} +6 -6
  93. package/dist/apps/data/routes/rpc.js.map +1 -0
  94. package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +4 -4
  95. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
  96. package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
  97. package/dist/apps/data/routes/tokenlist.js.map +1 -0
  98. package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +11 -11
  99. package/dist/apps/data/routes/tokens.d.ts.map +1 -0
  100. package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
  101. package/dist/apps/data/routes/tokens.js.map +1 -0
  102. package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +288 -288
  103. package/dist/apps/data/routes/transactions.d.ts.map +1 -0
  104. package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
  105. package/dist/apps/data/routes/transactions.js.map +1 -0
  106. package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +35 -35
  107. package/dist/apps/data/routes/transfers.d.ts.map +1 -0
  108. package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
  109. package/dist/apps/data/routes/transfers.js.map +1 -0
  110. package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +42 -42
  111. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
  112. package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
  113. package/dist/apps/data/routes/verified-tokens.js.map +1 -0
  114. package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +66 -63
  115. package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
  116. package/dist/apps/{webhooks.js → data/routes/webhooks.js} +67 -59
  117. package/dist/apps/data/routes/webhooks.js.map +1 -0
  118. package/dist/apps/docs/App.d.ts +27 -0
  119. package/dist/apps/docs/App.d.ts.map +1 -0
  120. package/dist/apps/docs/App.js +122 -0
  121. package/dist/apps/docs/App.js.map +1 -0
  122. package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
  123. package/dist/apps/docs/fonts.d.ts.map +1 -0
  124. package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
  125. package/dist/apps/docs/fonts.js.map +1 -0
  126. package/dist/apps/docs/index.d.ts +2 -0
  127. package/dist/apps/docs/index.d.ts.map +1 -0
  128. package/dist/apps/docs/index.js +2 -0
  129. package/dist/apps/docs/index.js.map +1 -0
  130. package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
  131. package/dist/apps/docs/logo.d.ts.map +1 -0
  132. package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
  133. package/dist/apps/docs/logo.js.map +1 -0
  134. package/dist/apps/index.d.ts +4 -0
  135. package/dist/apps/index.d.ts.map +1 -0
  136. package/dist/apps/index.js +4 -0
  137. package/dist/apps/index.js.map +1 -0
  138. package/dist/apps/metadata.d.ts +7 -0
  139. package/dist/apps/metadata.d.ts.map +1 -0
  140. package/dist/apps/metadata.js +15 -0
  141. package/dist/apps/metadata.js.map +1 -0
  142. package/dist/apps/platform/App.d.ts +2985 -0
  143. package/dist/apps/platform/App.d.ts.map +1 -0
  144. package/dist/apps/platform/App.js +74 -0
  145. package/dist/apps/platform/App.js.map +1 -0
  146. package/dist/apps/platform/index.d.ts +2 -0
  147. package/dist/apps/platform/index.d.ts.map +1 -0
  148. package/dist/apps/platform/index.js +2 -0
  149. package/dist/apps/platform/index.js.map +1 -0
  150. package/dist/apps/platform/routes/api-keys.d.ts +681 -0
  151. package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
  152. package/dist/apps/platform/routes/api-keys.js +328 -0
  153. package/dist/apps/platform/routes/api-keys.js.map +1 -0
  154. package/dist/apps/platform/routes/invitations.d.ts +733 -0
  155. package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
  156. package/dist/apps/platform/routes/invitations.js +413 -0
  157. package/dist/apps/platform/routes/invitations.js.map +1 -0
  158. package/dist/apps/platform/routes/me.d.ts +95 -0
  159. package/dist/apps/platform/routes/me.d.ts.map +1 -0
  160. package/dist/apps/platform/routes/me.js +81 -0
  161. package/dist/apps/platform/routes/me.js.map +1 -0
  162. package/dist/apps/platform/routes/members.d.ts +554 -0
  163. package/dist/apps/platform/routes/members.d.ts.map +1 -0
  164. package/dist/apps/platform/routes/members.js +251 -0
  165. package/dist/apps/platform/routes/members.js.map +1 -0
  166. package/dist/apps/platform/routes/orgs.d.ts +582 -0
  167. package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
  168. package/dist/apps/platform/routes/orgs.js +265 -0
  169. package/dist/apps/platform/routes/orgs.js.map +1 -0
  170. package/dist/apps/platform/routes/projects.d.ts +740 -0
  171. package/dist/apps/platform/routes/projects.d.ts.map +1 -0
  172. package/dist/apps/platform/routes/projects.js +286 -0
  173. package/dist/apps/platform/routes/projects.js.map +1 -0
  174. package/dist/apps/relay/App.d.ts +41 -0
  175. package/dist/apps/relay/App.d.ts.map +1 -0
  176. package/dist/apps/relay/App.js +103 -0
  177. package/dist/apps/relay/App.js.map +1 -0
  178. package/dist/apps/relay/Sponsorships.d.ts +107 -0
  179. package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
  180. package/dist/apps/relay/Sponsorships.js +193 -0
  181. package/dist/apps/relay/Sponsorships.js.map +1 -0
  182. package/dist/apps/relay/index.d.ts +3 -0
  183. package/dist/apps/relay/index.d.ts.map +1 -0
  184. package/dist/apps/relay/index.js +3 -0
  185. package/dist/apps/relay/index.js.map +1 -0
  186. package/dist/{Cli.d.ts → cli/Cli.d.ts} +13 -2
  187. package/dist/cli/Cli.d.ts.map +1 -0
  188. package/dist/cli/Cli.js +19 -0
  189. package/dist/cli/Cli.js.map +1 -0
  190. package/dist/cli/bin.d.ts +3 -0
  191. package/dist/cli/bin.d.ts.map +1 -0
  192. package/dist/cli/bin.js +4 -0
  193. package/dist/cli/bin.js.map +1 -0
  194. package/dist/cli/commands/admin.d.ts +15 -0
  195. package/dist/cli/commands/admin.d.ts.map +1 -0
  196. package/dist/cli/commands/admin.js +60 -0
  197. package/dist/cli/commands/admin.js.map +1 -0
  198. package/dist/cloudflare.d.ts +7 -0
  199. package/dist/cloudflare.d.ts.map +1 -1
  200. package/dist/cloudflare.js +9 -0
  201. package/dist/cloudflare.js.map +1 -1
  202. package/dist/db/Db.d.ts +113 -0
  203. package/dist/db/Db.d.ts.map +1 -0
  204. package/dist/db/Db.js +402 -0
  205. package/dist/db/Db.js.map +1 -0
  206. package/dist/db/Schema.d.ts +168 -0
  207. package/dist/db/Schema.d.ts.map +1 -0
  208. package/dist/db/Schema.js +229 -0
  209. package/dist/db/Schema.js.map +1 -0
  210. package/dist/db/tables/invitations.d.ts +84 -0
  211. package/dist/db/tables/invitations.d.ts.map +1 -0
  212. package/dist/db/tables/invitations.js +165 -0
  213. package/dist/db/tables/invitations.js.map +1 -0
  214. package/dist/db/tables/memberships.d.ts +108 -0
  215. package/dist/db/tables/memberships.d.ts.map +1 -0
  216. package/dist/db/tables/memberships.js +153 -0
  217. package/dist/db/tables/memberships.js.map +1 -0
  218. package/dist/db/tables/organizations.d.ts +123 -0
  219. package/dist/db/tables/organizations.d.ts.map +1 -0
  220. package/dist/db/tables/organizations.js +170 -0
  221. package/dist/db/tables/organizations.js.map +1 -0
  222. package/dist/db/tables/projects.d.ts +65 -0
  223. package/dist/db/tables/projects.d.ts.map +1 -0
  224. package/dist/db/tables/projects.js +75 -0
  225. package/dist/db/tables/projects.js.map +1 -0
  226. package/dist/db/tables/sponsoredTransactions.d.ts +120 -0
  227. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
  228. package/dist/db/tables/sponsoredTransactions.js +161 -0
  229. package/dist/db/tables/sponsoredTransactions.js.map +1 -0
  230. package/dist/db/tables/users.d.ts +48 -0
  231. package/dist/db/tables/users.d.ts.map +1 -0
  232. package/dist/db/tables/users.js +65 -0
  233. package/dist/db/tables/users.js.map +1 -0
  234. package/dist/db/tables/verifiedTokens.d.ts +53 -0
  235. package/dist/db/tables/verifiedTokens.d.ts.map +1 -0
  236. package/dist/db/tables/verifiedTokens.js +74 -0
  237. package/dist/db/tables/verifiedTokens.js.map +1 -0
  238. package/dist/db/tables/webhookDeliveries.d.ts +71 -0
  239. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -0
  240. package/dist/db/tables/webhookDeliveries.js +119 -0
  241. package/dist/db/tables/webhookDeliveries.js.map +1 -0
  242. package/dist/db/tables/webhookSubscriptions.d.ts +158 -0
  243. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -0
  244. package/dist/db/tables/webhookSubscriptions.js +272 -0
  245. package/dist/db/tables/webhookSubscriptions.js.map +1 -0
  246. package/dist/handlers/internal/executionError.d.ts +25 -0
  247. package/dist/handlers/internal/executionError.d.ts.map +1 -0
  248. package/dist/handlers/internal/executionError.js +186 -0
  249. package/dist/handlers/internal/executionError.js.map +1 -0
  250. package/dist/handlers/internal/multisig.d.ts +233 -0
  251. package/dist/handlers/internal/multisig.d.ts.map +1 -0
  252. package/dist/handlers/internal/multisig.js +542 -0
  253. package/dist/handlers/internal/multisig.js.map +1 -0
  254. package/dist/handlers/internal/requestListener.d.ts +124 -0
  255. package/dist/handlers/internal/requestListener.d.ts.map +1 -0
  256. package/dist/handlers/internal/requestListener.js +173 -0
  257. package/dist/handlers/internal/requestListener.js.map +1 -0
  258. package/dist/handlers/internal/sponsorship.d.ts +113 -0
  259. package/dist/handlers/internal/sponsorship.d.ts.map +1 -0
  260. package/dist/handlers/internal/sponsorship.js +128 -0
  261. package/dist/handlers/internal/sponsorship.js.map +1 -0
  262. package/dist/handlers/internal/types.d.ts +284 -0
  263. package/dist/handlers/internal/types.d.ts.map +1 -0
  264. package/dist/handlers/internal/types.js +2 -0
  265. package/dist/handlers/internal/types.js.map +1 -0
  266. package/dist/handlers/internal/utils.d.ts +34 -0
  267. package/dist/handlers/internal/utils.d.ts.map +1 -0
  268. package/dist/handlers/internal/utils.js +131 -0
  269. package/dist/handlers/internal/utils.js.map +1 -0
  270. package/dist/handlers/relay.d.ts +123 -0
  271. package/dist/handlers/relay.d.ts.map +1 -0
  272. package/dist/handlers/relay.js +1278 -0
  273. package/dist/handlers/relay.js.map +1 -0
  274. package/dist/index.d.ts +4 -2
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +4 -2
  277. package/dist/index.js.map +1 -1
  278. package/dist/internal/Auth.d.ts +224 -16
  279. package/dist/internal/Auth.d.ts.map +1 -1
  280. package/dist/internal/Auth.js +572 -33
  281. package/dist/internal/Auth.js.map +1 -1
  282. package/dist/internal/Log.d.ts +7 -3
  283. package/dist/internal/Log.d.ts.map +1 -1
  284. package/dist/internal/Log.js +4 -0
  285. package/dist/internal/Log.js.map +1 -1
  286. package/dist/internal/OpenApi.d.ts +0 -19
  287. package/dist/internal/OpenApi.d.ts.map +1 -1
  288. package/dist/internal/OpenApi.js +0 -57
  289. package/dist/internal/OpenApi.js.map +1 -1
  290. package/dist/internal/RpcSchema.d.ts +10 -0
  291. package/dist/internal/RpcSchema.d.ts.map +1 -0
  292. package/dist/internal/RpcSchema.js +2 -0
  293. package/dist/internal/RpcSchema.js.map +1 -0
  294. package/dist/internal/Store.d.ts +49 -4
  295. package/dist/internal/Store.d.ts.map +1 -1
  296. package/dist/internal/Store.js +81 -5
  297. package/dist/internal/Store.js.map +1 -1
  298. package/dist/internal/VerifiedTokens.d.ts +15 -34
  299. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  300. package/dist/internal/VerifiedTokens.js +115 -159
  301. package/dist/internal/VerifiedTokens.js.map +1 -1
  302. package/dist/internal/Viem.d.ts +84 -0
  303. package/dist/internal/Viem.d.ts.map +1 -1
  304. package/dist/internal/Webhooks.d.ts +50 -36
  305. package/dist/internal/Webhooks.d.ts.map +1 -1
  306. package/dist/internal/Webhooks.js +92 -205
  307. package/dist/internal/Webhooks.js.map +1 -1
  308. package/package.json +37 -6
  309. package/src/ApiKey.test.ts +3 -3
  310. package/src/ApiKey.ts +11 -12
  311. package/src/ApiKeys.test.ts +278 -0
  312. package/src/ApiKeys.ts +358 -0
  313. package/src/App.test-d.ts +1 -1
  314. package/src/App.test.ts +40508 -19083
  315. package/src/App.ts +239 -416
  316. package/src/Client.test-d.ts +307 -16
  317. package/src/Handler.ts +154 -0
  318. package/src/Scope.ts +17 -4
  319. package/src/Webhooks.test.ts +8 -7
  320. package/src/Webhooks.ts +13 -7
  321. package/src/admin/Access.ts +1 -3
  322. package/src/admin/App.ts +19 -24
  323. package/src/admin/apps/api-keys.test.ts +70 -18
  324. package/src/admin/apps/api-keys.ts +92 -9
  325. package/src/admin/apps/scopes.test.ts +8 -0
  326. package/src/admin/apps/verified-tokens.test.ts +3 -30
  327. package/src/admin/apps/verified-tokens.ts +18 -37
  328. package/src/admin/ui.generated.ts +1 -1
  329. package/src/apps/composition.test.ts +66 -0
  330. package/src/apps/data/App.ts +295 -0
  331. package/src/apps/data/index.ts +2 -0
  332. package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
  333. package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
  334. package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
  335. package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +6 -5
  336. package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
  337. package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +4 -4
  338. package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
  339. package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
  340. package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
  341. package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +2 -2
  342. package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
  343. package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
  344. package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
  345. package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +27 -6
  346. package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
  347. package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +4 -4
  348. package/src/apps/{receipts.ts → data/routes/receipts.ts} +13 -13
  349. package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +142 -13
  350. package/src/apps/{rpc.ts → data/routes/rpc.ts} +7 -7
  351. package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +8 -10
  352. package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
  353. package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +6 -5
  354. package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
  355. package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +4 -4
  356. package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
  357. package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +3 -3
  358. package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
  359. package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +27 -15
  360. package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
  361. package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +137 -150
  362. package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +83 -81
  363. package/src/apps/docs/App.ts +136 -0
  364. package/src/apps/docs/index.ts +1 -0
  365. package/src/apps/index.ts +3 -0
  366. package/src/apps/metadata.ts +23 -0
  367. package/src/apps/platform/App.ts +130 -0
  368. package/src/apps/platform/index.ts +1 -0
  369. package/src/apps/platform/routes/api-keys.test.ts +330 -0
  370. package/src/apps/platform/routes/api-keys.ts +427 -0
  371. package/src/apps/platform/routes/invitations.test.ts +361 -0
  372. package/src/apps/platform/routes/invitations.ts +519 -0
  373. package/src/apps/platform/routes/me.test.ts +121 -0
  374. package/src/apps/platform/routes/me.ts +106 -0
  375. package/src/apps/platform/routes/members.test.ts +195 -0
  376. package/src/apps/platform/routes/members.ts +313 -0
  377. package/src/apps/platform/routes/orgs.test.ts +313 -0
  378. package/src/apps/platform/routes/orgs.ts +343 -0
  379. package/src/apps/platform/routes/projects.test.ts +181 -0
  380. package/src/apps/platform/routes/projects.ts +367 -0
  381. package/src/apps/relay/App.test.ts +484 -0
  382. package/src/apps/relay/App.ts +128 -0
  383. package/src/apps/relay/Sponsorships.test.ts +375 -0
  384. package/src/apps/relay/Sponsorships.ts +305 -0
  385. package/src/apps/relay/index.ts +2 -0
  386. package/src/{Cli.test.ts → cli/Cli.test.ts} +10 -9
  387. package/src/{Cli.ts → cli/Cli.ts} +16 -9
  388. package/src/cli/bin.ts +4 -0
  389. package/src/cli/commands/admin.test.ts +71 -0
  390. package/src/cli/commands/admin.ts +60 -0
  391. package/src/cloudflare.ts +10 -0
  392. package/src/db/Db.test.ts +84 -0
  393. package/src/db/Db.ts +542 -0
  394. package/src/db/Schema.ts +301 -0
  395. package/src/db/tables/invitations.ts +198 -0
  396. package/src/db/tables/memberships.ts +208 -0
  397. package/src/db/tables/organizations.test.ts +160 -0
  398. package/src/db/tables/organizations.ts +232 -0
  399. package/src/db/tables/projects.ts +107 -0
  400. package/src/db/tables/sponsoredTransactions.test.ts +218 -0
  401. package/src/db/tables/sponsoredTransactions.ts +236 -0
  402. package/src/db/tables/users.ts +85 -0
  403. package/src/db/tables/verifiedTokens.ts +111 -0
  404. package/src/db/tables/webhookDeliveries.ts +159 -0
  405. package/src/db/tables/webhookSubscriptions.ts +358 -0
  406. package/src/handlers/internal/executionError.ts +207 -0
  407. package/src/handlers/internal/multisig.test.ts +818 -0
  408. package/src/handlers/internal/multisig.ts +823 -0
  409. package/src/handlers/internal/requestListener.ts +273 -0
  410. package/src/handlers/internal/sponsorship.ts +245 -0
  411. package/src/handlers/internal/types.ts +378 -0
  412. package/src/handlers/internal/utils.ts +153 -0
  413. package/src/handlers/relay.test.ts +2035 -0
  414. package/src/handlers/relay.ts +1623 -0
  415. package/src/index.ts +4 -2
  416. package/src/internal/Auth.test.ts +337 -21
  417. package/src/internal/Auth.ts +783 -44
  418. package/src/internal/Cursor.test.ts +3 -2
  419. package/src/internal/Log.test.ts +1 -1
  420. package/src/internal/Log.ts +11 -3
  421. package/src/internal/MetricSink.ts +1 -1
  422. package/src/internal/OpenApi.ts +0 -59
  423. package/src/internal/RateLimit.test.ts +1 -1
  424. package/src/internal/RpcSchema.ts +10 -0
  425. package/src/internal/Store.test.ts +150 -10
  426. package/src/internal/Store.ts +136 -11
  427. package/src/internal/Tidx.local.test.ts +1 -1
  428. package/src/internal/VerifiedTokens.test.ts +99 -115
  429. package/src/internal/VerifiedTokens.ts +123 -175
  430. package/src/internal/WebhookDestination.test.ts +1 -1
  431. package/src/internal/Webhooks.test.ts +111 -111
  432. package/src/internal/Webhooks.ts +103 -221
  433. package/dist/ApiKeySource.d.ts +0 -166
  434. package/dist/ApiKeySource.d.ts.map +0 -1
  435. package/dist/ApiKeySource.js +0 -234
  436. package/dist/ApiKeySource.js.map +0 -1
  437. package/dist/Cli.d.ts.map +0 -1
  438. package/dist/Cli.js +0 -13
  439. package/dist/Cli.js.map +0 -1
  440. package/dist/apps/activities.js.map +0 -1
  441. package/dist/apps/addresses.js.map +0 -1
  442. package/dist/apps/balances.d.ts.map +0 -1
  443. package/dist/apps/balances.js.map +0 -1
  444. package/dist/apps/blocks.d.ts.map +0 -1
  445. package/dist/apps/blocks.js.map +0 -1
  446. package/dist/apps/coingecko.d.ts.map +0 -1
  447. package/dist/apps/coingecko.js.map +0 -1
  448. package/dist/apps/exchanges.d.ts.map +0 -1
  449. package/dist/apps/exchanges.js.map +0 -1
  450. package/dist/apps/fee-amm.d.ts.map +0 -1
  451. package/dist/apps/fee-amm.js.map +0 -1
  452. package/dist/apps/indexer.d.ts.map +0 -1
  453. package/dist/apps/indexer.js.map +0 -1
  454. package/dist/apps/receipts.d.ts.map +0 -1
  455. package/dist/apps/receipts.js.map +0 -1
  456. package/dist/apps/rpc.d.ts.map +0 -1
  457. package/dist/apps/rpc.js.map +0 -1
  458. package/dist/apps/tokenlist.d.ts.map +0 -1
  459. package/dist/apps/tokenlist.js.map +0 -1
  460. package/dist/apps/tokens.d.ts.map +0 -1
  461. package/dist/apps/tokens.js.map +0 -1
  462. package/dist/apps/transactions.d.ts.map +0 -1
  463. package/dist/apps/transactions.js.map +0 -1
  464. package/dist/apps/transfers.d.ts.map +0 -1
  465. package/dist/apps/transfers.js.map +0 -1
  466. package/dist/apps/verified-tokens.d.ts.map +0 -1
  467. package/dist/apps/verified-tokens.js.map +0 -1
  468. package/dist/apps/webhooks.js.map +0 -1
  469. package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
  470. package/dist/internal/OpenApi.fonts.js.map +0 -1
  471. package/dist/internal/OpenApi.logo.d.ts.map +0 -1
  472. package/dist/internal/OpenApi.logo.js.map +0 -1
  473. package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +0 -1
  474. package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  475. package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  476. package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  477. package/seeds/31318/verified-tokens.json +0 -30
  478. package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  479. package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +0 -1
  480. package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +0 -1
  481. package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +0 -4
  482. package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +0 -30
  483. package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +0 -1
  484. package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +0 -1
  485. package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +0 -1
  486. package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +0 -11
  487. package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +0 -1
  488. package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +0 -1
  489. package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
  490. package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +0 -1
  491. package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
  492. package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +0 -1
  493. package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +0 -5
  494. package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +0 -1
  495. package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +0 -1
  496. package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +0 -1
  497. package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +0 -1
  498. package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +0 -1
  499. package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +0 -1
  500. package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +0 -1
  501. package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +0 -1
  502. package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
  503. package/seeds/4217/verified-tokens.json +0 -177
  504. package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  505. package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  506. package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  507. package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  508. package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +0 -1
  509. package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +0 -1
  510. package/seeds/42431/verified-tokens.json +0 -44
  511. package/seeds/openrpc/README.md +0 -27
  512. package/seeds/openrpc/execution-apis.json +0 -8989
  513. package/src/ApiKeySource.test-d.ts +0 -11
  514. package/src/ApiKeySource.test.ts +0 -295
  515. package/src/ApiKeySource.ts +0 -303
  516. /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
  517. /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
@@ -1,11 +1,11 @@
1
- import { Store, Webhooks as Core } from 'cadent'
2
-
3
- import * as Tidx from '../internal/Tidx.js'
4
- import * as Viem from '../internal/Viem.js'
5
- import * as TestApp from '../../test/App.js'
6
- import * as Mppx from '../../test/Mppx.js'
7
- import * as Runtime from '../../test/runtime.js'
8
- import * as Tempo from '../../test/Tempo.js'
1
+ import { type Db, Webhooks as Core } from 'tapimo'
2
+
3
+ import * as Tidx from '../../../internal/Tidx.js'
4
+ import * as Viem from '../../../internal/Viem.js'
5
+ import * as TestApp from '../../../../test/App.js'
6
+ import * as Mppx from '../../../../test/Mppx.js'
7
+ import * as Runtime from '../../../../test/runtime.js'
8
+ import * as Tempo from '../../../../test/Tempo.js'
9
9
  import * as Webhooks from './webhooks.js'
10
10
 
11
11
  /** API key with both webhook scopes, owned by `org_test`. */
@@ -14,7 +14,7 @@ const writer = {
14
14
  orgId: 'org_test',
15
15
  scopes: ['webhooks:read', 'webhooks:write'],
16
16
  token: 'secret_writer',
17
- } satisfies TestApp.source.Key
17
+ } satisfies TestApp.kvStore.Key
18
18
 
19
19
  /** API key with read-only webhook scope, owned by `org_test`. */
20
20
  const reader = {
@@ -22,7 +22,7 @@ const reader = {
22
22
  orgId: 'org_test',
23
23
  scopes: ['webhooks:read'],
24
24
  token: 'secret_reader',
25
- } satisfies TestApp.source.Key
25
+ } satisfies TestApp.kvStore.Key
26
26
 
27
27
  /** API key in a different org, used to prove owner isolation. */
28
28
  const other = {
@@ -30,13 +30,12 @@ const other = {
30
30
  orgId: 'org_other',
31
31
  scopes: ['webhooks:read', 'webhooks:write'],
32
32
  token: 'secret_other',
33
- } satisfies TestApp.source.Key
33
+ } satisfies TestApp.kvStore.Key
34
34
 
35
- /** Creates a webhooks-enabled test client backed by an in-memory state store. */
36
- function client(keys: readonly TestApp.source.Key[] = [writer, reader, other]) {
35
+ /** Creates a webhooks-enabled test client backed by an in-memory state db. */
36
+ function client(keys: readonly TestApp.kvStore.Key[] = [writer, reader, other]) {
37
37
  return TestApp.client({
38
- auth: { source: TestApp.source({ keys }) },
39
- webhook: { store: Store.memory() },
38
+ auth: { keys },
40
39
  })
41
40
  }
42
41
 
@@ -52,7 +51,7 @@ const validBody = {
52
51
  } as const
53
52
 
54
53
  describe('feature gate', () => {
55
- test('returns 404 when no state store is configured', async () => {
54
+ test('returns 404 when webhooks are disabled', async () => {
56
55
  // Routes stay mounted for a stable schema, but the resource is disabled.
57
56
  // `event-types` requires `data:read`, so seed a key that holds it to reach
58
57
  // the feature gate rather than tripping the scope check first.
@@ -61,8 +60,8 @@ describe('feature gate', () => {
61
60
  orgId: 'org_test',
62
61
  scopes: ['data:read'],
63
62
  token: 'secret_data_reader',
64
- } satisfies TestApp.source.Key
65
- const disabled = TestApp.client({ auth: { source: TestApp.source({ keys: [dataReader] }) } })
63
+ } satisfies TestApp.kvStore.Key
64
+ const disabled = TestApp.client({ auth: { keys: [dataReader] }, webhook: false })
66
65
  const response = await disabled.v1.webhooks['event-types'].$get({}, as(dataReader))
67
66
 
68
67
  expect(response.status).toMatchInlineSnapshot(`404`)
@@ -97,7 +96,7 @@ describe('access matrix', () => {
97
96
  orgId: 'org_test',
98
97
  scopes: ['data:read'],
99
98
  token: 'secret_noscope',
100
- } satisfies TestApp.source.Key
99
+ } satisfies TestApp.kvStore.Key
101
100
  const response = await client([noScope]).v1.webhooks.$get({ query: {} }, as(noScope))
102
101
  const body = (await response.json()) as { error?: { code?: string } }
103
102
 
@@ -142,7 +141,7 @@ describe('access matrix', () => {
142
141
  orgId: 'org_test',
143
142
  scopes: ['data:read'],
144
143
  token: 'secret_data_reader',
145
- } satisfies TestApp.source.Key
144
+ } satisfies TestApp.kvStore.Key
146
145
  const response = await client([dataReader]).v1.webhooks['event-types'].$get({}, as(dataReader))
147
146
 
148
147
  expect(response.status).toMatchInlineSnapshot(`200`)
@@ -272,8 +271,8 @@ describe('owner isolation', () => {
272
271
  describe('subscription limits', () => {
273
272
  test('rejects creation past the configured per-owner cap with 403 limit_exceeded', async () => {
274
273
  const app = TestApp.client({
275
- auth: { source: TestApp.source({ keys: [writer, other] }) },
276
- webhook: { maxPerOwner: 2, store: Store.memory() },
274
+ auth: { keys: [writer, other] },
275
+ webhook: { maxPerOwner: 2 },
277
276
  })
278
277
 
279
278
  // Fill the writer's quota.
@@ -317,20 +316,20 @@ describe('delivery log', () => {
317
316
  }
318
317
 
319
318
  /** Seeds a subscription owned by `writer` plus `count` delivery rows. */
320
- async function seed(store: ReturnType<typeof Store.memory>, count: number) {
319
+ async function seed(db: Db.Db, count: number) {
321
320
  const app = TestApp.client({
322
- auth: { source: TestApp.source({ keys: [writer, reader, other] }) },
323
- webhook: { store },
321
+ auth: { keys: [writer, reader, other] },
322
+ db,
324
323
  })
325
324
  const created = await app.v1.webhooks.$post({ json: validBody }, as(writer))
326
325
  const { id } = await TestApp.json(created, Webhooks.schema.createWebhook.Response)
327
- for (let n = 1; n <= count; n++) await Core.recordDelivery(store, row(id, n))
326
+ for (let n = 1; n <= count; n++) await Core.recordDelivery(db, row(id, n))
328
327
  return { app, id }
329
328
  }
330
329
 
331
330
  test('lists a subscription deliveries newest-first', async () => {
332
- const store = Store.memory()
333
- const { app, id } = await seed(store, 3)
331
+ const db = TestApp.database()
332
+ const { app, id } = await seed(db, 3)
334
333
 
335
334
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
336
335
  { param: { id }, query: {} },
@@ -349,8 +348,8 @@ describe('delivery log', () => {
349
348
  })
350
349
 
351
350
  test('embeds the exact delivery total via include=totalCount', async () => {
352
- const store = Store.memory()
353
- const { app, id } = await seed(store, 8)
351
+ const db = TestApp.database()
352
+ const { app, id } = await seed(db, 8)
354
353
 
355
354
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
356
355
  { param: { id }, query: { include: 'totalCount', limit: '5' } },
@@ -372,8 +371,8 @@ describe('delivery log', () => {
372
371
  })
373
372
 
374
373
  test('paginates with cursor and limit', async () => {
375
- const store = Store.memory()
376
- const { app, id } = await seed(store, 6)
374
+ const db = TestApp.database()
375
+ const { app, id } = await seed(db, 6)
377
376
 
378
377
  const first = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
379
378
  { param: { id }, query: { limit: '5' } },
@@ -397,8 +396,8 @@ describe('delivery log', () => {
397
396
  })
398
397
 
399
398
  test('serves a positional page via `page` (deterministic in-memory slice)', async () => {
400
- const store = Store.memory()
401
- const { app, id } = await seed(store, 6)
399
+ const db = TestApp.database()
400
+ const { app, id } = await seed(db, 6)
402
401
 
403
402
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
404
403
  { param: { id }, query: { limit: '5', page: '2' } },
@@ -411,8 +410,8 @@ describe('delivery log', () => {
411
410
  })
412
411
 
413
412
  test('rejects `page` combined with `cursor`', async () => {
414
- const store = Store.memory()
415
- const { app, id } = await seed(store, 6)
413
+ const db = TestApp.database()
414
+ const { app, id } = await seed(db, 6)
416
415
 
417
416
  const first = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
418
417
  { param: { id }, query: { limit: '5' } },
@@ -428,8 +427,8 @@ describe('delivery log', () => {
428
427
  })
429
428
 
430
429
  test('a read-only key can list deliveries', async () => {
431
- const store = Store.memory()
432
- const { app, id } = await seed(store, 1)
430
+ const db = TestApp.database()
431
+ const { app, id } = await seed(db, 1)
433
432
 
434
433
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
435
434
  { param: { id }, query: {} },
@@ -439,8 +438,8 @@ describe('delivery log', () => {
439
438
  })
440
439
 
441
440
  test('a different org cannot read another org deliveries', async () => {
442
- const store = Store.memory()
443
- const { app, id } = await seed(store, 1)
441
+ const db = TestApp.database()
442
+ const { app, id } = await seed(db, 1)
444
443
 
445
444
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries.$get(
446
445
  { param: { id }, query: {} },
@@ -491,8 +490,7 @@ describe('SSRF protection', () => {
491
490
  describe('subscription context', () => {
492
491
  test('round-trips context through create and read', async () => {
493
492
  const app = TestApp.client({
494
- auth: { source: TestApp.source({ keys: [writer] }) },
495
- webhook: { store: Store.memory() },
493
+ auth: { keys: [writer] },
496
494
  })
497
495
  const context = {
498
496
  description: 'Notify #ops when a large USDC transfer settles.',
@@ -523,8 +521,7 @@ describe('subscription context', () => {
523
521
 
524
522
  test('clears context with an explicit null patch', async () => {
525
523
  const app = TestApp.client({
526
- auth: { source: TestApp.source({ keys: [writer] }) },
527
- webhook: { store: Store.memory() },
524
+ auth: { keys: [writer] },
528
525
  })
529
526
  const created = await app.v1.webhooks.$post(
530
527
  {
@@ -548,8 +545,7 @@ describe('subscription context', () => {
548
545
 
549
546
  test('rejects metadata that exceeds the entry limit', async () => {
550
547
  const app = TestApp.client({
551
- auth: { source: TestApp.source({ keys: [writer] }) },
552
- webhook: { store: Store.memory() },
548
+ auth: { keys: [writer] },
553
549
  })
554
550
  const metadata = Object.fromEntries(Array.from({ length: 21 }, (_, i) => [`key${i}`, 'value']))
555
551
  const created = await app.v1.webhooks.$post(
@@ -569,8 +565,7 @@ describe('subscription context', () => {
569
565
  describe('slack destination', () => {
570
566
  test('creates a subscription with a slack incoming-webhook URL', async () => {
571
567
  const app = TestApp.client({
572
- auth: { source: TestApp.source({ keys: [writer] }) },
573
- webhook: { store: Store.memory() },
568
+ auth: { keys: [writer] },
574
569
  })
575
570
  const created = await app.v1.webhooks.$post(
576
571
  {
@@ -596,8 +591,7 @@ describe('slack destination', () => {
596
591
 
597
592
  test('rejects a slack destination whose host is not hooks.slack.com', async () => {
598
593
  const app = TestApp.client({
599
- auth: { source: TestApp.source({ keys: [writer] }) },
600
- webhook: { store: Store.memory() },
594
+ auth: { keys: [writer] },
601
595
  })
602
596
  const response = await app.v1.webhooks.$post(
603
597
  {
@@ -618,8 +612,7 @@ describe('slack destination', () => {
618
612
  describe('betterstack destination', () => {
619
613
  test('creates a subscription with a Better Stack source', async () => {
620
614
  const app = TestApp.client({
621
- auth: { source: TestApp.source({ keys: [writer] }) },
622
- webhook: { store: Store.memory() },
615
+ auth: { keys: [writer] },
623
616
  })
624
617
  const created = await app.v1.webhooks.$post(
625
618
  {
@@ -647,8 +640,7 @@ describe('betterstack destination', () => {
647
640
 
648
641
  test('rejects a Better Stack destination whose host is not betterstackdata.com', async () => {
649
642
  const app = TestApp.client({
650
- auth: { source: TestApp.source({ keys: [writer] }) },
651
- webhook: { store: Store.memory() },
643
+ auth: { keys: [writer] },
652
644
  })
653
645
  const response = await app.v1.webhooks.$post(
654
646
  {
@@ -678,8 +670,7 @@ describe('ping', () => {
678
670
  /** Seeds a webhooks-enabled client with a subscription owned by `writer`. */
679
671
  async function seed() {
680
672
  const app = TestApp.client({
681
- auth: { source: TestApp.source({ keys: [writer, reader, other] }) },
682
- webhook: { store: Store.memory() },
673
+ auth: { keys: [writer, reader, other] },
683
674
  })
684
675
  const created = await app.v1.webhooks.$post({ json: validBody }, as(writer))
685
676
  const { id } = await TestApp.json(created, Webhooks.schema.createWebhook.Response)
@@ -775,14 +766,14 @@ describe('retry delivery', () => {
775
766
 
776
767
  /** Seeds a webhooks client with a subscription plus one logged delivery to replay. */
777
768
  async function seed() {
778
- const store = Store.memory()
769
+ const db = TestApp.database()
779
770
  const app = TestApp.client({
780
- auth: { source: TestApp.source({ keys: [writer, reader, other] }) },
781
- webhook: { store },
771
+ auth: { keys: [writer, reader, other] },
772
+ db,
782
773
  })
783
774
  const created = await app.v1.webhooks.$post({ json: validBody }, as(writer))
784
775
  const { id } = await TestApp.json(created, Webhooks.schema.createWebhook.Response)
785
- await Core.recordDelivery(store, {
776
+ await Core.recordDelivery(db, {
786
777
  attempt: 1,
787
778
  createdAt: new Date(1_700_000_000_000).toISOString(),
788
779
  envelope: {
@@ -799,11 +790,11 @@ describe('retry delivery', () => {
799
790
  status: 'failed',
800
791
  subscriptionId: id,
801
792
  })
802
- return { app, id, store }
793
+ return { app, id, db }
803
794
  }
804
795
 
805
796
  test('replays the stored envelope and records a new attempt', async () => {
806
- const { app, id, store } = await seed()
797
+ const { app, id, db } = await seed()
807
798
  vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response(null, { status: 200 }))
808
799
 
809
800
  const response = await app.v1.webhooks[':id{wh_[A-Za-z0-9_-]+}'].deliveries[
@@ -815,7 +806,7 @@ describe('retry delivery', () => {
815
806
  expect(body.eventId).toMatchInlineSnapshot(`"evt_seed"`)
816
807
 
817
808
  // A new attempt was appended alongside the seeded row.
818
- expect(await Core.listDeliveries(store, id)).toHaveLength(2)
809
+ expect(await Core.listDeliveries(db, id)).toHaveLength(2)
819
810
  })
820
811
 
821
812
  test('a failed replay reports the error', async () => {
@@ -867,7 +858,7 @@ describe('retry delivery', () => {
867
858
 
868
859
  describe('OpenAPI visibility', () => {
869
860
  test('hides webhook routes when the feature is disabled', async () => {
870
- const app = TestApp.create({ auth: { source: TestApp.source({ keys: [writer] }) } })
861
+ const app = TestApp.create({ auth: { keys: [writer] }, webhook: false })
871
862
  const body = (await (await app.request('/openapi.json')).json()) as { paths: object }
872
863
 
873
864
  // OpenAPI paths include App.create's mounted `/v1` prefix; the webhook
@@ -877,8 +868,7 @@ describe('OpenAPI visibility', () => {
877
868
 
878
869
  test('documents webhook routes when the feature is enabled', async () => {
879
870
  const app = TestApp.create({
880
- auth: { source: TestApp.source({ keys: [writer] }) },
881
- webhook: { store: Store.memory() },
871
+ auth: { keys: [writer] },
882
872
  })
883
873
  const body = (await (await app.request('/openapi.json')).json()) as { paths: object }
884
874
  const paths = Object.keys(body.paths)
@@ -898,7 +888,7 @@ describe('OpenAPI visibility', () => {
898
888
  })
899
889
 
900
890
  test('omits the outbound `webhooks` section when the feature is disabled', async () => {
901
- const app = TestApp.create({ auth: { source: TestApp.source({ keys: [writer] }) } })
891
+ const app = TestApp.create({ auth: { keys: [writer] }, webhook: false })
902
892
  const body = (await (await app.request('/openapi.json')).json()) as { webhooks?: object }
903
893
 
904
894
  expect(body.webhooks).toMatchInlineSnapshot(`undefined`)
@@ -906,8 +896,7 @@ describe('OpenAPI visibility', () => {
906
896
 
907
897
  test('documents the outbound delivery envelope under OAS `webhooks` when enabled', async () => {
908
898
  const app = TestApp.create({
909
- auth: { source: TestApp.source({ keys: [writer] }) },
910
- webhook: { store: Store.memory() },
899
+ auth: { keys: [writer] },
911
900
  })
912
901
  const body = (await (await app.request('/openapi.json')).json()) as {
913
902
  webhooks?: {
@@ -946,8 +935,7 @@ describe('OpenAPI visibility', () => {
946
935
 
947
936
  test('documents per-event-type filters on the create body', async () => {
948
937
  const app = TestApp.create({
949
- auth: { source: TestApp.source({ keys: [writer] }) },
950
- webhook: { store: Store.memory() },
938
+ auth: { keys: [writer] },
951
939
  })
952
940
  const body = (await (await app.request('/openapi.json')).json()) as {
953
941
  paths: {
@@ -1050,7 +1038,7 @@ describe('OpenAPI visibility', () => {
1050
1038
  describe('envelope schema', () => {
1051
1039
  /** A `transfer` subscription used to build representative envelopes. */
1052
1040
  async function transferSubscription() {
1053
- const store = Store.memory()
1041
+ const db = TestApp.database()
1054
1042
  return Core.buildEnvelope({
1055
1043
  blockNumber: 100,
1056
1044
  createdAt: new Date('2026-01-01T00:00:00.000Z'),
@@ -1064,7 +1052,7 @@ describe('envelope schema', () => {
1064
1052
  transactionHash: '0x33333333333333333333333333333333333333333333333333333333333333aa',
1065
1053
  },
1066
1054
  logIndex: 0,
1067
- subscription: await Core.createSubscription(store, {
1055
+ subscription: await Core.createSubscription(db, {
1068
1056
  chainId: 42431,
1069
1057
  eventType: 'token:transfer',
1070
1058
  owner: { orgId: 'org_test', type: 'api_key' },
@@ -1080,8 +1068,8 @@ describe('envelope schema', () => {
1080
1068
  })
1081
1069
 
1082
1070
  test('round-trips a ping envelope', async () => {
1083
- const store = Store.memory()
1084
- const subscription = await Core.createSubscription(store, {
1071
+ const db = TestApp.database()
1072
+ const subscription = await Core.createSubscription(db, {
1085
1073
  chainId: 42431,
1086
1074
  eventType: 'token:transfer',
1087
1075
  owner: { orgId: 'org_test', type: 'api_key' },
@@ -1110,7 +1098,7 @@ describe('envelope schema', () => {
1110
1098
  describe('MPP access (disabled for now — API-key-only)', () => {
1111
1099
  test('rejects an MPP payer with 401, offering no payment challenge', async () => {
1112
1100
  const app = TestApp.create({
1113
- auth: { source: TestApp.source({ keys: [] }) },
1101
+ auth: { keys: [] },
1114
1102
  mpp: {
1115
1103
  charge: {
1116
1104
  chainId: Tempo.chain.id,
@@ -1121,7 +1109,6 @@ describe('MPP access (disabled for now — API-key-only)', () => {
1121
1109
  },
1122
1110
  secretKey: 'secret_test_key_0123456789abcdef',
1123
1111
  },
1124
- webhook: { store: Store.memory() },
1125
1112
  })
1126
1113
 
1127
1114
  // The paid lane is disabled on webhook routes, so no `402` challenge is
@@ -1182,8 +1169,8 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1182
1169
  // followed by its fee payment. Filtering on it makes the scan deterministic.
1183
1170
  const windowSender = '0xe7687128b0a808c2831ff94d4f7b2fb35c65af38'
1184
1171
 
1185
- async function createTransferSubscription(store: ReturnType<typeof Store.memory>) {
1186
- return Core.createSubscription(store, {
1172
+ async function createTransferSubscription(db: Db.Db) {
1173
+ return Core.createSubscription(db, {
1187
1174
  chainId: 42431,
1188
1175
  eventType: 'token:transfer',
1189
1176
  filters: { sender: windowSender },
@@ -1193,12 +1180,12 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1193
1180
  }
1194
1181
 
1195
1182
  test('dispatches a signed envelope per row and advances the cursor', async () => {
1196
- const store = Store.memory()
1197
- const subscription = await createTransferSubscription(store)
1183
+ const db = TestApp.database()
1184
+ const subscription = await createTransferSubscription(db)
1198
1185
  // Anchor the subscription just below the pinned window so the poller scans
1199
1186
  // it this tick (a brand-new subscription anchors at head and skips its first
1200
1187
  // tick).
1201
- await Core.setCursor(store, subscription.id, windowCursor)
1188
+ await Core.setCursor(db, subscription.id, windowCursor)
1202
1189
 
1203
1190
  const dispatched: Webhooks.poll.Dispatchable[] = []
1204
1191
  const result = await Webhooks.poll({
@@ -1210,7 +1197,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1210
1197
  eventTypes: ['token:transfer'],
1211
1198
  headBlockNumber: windowHead,
1212
1199
  client,
1213
- store,
1200
+ db,
1214
1201
  tidx: realTidx,
1215
1202
  })
1216
1203
 
@@ -1245,7 +1232,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1245
1232
  `)
1246
1233
 
1247
1234
  // Cursor advanced to the last dispatched row `(1000002, 1)`.
1248
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1235
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1249
1236
  [
1250
1237
  1000002,
1251
1238
  1,
@@ -1254,9 +1241,9 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1254
1241
  })
1255
1242
 
1256
1243
  test('pauses the cursor at the last success when dispatch fails', async () => {
1257
- const store = Store.memory()
1258
- const subscription = await createTransferSubscription(store)
1259
- await Core.setCursor(store, subscription.id, windowCursor)
1244
+ const db = TestApp.database()
1245
+ const subscription = await createTransferSubscription(db)
1246
+ await Core.setCursor(db, subscription.id, windowCursor)
1260
1247
 
1261
1248
  let calls = 0
1262
1249
  const result = await Webhooks.poll({
@@ -1266,7 +1253,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1266
1253
  eventTypes: ['token:transfer'],
1267
1254
  headBlockNumber: windowHead,
1268
1255
  client,
1269
- store,
1256
+ db,
1270
1257
  tidx: realTidx,
1271
1258
  })
1272
1259
 
@@ -1275,7 +1262,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1275
1262
 
1276
1263
  // Cursor stops at the first (successful) row `(1000002, 0)`, so the failed
1277
1264
  // one re-runs on the next tick (at-least-once).
1278
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1265
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1279
1266
  [
1280
1267
  1000002,
1281
1268
  0,
@@ -1284,9 +1271,9 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1284
1271
  })
1285
1272
 
1286
1273
  test('does not advance the cursor when the first row fails', async () => {
1287
- const store = Store.memory()
1288
- const subscription = await createTransferSubscription(store)
1289
- await Core.setCursor(store, subscription.id, windowCursor)
1274
+ const db = TestApp.database()
1275
+ const subscription = await createTransferSubscription(db)
1276
+ await Core.setCursor(db, subscription.id, windowCursor)
1290
1277
 
1291
1278
  const result = await Webhooks.poll({
1292
1279
  chainId: 42431,
@@ -1294,7 +1281,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1294
1281
  eventTypes: ['token:transfer'],
1295
1282
  headBlockNumber: windowHead,
1296
1283
  client,
1297
- store,
1284
+ db,
1298
1285
  tidx: realTidx,
1299
1286
  })
1300
1287
 
@@ -1302,7 +1289,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1302
1289
  expect(result.failed).toMatchInlineSnapshot(`1`)
1303
1290
  // Nothing accepted → cursor untouched at the window anchor, so the row
1304
1291
  // retries next tick.
1305
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1292
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1306
1293
  [
1307
1294
  999999,
1308
1295
  2147483647,
@@ -1311,8 +1298,8 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1311
1298
  })
1312
1299
 
1313
1300
  test('anchors a first-seen subscription at the confirmed head without backfilling', async () => {
1314
- const store = Store.memory()
1315
- const subscription = await createTransferSubscription(store)
1301
+ const db = TestApp.database()
1302
+ const subscription = await createTransferSubscription(db)
1316
1303
 
1317
1304
  const dispatched: Webhooks.poll.Dispatchable[] = []
1318
1305
  const result = await Webhooks.poll({
@@ -1324,7 +1311,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1324
1311
  eventTypes: ['token:transfer'],
1325
1312
  headBlockNumber: windowHead,
1326
1313
  client,
1327
- store,
1314
+ db,
1328
1315
  // Rows exist in history, but a brand-new subscription must not replay them.
1329
1316
  tidx: realTidx,
1330
1317
  })
@@ -1333,7 +1320,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1333
1320
  // the head of the confirmed window (`windowHead - confirmations` = 1000002).
1334
1321
  expect(result.scanned).toMatchInlineSnapshot(`0`)
1335
1322
  expect(dispatched).toHaveLength(0)
1336
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1323
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1337
1324
  [
1338
1325
  1000002,
1339
1326
  2147483647,
@@ -1342,12 +1329,12 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1342
1329
  })
1343
1330
 
1344
1331
  test('advances to the end of the confirmed window on an empty scan', async () => {
1345
- const store = Store.memory()
1346
- const subscription = await createTransferSubscription(store)
1332
+ const db = TestApp.database()
1333
+ const subscription = await createTransferSubscription(db)
1347
1334
  // Anchor just past the window's only matching block (1000002) and confirm up
1348
1335
  // to block 1000004 — a range `windowSender` has no transfers in, so the scan
1349
1336
  // is genuinely empty.
1350
- await Core.setCursor(store, subscription.id, encodeCursor([windowTo, endOfBlockIndex]))
1337
+ await Core.setCursor(db, subscription.id, encodeCursor([windowTo, endOfBlockIndex]))
1351
1338
 
1352
1339
  const result = await Webhooks.poll({
1353
1340
  chainId: 42431,
@@ -1355,7 +1342,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1355
1342
  eventTypes: ['token:transfer'],
1356
1343
  headBlockNumber: windowTo + 4,
1357
1344
  client,
1358
- store,
1345
+ db,
1359
1346
  tidx: realTidx,
1360
1347
  })
1361
1348
 
@@ -1363,7 +1350,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1363
1350
 
1364
1351
  // No rows, clean scan: cursor jumps past the end of the confirmed window
1365
1352
  // (`headBlockNumber - confirmations` = block 1000004) so it is not rescanned.
1366
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1353
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1367
1354
  [
1368
1355
  1000004,
1369
1356
  2147483647,
@@ -1381,15 +1368,15 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1381
1368
  const windowSenderTopic = `0x${'0'.repeat(24)}${windowSender.slice(2)}`
1382
1369
 
1383
1370
  test('log:emitted decodes args from a signature-matched event view', async () => {
1384
- const store = Store.memory()
1385
- const subscription = await Core.createSubscription(store, {
1371
+ const db = TestApp.database()
1372
+ const subscription = await Core.createSubscription(db, {
1386
1373
  chainId: 42431,
1387
1374
  eventType: 'log:emitted',
1388
1375
  filters: { signature: transferSignature, args: { from: windowSender } },
1389
1376
  owner: { orgId: 'org_test', type: 'api_key' },
1390
1377
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1391
1378
  })
1392
- await Core.setCursor(store, subscription.id, windowCursor)
1379
+ await Core.setCursor(db, subscription.id, windowCursor)
1393
1380
 
1394
1381
  const dispatched: Webhooks.poll.Dispatchable[] = []
1395
1382
  const result = await Webhooks.poll({
@@ -1401,7 +1388,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1401
1388
  eventTypes: ['log:emitted'],
1402
1389
  headBlockNumber: windowHead,
1403
1390
  client,
1404
- store,
1391
+ db,
1405
1392
  tidx: realTidx,
1406
1393
  })
1407
1394
 
@@ -1435,15 +1422,15 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1435
1422
  })
1436
1423
 
1437
1424
  test('log:emitted scans raw logs by topic when no signature is given', async () => {
1438
- const store = Store.memory()
1439
- const subscription = await Core.createSubscription(store, {
1425
+ const db = TestApp.database()
1426
+ const subscription = await Core.createSubscription(db, {
1440
1427
  chainId: 42431,
1441
1428
  eventType: 'log:emitted',
1442
1429
  filters: { topic0: transferSelector, topic1: windowSenderTopic },
1443
1430
  owner: { orgId: 'org_test', type: 'api_key' },
1444
1431
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1445
1432
  })
1446
- await Core.setCursor(store, subscription.id, windowCursor)
1433
+ await Core.setCursor(db, subscription.id, windowCursor)
1447
1434
 
1448
1435
  const dispatched: Webhooks.poll.Dispatchable[] = []
1449
1436
  const result = await Webhooks.poll({
@@ -1455,7 +1442,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1455
1442
  eventTypes: ['log:emitted'],
1456
1443
  headBlockNumber: windowHead,
1457
1444
  client,
1458
- store,
1445
+ db,
1459
1446
  tidx: realTidx,
1460
1447
  })
1461
1448
 
@@ -1479,8 +1466,8 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1479
1466
  })
1480
1467
 
1481
1468
  test('block:created scans new blocks and resolves transaction counts', async () => {
1482
- const store = Store.memory()
1483
- const subscription = await Core.createSubscription(store, {
1469
+ const db = TestApp.database()
1470
+ const subscription = await Core.createSubscription(db, {
1484
1471
  chainId: 42431,
1485
1472
  eventType: 'block:created',
1486
1473
  // Pin to a single block so the heartbeat feed is deterministic.
@@ -1488,7 +1475,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1488
1475
  owner: { orgId: 'org_test', type: 'api_key' },
1489
1476
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1490
1477
  })
1491
- await Core.setCursor(store, subscription.id, windowCursor)
1478
+ await Core.setCursor(db, subscription.id, windowCursor)
1492
1479
 
1493
1480
  const dispatched: Webhooks.poll.Dispatchable[] = []
1494
1481
  const result = await Webhooks.poll({
@@ -1500,7 +1487,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1500
1487
  eventTypes: ['block:created'],
1501
1488
  headBlockNumber: windowHead,
1502
1489
  client,
1503
- store,
1490
+ db,
1504
1491
  tidx: realTidx,
1505
1492
  })
1506
1493
 
@@ -1519,7 +1506,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1519
1506
  `)
1520
1507
  // The window scanner advances to the end of the fully-scanned block so the
1521
1508
  // next tick resumes at the following block.
1522
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
1509
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toMatchInlineSnapshot(`
1523
1510
  [
1524
1511
  1000002,
1525
1512
  2147483647,
@@ -1528,8 +1515,8 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1528
1515
  })
1529
1516
 
1530
1517
  test('transaction:included filters on txs columns and inner calls', async () => {
1531
- const store = Store.memory()
1532
- const subscription = await Core.createSubscription(store, {
1518
+ const db = TestApp.database()
1519
+ const subscription = await Core.createSubscription(db, {
1533
1520
  chainId: 42431,
1534
1521
  eventType: 'transaction:included',
1535
1522
  // `from` + an `input` selector (ERC20 `transfer` = 0xa9059cbb) pins the
@@ -1538,7 +1525,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1538
1525
  owner: { orgId: 'org_test', type: 'api_key' },
1539
1526
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1540
1527
  })
1541
- await Core.setCursor(store, subscription.id, windowCursor)
1528
+ await Core.setCursor(db, subscription.id, windowCursor)
1542
1529
 
1543
1530
  const dispatched: Webhooks.poll.Dispatchable[] = []
1544
1531
  const result = await Webhooks.poll({
@@ -1550,7 +1537,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1550
1537
  eventTypes: ['transaction:included'],
1551
1538
  headBlockNumber: windowHead,
1552
1539
  client,
1553
- store,
1540
+ db,
1554
1541
  tidx: realTidx,
1555
1542
  })
1556
1543
 
@@ -1563,15 +1550,15 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1563
1550
  })
1564
1551
 
1565
1552
  test('transaction:included routes a status filter through receipts', async () => {
1566
- const store = Store.memory()
1567
- const subscription = await Core.createSubscription(store, {
1553
+ const db = TestApp.database()
1554
+ const subscription = await Core.createSubscription(db, {
1568
1555
  chainId: 42431,
1569
1556
  eventType: 'transaction:included',
1570
1557
  filters: { from: windowSender, status: 'success' },
1571
1558
  owner: { orgId: 'org_test', type: 'api_key' },
1572
1559
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1573
1560
  })
1574
- await Core.setCursor(store, subscription.id, windowCursor)
1561
+ await Core.setCursor(db, subscription.id, windowCursor)
1575
1562
 
1576
1563
  const result = await Webhooks.poll({
1577
1564
  chainId: 42431,
@@ -1579,7 +1566,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1579
1566
  eventTypes: ['transaction:included'],
1580
1567
  headBlockNumber: windowHead,
1581
1568
  client,
1582
- store,
1569
+ db,
1583
1570
  tidx: realTidx,
1584
1571
  })
1585
1572
 
@@ -1588,8 +1575,8 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1588
1575
  })
1589
1576
 
1590
1577
  test('transaction:included embeds the receipt when includeReceipt is set', async () => {
1591
- const store = Store.memory()
1592
- const subscription = await Core.createSubscription(store, {
1578
+ const db = TestApp.database()
1579
+ const subscription = await Core.createSubscription(db, {
1593
1580
  chainId: 42431,
1594
1581
  eventType: 'transaction:included',
1595
1582
  // No receipt-touching filter — `includeReceipt` alone must trigger the
@@ -1598,7 +1585,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1598
1585
  owner: { orgId: 'org_test', type: 'api_key' },
1599
1586
  destination: { type: 'url', url: 'https://hooks.example.com/x' },
1600
1587
  })
1601
- await Core.setCursor(store, subscription.id, windowCursor)
1588
+ await Core.setCursor(db, subscription.id, windowCursor)
1602
1589
 
1603
1590
  const dispatched: Webhooks.poll.Dispatchable[] = []
1604
1591
  const result = await Webhooks.poll({
@@ -1610,7 +1597,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1610
1597
  eventTypes: ['transaction:included'],
1611
1598
  headBlockNumber: windowHead,
1612
1599
  client,
1613
- store,
1600
+ db,
1614
1601
  tidx: realTidx,
1615
1602
  })
1616
1603
 
@@ -1634,9 +1621,9 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1634
1621
  })
1635
1622
 
1636
1623
  test('delivers a verifiable signed envelope and records success', async () => {
1637
- const store = Store.memory()
1638
- const subscription = await createTransferSubscription(store)
1639
- await Core.setCursor(store, subscription.id, windowCursor)
1624
+ const db = TestApp.database()
1625
+ const subscription = await createTransferSubscription(db)
1626
+ await Core.setCursor(db, subscription.id, windowCursor)
1640
1627
 
1641
1628
  // Real TIDX queries also go through `globalThis.fetch`, so the mock passes
1642
1629
  // non-webhook requests through to the real network and only captures the
@@ -1663,7 +1650,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1663
1650
  eventTypes: ['token:transfer'],
1664
1651
  headBlockNumber: windowHead,
1665
1652
  client,
1666
- store,
1653
+ db,
1667
1654
  tidx: realTidx,
1668
1655
  })
1669
1656
 
@@ -1687,16 +1674,16 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1687
1674
  expect((envelope.data as { blockNumber: number }).blockNumber).toBe(windowTo)
1688
1675
 
1689
1676
  // Success resets the failure counter, stamps lastDeliveryAt, stays active.
1690
- const after = await Core.getSubscription(store, subscription.owner, subscription.id)
1677
+ const after = await Core.getSubscription(db, subscription.owner, subscription.id)
1691
1678
  expect(after?.status).toBe('active')
1692
1679
  expect(after?.failureCount).toBe(0)
1693
1680
  expect(after?.lastDeliveryAt).toBeDefined()
1694
1681
  })
1695
1682
 
1696
1683
  test('pauses on a failed delivery and re-delivers on the next tick', async () => {
1697
- const store = Store.memory()
1698
- const subscription = await createTransferSubscription(store)
1699
- await Core.setCursor(store, subscription.id, windowCursor)
1684
+ const db = TestApp.database()
1685
+ const subscription = await createTransferSubscription(db)
1686
+ await Core.setCursor(db, subscription.id, windowCursor)
1700
1687
 
1701
1688
  const realFetch = globalThis.fetch.bind(globalThis)
1702
1689
  let attempts = 0
@@ -1715,7 +1702,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1715
1702
  eventTypes: ['token:transfer'],
1716
1703
  headBlockNumber: windowHead,
1717
1704
  client,
1718
- store,
1705
+ db,
1719
1706
  tidx: realTidx,
1720
1707
  })
1721
1708
 
@@ -1723,7 +1710,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1723
1710
  expect(first.failed).toBe(1)
1724
1711
  expect(first.dispatched).toBe(0)
1725
1712
  // Cursor paused at the prior position so the row re-delivers next tick.
1726
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toEqual([
1713
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toEqual([
1727
1714
  windowFrom - 1,
1728
1715
  endOfBlockIndex,
1729
1716
  ])
@@ -1732,13 +1719,13 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1732
1719
  expect(second.dispatched).toBe(1)
1733
1720
  expect(attempts).toBe(2)
1734
1721
  // Now advanced past the redelivered row (the first row in block 1000002).
1735
- expect(decodeCursor(await Core.getCursor(store, subscription.id))).toEqual([windowTo, 0])
1722
+ expect(decodeCursor(await Core.getCursor(db, subscription.id))).toEqual([windowTo, 0])
1736
1723
  })
1737
1724
 
1738
1725
  test('auto-disables a subscription after sustained failures', async () => {
1739
- const store = Store.memory()
1740
- const subscription = await createTransferSubscription(store)
1741
- await Core.setCursor(store, subscription.id, windowCursor)
1726
+ const db = TestApp.database()
1727
+ const subscription = await createTransferSubscription(db)
1728
+ await Core.setCursor(db, subscription.id, windowCursor)
1742
1729
 
1743
1730
  // Real TIDX queries pass through; only the webhook delivery fails (500).
1744
1731
  const realFetch = globalThis.fetch.bind(globalThis)
@@ -1756,7 +1743,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1756
1743
  eventTypes: ['token:transfer'],
1757
1744
  headBlockNumber: windowHead,
1758
1745
  client,
1759
- store,
1746
+ db,
1760
1747
  tidx: realTidx,
1761
1748
  })
1762
1749
 
@@ -1764,7 +1751,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1764
1751
  // subscription auto-disables and drops out of the poller's active index.
1765
1752
  for (let i = 0; i < Core.maxFailures; i++) await tick()
1766
1753
 
1767
- const disabled = await Core.getSubscription(store, subscription.owner, subscription.id)
1754
+ const disabled = await Core.getSubscription(db, subscription.owner, subscription.id)
1768
1755
  expect(disabled?.status).toBe('disabled')
1769
1756
  expect(disabled?.failureCount).toBe(Core.maxFailures)
1770
1757
 
@@ -1781,10 +1768,10 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1781
1768
  // proves the route-issued secret and id line up with what is delivered/logged.
1782
1769
  describe('end-to-end (routes + poller)', () => {
1783
1770
  test('create → poll → signed delivery → deliveries route records success', async () => {
1784
- const store = Store.memory()
1771
+ const db = TestApp.database()
1785
1772
  const app = TestApp.client({
1786
- auth: { source: TestApp.source({ keys: [writer] }) },
1787
- webhook: { store },
1773
+ auth: { keys: [writer] },
1774
+ db,
1788
1775
  })
1789
1776
 
1790
1777
  // 1. Create through the route; capture the one-time signing secret + id.
@@ -1799,7 +1786,7 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1799
1786
  // Anchor the cursor just below the window so the poller scans this tick (a
1800
1787
  // brand-new subscription anchors at the confirmed head and skips its first
1801
1788
  // tick).
1802
- await Core.setCursor(store, id, windowCursor)
1789
+ await Core.setCursor(db, id, windowCursor)
1803
1790
 
1804
1791
  // 2. A local delivery sink that captures the request and acks 200, injected
1805
1792
  // via `deliverAndRecord`'s `fetch` option (the SSRF guard blocks loopback,
@@ -1821,11 +1808,11 @@ describe.skipIf(Runtime.get().mode === 'localnet')('poll', () => {
1821
1808
  batchSize: 1,
1822
1809
  chainId: 42431,
1823
1810
  dispatch: ({ envelope, subscription }) =>
1824
- Core.deliverAndRecord(store, subscription, envelope, { fetch }),
1811
+ Core.deliverAndRecord(db, subscription, envelope, { fetch }),
1825
1812
  eventTypes: ['token:transfer'],
1826
1813
  headBlockNumber: windowHead,
1827
1814
  client,
1828
- store,
1815
+ db,
1829
1816
  tidx: realTidx,
1830
1817
  })
1831
1818
  expect(result.dispatched).toBe(1)