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,10 +1,12 @@
1
1
  import { nanoid } from 'nanoid'
2
2
  import { Hash, Hex } from 'ox'
3
3
 
4
- import type * as app_Webhooks from '../apps/webhooks.js'
4
+ import type * as app_Webhooks from '../apps/data/routes/webhooks.js'
5
+ import type * as Db from '../db/Db.js'
6
+ import * as WebhookDeliveries from '../db/tables/webhookDeliveries.js'
7
+ import * as WebhookSubscriptions from '../db/tables/webhookSubscriptions.js'
5
8
  import type * as Metrics from '../Metrics.js'
6
9
  import * as MetricSink from './MetricSink.js'
7
- import * as Store from './Store.js'
8
10
  import * as WebhookDestination from './WebhookDestination.js'
9
11
 
10
12
  // The destination layer lives in `./WebhookDestination.js`. Re-export only the
@@ -159,22 +161,24 @@ export type Delivery = {
159
161
 
160
162
  /**
161
163
  * Creates a subscription, validating its URL and (optionally) enforcing a
162
- * per-owner cap, then persists it and indexes it for the poller.
164
+ * per-owner cap, then persists it. The cap check stays best-effort (count then
165
+ * insert, non-transactional) — parity with the old store behavior.
163
166
  */
164
167
  export async function createSubscription(
165
- store: Store.State,
168
+ db: Db.Db,
166
169
  input: CreateInput,
167
170
  options: createSubscription.Options = {},
168
171
  ): Promise<Subscription> {
169
172
  WebhookDestination.assertDestination(input.destination)
170
173
 
174
+ const now = (options.now ?? (() => new Date()))()
175
+ const iso = now.toISOString()
176
+
171
177
  if (options.maxPerOwner !== undefined) {
172
- const existing = await listSubscriptions(store, input.owner)
173
- if (existing.length >= options.maxPerOwner) throw new LimitExceededError(options.maxPerOwner)
178
+ const existing = await WebhookSubscriptions.count(db, input.owner, iso)
179
+ if (existing >= options.maxPerOwner) throw new LimitExceededError(options.maxPerOwner)
174
180
  }
175
181
 
176
- const now = (options.now ?? (() => new Date()))()
177
- const iso = now.toISOString()
178
182
  const subscription: Subscription = {
179
183
  chainId: input.chainId,
180
184
  ...(input.context === undefined ? {} : { context: input.context }),
@@ -193,7 +197,7 @@ export async function createSubscription(
193
197
  : { expiresAt: new Date(now.getTime() + input.ttl).toISOString() }),
194
198
  }
195
199
 
196
- await writeSubscription(store, subscription)
200
+ await WebhookSubscriptions.insert(db, subscription)
197
201
  return subscription
198
202
  }
199
203
 
@@ -209,39 +213,23 @@ export declare namespace createSubscription {
209
213
 
210
214
  /** Reads a single subscription scoped to its owner. Returns null when absent. */
211
215
  export async function getSubscription(
212
- store: Store.State,
216
+ db: Db.Db,
213
217
  owner: Owner,
214
218
  id: string,
215
219
  ): Promise<Subscription | null> {
216
- return readSubscription(store, subscriptionKey(owner, id))
220
+ return WebhookSubscriptions.get(db, owner, id, new Date().toISOString())
217
221
  }
218
222
 
219
223
  /**
220
224
  * Lists an owner's subscriptions, newest first, with optional keyset paging.
221
- * Subscription ids embed a timestamp, so lexical key order is chronological.
225
+ * Subscription ids embed a timestamp, so lexical id order is chronological.
222
226
  */
223
227
  export async function listSubscriptions(
224
- store: Store.State,
228
+ db: Db.Db,
225
229
  owner: Owner,
226
230
  options: listSubscriptions.Options = {},
227
231
  ): Promise<Subscription[]> {
228
- const prefix = subscriptionPrefix(owner)
229
- const { keys } = await store.list({ prefix })
230
-
231
- // Newest first: ids sort chronologically ascending, so reverse for descending.
232
- let names = keys
233
- .map((key) => key.name)
234
- .sort()
235
- .reverse()
236
- if (options.cursor) names = names.filter((name) => name < `${prefix}${options.cursor}`)
237
- if (options.offset) names = names.slice(options.offset)
238
- if (options.limit !== undefined) names = names.slice(0, options.limit)
239
-
240
- // Hydrate the page in parallel: the reads are independent, and a serial
241
- // loop costs one store round trip per row (an N+1 against the production
242
- // Durable Object).
243
- const subscriptions = await Promise.all(names.map((name) => readSubscription(store, name)))
244
- return subscriptions.filter((subscription) => subscription !== null)
232
+ return WebhookSubscriptions.list(db, owner, { ...options, now: new Date().toISOString() })
245
233
  }
246
234
 
247
235
  export declare namespace listSubscriptions {
@@ -257,47 +245,41 @@ export declare namespace listSubscriptions {
257
245
  }
258
246
 
259
247
  /**
260
- * Counts an owner's subscriptions. Reads only the key set under the owner
261
- * prefix (no row hydration), so it's a single store `list` — exact and cheap,
248
+ * Counts an owner's subscriptions a single indexed count, exact and cheap,
262
249
  * since the per-owner set is bounded by `maxPerOwner`. Feeds the opt-in
263
250
  * `meta.totalCount` on `GET /webhooks`.
264
251
  */
265
- export async function countSubscriptions(store: Store.State, owner: Owner): Promise<number> {
266
- const { keys } = await store.list({ prefix: subscriptionPrefix(owner) })
267
- return keys.length
252
+ export async function countSubscriptions(db: Db.Db, owner: Owner): Promise<number> {
253
+ return WebhookSubscriptions.count(db, owner, new Date().toISOString())
268
254
  }
269
255
 
270
256
  /**
271
- * Patches an owner's subscription, re-validating the URL when changed and
272
- * re-indexing for the poller when the status changes. Returns null when absent.
257
+ * Patches an owner's subscription, re-validating the URL when changed.
258
+ * Returns null when absent. The status column drives the poller's partial
259
+ * index, so no secondary-index maintenance is needed.
273
260
  */
274
261
  export async function updateSubscription(
275
- store: Store.State,
262
+ db: Db.Db,
276
263
  owner: Owner,
277
264
  id: string,
278
265
  patch: PatchInput,
279
266
  options: updateSubscription.Options = {},
280
267
  ): Promise<Subscription | null> {
281
- const current = await getSubscription(store, owner, id)
268
+ const current = await getSubscription(db, owner, id)
282
269
  if (!current) return null
283
270
 
284
271
  if (patch.destination !== undefined) WebhookDestination.assertDestination(patch.destination)
285
272
 
286
273
  const now = (options.now ?? (() => new Date()))()
287
- const next: Subscription = {
288
- ...current,
289
- // `context: null` clears it (stored as undefined; drops from JSON + reads).
290
- ...(patch.context === undefined
291
- ? {}
292
- : { context: patch.context === null ? undefined : patch.context }),
274
+ const next = await WebhookSubscriptions.update(db, id, {
275
+ // `context: null` clears it (stored as a null column; drops from reads).
276
+ ...(patch.context === undefined ? {} : { context: patch.context }),
293
277
  ...(patch.destination === undefined ? {} : { destination: patch.destination }),
294
278
  ...(patch.filters === undefined ? {} : { filters: patch.filters }),
295
279
  ...(patch.status === undefined ? {} : { status: patch.status }),
296
280
  updatedAt: now.toISOString(),
297
- }
298
-
299
- await writeSubscription(store, next)
300
- return next
281
+ })
282
+ return next ?? null
301
283
  }
302
284
 
303
285
  export declare namespace updateSubscription {
@@ -308,61 +290,51 @@ export declare namespace updateSubscription {
308
290
  }
309
291
  }
310
292
 
311
- /** Deletes an owner's subscription and its index/cursor keys. */
312
- export async function deleteSubscription(
313
- store: Store.State,
314
- owner: Owner,
315
- id: string,
316
- ): Promise<boolean> {
317
- const current = await getSubscription(store, owner, id)
318
- if (!current) return false
319
-
320
- await store.delete(subscriptionKey(owner, id))
321
- await store.delete(activeKey(current.chainId, current.eventType, id))
322
- await store.delete(cursorKey(id))
323
-
324
- // Drop the delivery log so a deleted subscription leaves no orphaned rows.
325
- const { keys } = await store.list({ prefix: deliveryPrefix(id) })
326
- for (const { name } of keys) await store.delete(name)
327
- return true
293
+ /** Deletes an owner's subscription; its delivery rows cascade via the FK. */
294
+ export async function deleteSubscription(db: Db.Db, owner: Owner, id: string): Promise<boolean> {
295
+ return WebhookSubscriptions.remove(db, owner, id, new Date().toISOString())
328
296
  }
329
297
 
330
298
  /**
331
299
  * Lists active subscriptions for a `(chainId, eventType)` stream. Used by the
332
- * poller; reads the secondary index, then hydrates each subscription.
300
+ * poller; one indexed query (the partial status index replaces the old
301
+ * secondary key space).
333
302
  */
334
303
  export async function listActive(
335
- store: Store.State,
304
+ db: Db.Db,
336
305
  chainId: number,
337
306
  eventType: EventType,
338
307
  ): Promise<Subscription[]> {
339
- const { keys } = await store.list({ prefix: activePrefix(chainId, eventType) })
340
-
341
- const subscriptions: Subscription[] = []
342
- for (const { name } of keys) {
343
- const subKey = await store.get(name)
344
- if (!subKey) continue
345
- const subscription = await readSubscription(store, subKey)
346
- if (subscription) subscriptions.push(subscription)
347
- }
348
- return subscriptions
308
+ return WebhookSubscriptions.listActive(db, chainId, eventType, new Date().toISOString())
349
309
  }
350
310
 
351
311
  /** Reads a subscription's keyset cursor. Returns null when unset. */
352
- export async function getCursor(
353
- store: Store.State,
354
- subscriptionId: string,
355
- ): Promise<string | null> {
356
- return store.get(cursorKey(subscriptionId))
312
+ export async function getCursor(db: Db.Db, subscriptionId: string): Promise<string | null> {
313
+ return WebhookSubscriptions.getCursor(db, subscriptionId)
357
314
  }
358
315
 
359
316
  /** Writes a subscription's keyset cursor. */
360
- export async function setCursor(
361
- store: Store.State,
362
- subscriptionId: string,
363
- cursor: string,
364
- ): Promise<void> {
365
- await store.put(cursorKey(subscriptionId), cursor)
317
+ export async function setCursor(db: Db.Db, subscriptionId: string, cursor: string): Promise<void> {
318
+ await WebhookSubscriptions.setCursor(db, subscriptionId, cursor)
319
+ }
320
+
321
+ /**
322
+ * Deletes expired MPP-owned subscriptions (delivery rows cascade) and
323
+ * deliveries past retention. Reads already filter expiry at query time — this
324
+ * is the janitor reclaiming space, called best-effort per poller tick.
325
+ */
326
+ export async function pruneExpired(db: Db.Db, options: pruneExpired.Options = {}): Promise<void> {
327
+ const iso = (options.now ?? (() => new Date()))().toISOString()
328
+ await WebhookDeliveries.pruneExpired(db, iso)
329
+ await WebhookSubscriptions.pruneExpired(db, iso)
330
+ }
331
+
332
+ export declare namespace pruneExpired {
333
+ /** Options for {@link pruneExpired}. */
334
+ type Options = {
335
+ /** Clock used for expiry evaluation; injectable for tests. */
336
+ now?: (() => Date) | undefined
337
+ }
366
338
  }
367
339
 
368
340
  /**
@@ -373,14 +345,16 @@ export const deliveryRetentionMs = 7 * 24 * 60 * 60 * 1_000
373
345
 
374
346
  /** Records one delivery-log row (stateful, owner-agnostic; scoped per subscription). */
375
347
  export async function recordDelivery(
376
- store: Store.State,
348
+ db: Db.Db,
377
349
  delivery: Delivery,
378
350
  options: recordDelivery.Options = {},
379
351
  ): Promise<void> {
380
352
  const ttl = options.ttl ?? deliveryRetentionMs
381
- await store.put(deliveryKey(delivery.subscriptionId, delivery.id), JSON.stringify(delivery), {
382
- ttl,
383
- })
353
+ // The retention deadline replaces the old store TTL: reads filter on it at
354
+ // query time and the poller prunes past it. Anchored to write time (not the
355
+ // row's `createdAt`, which tests pin) — exactly like the old `put` TTL.
356
+ const expiresAt = new Date(Date.now() + ttl).toISOString()
357
+ await WebhookDeliveries.insert(db, delivery, expiresAt)
384
358
  }
385
359
 
386
360
  export declare namespace recordDelivery {
@@ -396,27 +370,11 @@ export declare namespace recordDelivery {
396
370
  * paging. Delivery ids embed a timestamp, so lexical key order is chronological.
397
371
  */
398
372
  export async function listDeliveries(
399
- store: Store.State,
373
+ db: Db.Db,
400
374
  subscriptionId: string,
401
375
  options: listDeliveries.Options = {},
402
376
  ): Promise<Delivery[]> {
403
- const prefix = deliveryPrefix(subscriptionId)
404
- const { keys } = await store.list({ prefix })
405
-
406
- // Newest first: ids sort chronologically ascending, so reverse for descending.
407
- let names = keys
408
- .map((key) => key.name)
409
- .sort()
410
- .reverse()
411
- if (options.cursor) names = names.filter((name) => name < `${prefix}${options.cursor}`)
412
- if (options.offset) names = names.slice(options.offset)
413
- if (options.limit !== undefined) names = names.slice(0, options.limit)
414
-
415
- // Hydrate the page in parallel: the reads are independent, and a serial
416
- // loop costs one store round trip per row (an N+1 against the production
417
- // Durable Object).
418
- const deliveries = await Promise.all(names.map((name) => readDelivery(store, name)))
419
- return deliveries.filter((delivery) => delivery !== null)
377
+ return WebhookDeliveries.list(db, subscriptionId, { ...options, now: new Date().toISOString() })
420
378
  }
421
379
 
422
380
  export declare namespace listDeliveries {
@@ -432,23 +390,21 @@ export declare namespace listDeliveries {
432
390
  }
433
391
 
434
392
  /**
435
- * Counts a subscription's delivery-log entries. Reads only the key set under
436
- * the delivery prefix (no row hydration), so it's a single store `list` —
437
- * exact, and bounded by the delivery retention TTL. Feeds the opt-in
393
+ * Counts a subscription's delivery-log entries a single indexed count,
394
+ * exact, and bounded by the delivery retention window. Feeds the opt-in
438
395
  * `meta.totalCount` on `GET /webhooks/:id/deliveries`.
439
396
  */
440
- export async function countDeliveries(store: Store.State, subscriptionId: string): Promise<number> {
441
- const { keys } = await store.list({ prefix: deliveryPrefix(subscriptionId) })
442
- return keys.length
397
+ export async function countDeliveries(db: Db.Db, subscriptionId: string): Promise<number> {
398
+ return WebhookDeliveries.count(db, subscriptionId, new Date().toISOString())
443
399
  }
444
400
 
445
401
  /** Loads a single delivery-log row (`null` when absent), scoped to its subscription. */
446
402
  export async function getDelivery(
447
- store: Store.State,
403
+ db: Db.Db,
448
404
  subscriptionId: string,
449
405
  deliveryId: string,
450
406
  ): Promise<Delivery | null> {
451
- return readDelivery(store, deliveryKey(subscriptionId, deliveryId))
407
+ return WebhookDeliveries.get(db, subscriptionId, deliveryId, new Date().toISOString())
452
408
  }
453
409
 
454
410
  /**
@@ -459,23 +415,20 @@ export const maxFailures = 10
459
415
 
460
416
  /**
461
417
  * Records a successful delivery: resets the consecutive-failure counter and
462
- * stamps `lastDeliveryAt`. Returns the updated subscription (re-persisted so the
463
- * poller's active index and TTL stay correct).
418
+ * stamps `lastDeliveryAt`. A column-targeted update, so a concurrent patch is
419
+ * never clobbered by the stale copy carried through the delivery queue.
464
420
  */
465
421
  export async function recordSuccess(
466
- store: Store.State,
422
+ db: Db.Db,
467
423
  subscription: Subscription,
468
424
  options: recordSuccess.Options = {},
469
425
  ): Promise<Subscription> {
470
426
  const now = (options.now ?? (() => new Date()))()
471
- const next: Subscription = {
472
- ...subscription,
473
- failureCount: 0,
474
- lastDeliveryAt: now.toISOString(),
475
- updatedAt: now.toISOString(),
476
- }
477
- await writeSubscription(store, next)
478
- return next
427
+ const iso = now.toISOString()
428
+ const next = await WebhookSubscriptions.recordSuccess(db, subscription.id, iso)
429
+ // A concurrently deleted subscription is not resurrected; return the
430
+ // optimistic next state so the caller still observes the outcome.
431
+ return next ?? { ...subscription, failureCount: 0, lastDeliveryAt: iso, updatedAt: iso }
479
432
  }
480
433
 
481
434
  export declare namespace recordSuccess {
@@ -487,27 +440,30 @@ export declare namespace recordSuccess {
487
440
  }
488
441
 
489
442
  /**
490
- * Records a failed delivery: increments the consecutive-failure counter and,
491
- * once it reaches `maxFailures`, sets `status: 'disabled'` so the subscription
492
- * drops out of the poller's active index (surfaced via the API). Returns the
493
- * updated subscription.
443
+ * Records a failed delivery: atomically increments the consecutive-failure
444
+ * counter and, once it reaches `maxFailures`, sets `status: 'disabled'` so the
445
+ * subscription drops out of the poller's partial index (surfaced via the API).
446
+ * Returns the updated subscription.
494
447
  */
495
448
  export async function recordFailure(
496
- store: Store.State,
449
+ db: Db.Db,
497
450
  subscription: Subscription,
498
451
  options: recordFailure.Options = {},
499
452
  ): Promise<Subscription> {
500
453
  const now = (options.now ?? (() => new Date()))()
454
+ const iso = now.toISOString()
455
+ const max = options.maxFailures ?? maxFailures
456
+ const next = await WebhookSubscriptions.recordFailure(db, subscription.id, max, iso)
457
+ if (next) return next
458
+ // A concurrently deleted subscription is not resurrected; return the
459
+ // optimistic next state so the caller still observes the outcome.
501
460
  const failureCount = subscription.failureCount + 1
502
- const disabled = failureCount >= (options.maxFailures ?? maxFailures)
503
- const next: Subscription = {
461
+ return {
504
462
  ...subscription,
505
463
  failureCount,
506
- ...(disabled ? { status: 'disabled' } : {}),
507
- updatedAt: now.toISOString(),
464
+ ...(failureCount >= max ? { status: 'disabled' as const } : {}),
465
+ updatedAt: iso,
508
466
  }
509
- await writeSubscription(store, next)
510
- return next
511
467
  }
512
468
 
513
469
  export declare namespace recordFailure {
@@ -527,7 +483,7 @@ export declare namespace recordFailure {
527
483
  * point shared by the Cloudflare Queue consumer and the self-host inline path.
528
484
  */
529
485
  export async function deliverAndRecord(
530
- store: Store.State,
486
+ db: Db.Db,
531
487
  subscription: Subscription,
532
488
  envelope: Envelope,
533
489
  options: deliverAndRecord.Options = {},
@@ -540,8 +496,8 @@ export async function deliverAndRecord(
540
496
  ...(options.fetch === undefined ? {} : { fetch: options.fetch }),
541
497
  ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
542
498
  })
543
- if (result.ok) await recordSuccess(store, subscription, options)
544
- else await recordFailure(store, subscription, options)
499
+ if (result.ok) await recordSuccess(db, subscription, options)
500
+ else await recordFailure(db, subscription, options)
545
501
 
546
502
  // Emit a `webhook:delivery` metric. recordSuccess/recordFailure are immutable
547
503
  // (they spread into a new record), so `subscription.failureCount` here is still
@@ -563,7 +519,7 @@ export async function deliverAndRecord(
563
519
  // the delivery outcome the caller (Queue consumer / inline path) acts on.
564
520
  try {
565
521
  await recordDelivery(
566
- store,
522
+ db,
567
523
  buildDelivery({ attempt, envelope, result, subscription }, options),
568
524
  options.deliveryRetentionMs === undefined ? {} : { ttl: options.deliveryRetentionMs },
569
525
  )
@@ -741,7 +697,7 @@ export declare namespace buildPingEnvelope {
741
697
  * delivery log.
742
698
  */
743
699
  export async function ping(
744
- store: Store.State,
700
+ db: Db.Db,
745
701
  subscription: Subscription,
746
702
  options: ping.Options = {},
747
703
  ): Promise<ping.Result> {
@@ -761,7 +717,7 @@ export async function ping(
761
717
  const delivery = buildDelivery({ attempt: 1, envelope, result, subscription }, { now })
762
718
  try {
763
719
  await recordDelivery(
764
- store,
720
+ db,
765
721
  delivery,
766
722
  options.deliveryRetentionMs === undefined ? {} : { ttl: options.deliveryRetentionMs },
767
723
  )
@@ -797,80 +753,6 @@ export declare namespace ping {
797
753
  }
798
754
  }
799
755
 
800
- function ownerKey(owner: Owner): string {
801
- return owner.type === 'api_key'
802
- ? `api_key:${encodeURIComponent(owner.orgId)}`
803
- : `mpp:${encodeURIComponent(owner.payer)}`
804
- }
805
-
806
- function subscriptionPrefix(owner: Owner): string {
807
- return `webhook:sub:${ownerKey(owner)}:`
808
- }
809
-
810
- function subscriptionKey(owner: Owner, id: string): string {
811
- return `${subscriptionPrefix(owner)}${id}`
812
- }
813
-
814
- function cursorKey(subscriptionId: string): string {
815
- return `webhook:cursor:${subscriptionId}`
816
- }
817
-
818
- function deliveryPrefix(subscriptionId: string): string {
819
- return `webhook:delivery:${subscriptionId}:`
820
- }
821
-
822
- function deliveryKey(subscriptionId: string, deliveryId: string): string {
823
- return `${deliveryPrefix(subscriptionId)}${deliveryId}`
824
- }
825
-
826
- function activePrefix(chainId: number, eventType: EventType): string {
827
- return `webhook:active:${chainId}:${eventType}:`
828
- }
829
-
830
- function activeKey(chainId: number, eventType: EventType, id: string): string {
831
- return `${activePrefix(chainId, eventType)}${id}`
832
- }
833
-
834
- async function readSubscription(store: Store.State, key: string): Promise<Subscription | null> {
835
- const raw = await store.get(key)
836
- if (!raw) return null
837
- try {
838
- return JSON.parse(raw) as Subscription
839
- } catch {
840
- // Corrupt entries are treated as absent.
841
- return null
842
- }
843
- }
844
-
845
- async function readDelivery(store: Store.State, key: string): Promise<Delivery | null> {
846
- const raw = await store.get(key)
847
- if (!raw) return null
848
- try {
849
- return JSON.parse(raw) as Delivery
850
- } catch {
851
- // Corrupt entries are treated as absent.
852
- return null
853
- }
854
- }
855
-
856
- async function writeSubscription(store: Store.State, subscription: Subscription): Promise<void> {
857
- const ttl = ttlFor(subscription)
858
- const key = subscriptionKey(subscription.owner, subscription.id)
859
- await store.put(key, JSON.stringify(subscription), { ttl })
860
-
861
- // Mirror status into the poller's secondary index: only `active`
862
- // subscriptions are polled. The index value is the subscription's storage key
863
- // so the poller can hydrate without knowing the owner.
864
- const indexKey = activeKey(subscription.chainId, subscription.eventType, subscription.id)
865
- if (subscription.status === 'active') await store.put(indexKey, key, { ttl })
866
- else await store.delete(indexKey)
867
- }
868
-
869
- function ttlFor(subscription: Subscription): number | undefined {
870
- if (!subscription.expiresAt) return undefined
871
- return Math.max(1, new Date(subscription.expiresAt).getTime() - Date.now())
872
- }
873
-
874
756
  function generateId(now: Date): string {
875
757
  // Zero-pad the epoch-ms so ids sort chronologically by string comparison
876
758
  // (mirroring delivery ids), letting listSubscriptions page newest-first; 15