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
package/src/admin/App.ts CHANGED
@@ -3,10 +3,10 @@ import { HTTPException } from 'hono/http-exception'
3
3
  import { requestId, type RequestIdVariables } from 'hono/request-id'
4
4
 
5
5
  import * as ApiKey from '../ApiKey.js'
6
- import * as ApiKeySource from '../ApiKeySource.js'
7
6
  import type * as Assets from '../Assets.js'
8
- import * as Response from '../internal/Response.js'
7
+ import type * as Db from '../db/Db.js'
9
8
  import type * as Store from '../internal/Store.js'
9
+ import * as Response from '../internal/Response.js'
10
10
 
11
11
  import { apiKeys } from './apps/api-keys.js'
12
12
  import { scopes } from './apps/scopes.js'
@@ -24,12 +24,12 @@ export type Environment = {
24
24
  Variables: RequestIdVariables & {
25
25
  /** Static-asset writer (e.g. the R2 icon bucket), when configured. */
26
26
  assets: create.Assets | undefined
27
+ /** Authoritative Postgres store, or a per-request factory. Resolve at the leaf with `Db.get`. */
28
+ db: Db.Source
29
+ /** KV state store backing API-key records (mint/list/revoke). */
30
+ kv: { store: Store.State }
27
31
  /** The admin identity, or `null` when unauthenticated (gated routes reject). */
28
32
  identity: Identity | null
29
- /** The API-key source provisioned against (mint/list/revoke). */
30
- source: ApiKeySource.Source
31
- /** Verified-token state store, when management is enabled. */
32
- verifiedTokens: { store: Store.State } | undefined
33
33
  }
34
34
  }
35
35
 
@@ -39,7 +39,6 @@ export type App = ReturnType<typeof create>
39
39
  /** Creates the admin portal Hono app. */
40
40
  export function create(options: create.Options) {
41
41
  const { identify } = options
42
- const { source } = options.apiKey
43
42
  // `false` (disabled) collapses to `undefined` so only a real config surfaces
44
43
  // `loginUrl`/`logoutUrl` in `/config.json`.
45
44
  const ui = options.ui || undefined
@@ -55,9 +54,9 @@ export function create(options: create.Options) {
55
54
  app.use('*', async (c, next) => {
56
55
  // Admin data is per-principal and mutating: never cache.
57
56
  c.header('Cache-Control', 'no-store')
58
- c.set('source', source)
59
57
  c.set('assets', options.assets)
60
- c.set('verifiedTokens', options.verifiedTokens)
58
+ c.set('db', options.db)
59
+ c.set('kv', options.kv)
61
60
  c.set('identity', await identify(c.req.raw))
62
61
  return next()
63
62
  })
@@ -173,16 +172,22 @@ export declare namespace create {
173
172
 
174
173
  /** Options for {@link create}. */
175
174
  type Options = {
176
- /** API-key provisioning config (mirrors the API app's `apiKey` option). */
177
- apiKey: {
178
- /** Source to provision against (mint/list/revoke). */
179
- source: ApiKeySource.Source
180
- }
181
175
  /**
182
176
  * Static-asset writer for logo uploads (shared with the main API's `assets`
183
177
  * loader) to enable `PUT /verified-tokens/:address/logo`; omit for `404`.
184
178
  */
185
179
  assets?: Assets | undefined
180
+ /**
181
+ * Authoritative Postgres store shared with the main API (verified
182
+ * tokens). Pass a long-lived `Db.postgres(...)` singleton on Node, or a
183
+ * factory (`() => Db.postgres(...)`) on Workers.
184
+ */
185
+ db: Db.Source
186
+ /**
187
+ * KV state store backing API-key records (shared with the main API's
188
+ * `kv` option), provisioned against by the `/api-keys` routes.
189
+ */
190
+ kv: { store: Store.State }
186
191
  /**
187
192
  * Extracts the verified admin identity from a request, or `null` to deny.
188
193
  * Must only return an identity for an already-authenticated request (a
@@ -194,16 +199,6 @@ export declare namespace create {
194
199
  * `loginUrl`/`logoutUrl` are surfaced in `GET /config.json`.
195
200
  */
196
201
  ui?: Ui | false | undefined
197
- /**
198
- * Verified-token management config (store shared with the main API's reads)
199
- * to enable the `/verified-tokens` routes; omit to serve them as `404`.
200
- */
201
- verifiedTokens?:
202
- | {
203
- /** Verified-token state store (shared with the main API's reads). */
204
- store: Store.State
205
- }
206
- | undefined
207
202
  }
208
203
 
209
204
  /** Admin UI options surfaced to the SPA via `GET /config.json`. */
@@ -1,4 +1,5 @@
1
1
  import * as ApiKey from '../../ApiKey.js'
2
+ import * as core_ApiKeys from '../../ApiKeys.js'
2
3
 
3
4
  import * as TestAdmin from '../../../test/Admin.js'
4
5
  import * as TestApp from '../../../test/App.js'
@@ -9,7 +10,7 @@ const validBody = { orgId: 'org_test', scopes: ['data:read'] } as const
9
10
 
10
11
  describe('POST /api-keys', () => {
11
12
  test('mints a key, returns the token once, persists a hashed record', async () => {
12
- const { client, source, store } = TestAdmin.setup()
13
+ const { client, store } = TestAdmin.setup()
13
14
  const response = await client['api-keys'].$post({ json: { ...validBody, name: 'CI' } })
14
15
  const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
15
16
 
@@ -34,26 +35,26 @@ describe('POST /api-keys', () => {
34
35
  }
35
36
  `)
36
37
 
37
- // The token resolves through the source (proving the record persisted),
38
+ // The token resolves through the module (proving the record persisted),
38
39
  // and at rest it is keyed by the token hash — never the plaintext token.
39
- const resolved = await source.resolve(body.token)
40
+ const resolved = await core_ApiKeys.resolve(store, body.token)
40
41
  expect(resolved?.orgId).toBe('org_test')
41
42
  expect(await store.get(body.token)).toBeNull()
42
43
  expect(await store.get(ApiKey.keyFor(body.token))).not.toBeNull()
43
44
  })
44
45
 
45
46
  test('defaults to the production environment', async () => {
46
- const { client, source } = TestAdmin.setup()
47
+ const { client, store } = TestAdmin.setup()
47
48
  const response = await client['api-keys'].$post({ json: validBody })
48
49
  const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
49
50
 
50
51
  expect(response.status).toBe(200)
51
52
  expect(body.environment).toBe('production')
52
- expect((await source.list())[0]?.environment).toBe('production')
53
+ expect((await core_ApiKeys.list(store))[0]?.environment).toBe('production')
53
54
  })
54
55
 
55
56
  test('persists a sandbox environment when provided', async () => {
56
- const { client, source } = TestAdmin.setup()
57
+ const { client, store } = TestAdmin.setup()
57
58
  const response = await client['api-keys'].$post({
58
59
  json: { ...validBody, environment: 'sandbox' },
59
60
  })
@@ -63,19 +64,19 @@ describe('POST /api-keys', () => {
63
64
  expect(body.environment).toBe('sandbox')
64
65
  // Sandbox tokens carry a distinct prefix for recognizability/leak detection.
65
66
  expect(body.token).toMatch(/^tempo_sandbox:sk:[a-f0-9]{48}$/)
66
- const resolved = await source.resolve(body.token)
67
+ const resolved = await core_ApiKeys.resolve(store, body.token)
67
68
  expect(resolved?.environment).toBe('sandbox')
68
69
  })
69
70
 
70
71
  test('records the expiry when provided', async () => {
71
- const { client, source } = TestAdmin.setup()
72
+ const { client, store } = TestAdmin.setup()
72
73
  const expiresAt = '2100-01-01T00:00:00.000Z'
73
74
  const response = await client['api-keys'].$post({ json: { ...validBody, expiresAt } })
74
75
  const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
75
76
 
76
77
  expect(response.status).toBe(200)
77
78
  expect(body.expiresAt).toBe(expiresAt)
78
- expect((await source.list())[0]?.expiresAt).toBe(expiresAt)
79
+ expect((await core_ApiKeys.list(store))[0]?.expiresAt).toBe(expiresAt)
79
80
  })
80
81
 
81
82
  test('rejects an unknown scope with 400', async () => {
@@ -106,8 +107,8 @@ describe('POST /api-keys', () => {
106
107
 
107
108
  describe('GET /api-keys', () => {
108
109
  test('lists records as metadata only (never the token)', async () => {
109
- const { client, source } = TestAdmin.setup()
110
- const { token } = await source.mint(validBody)
110
+ const { client, store } = TestAdmin.setup()
111
+ const { token } = await core_ApiKeys.mint(store, validBody)
111
112
 
112
113
  const response = await client['api-keys'].$get({ query: {} })
113
114
  const body = await TestApp.json(response, ApiKeys.schema.listApiKeys.Response)
@@ -120,9 +121,9 @@ describe('GET /api-keys', () => {
120
121
  })
121
122
 
122
123
  test('filters by orgId', async () => {
123
- const { client, source } = TestAdmin.setup()
124
- await source.mint({ orgId: 'org_a', scopes: ['data:read'] })
125
- await source.mint({ orgId: 'org_b', scopes: ['data:read'] })
124
+ const { client, store } = TestAdmin.setup()
125
+ await core_ApiKeys.mint(store, { orgId: 'org_a', scopes: ['data:read'] })
126
+ await core_ApiKeys.mint(store, { orgId: 'org_b', scopes: ['data:read'] })
126
127
 
127
128
  const response = await client['api-keys'].$get({ query: { orgId: 'org_a' } })
128
129
  const body = await TestApp.json(response, ApiKeys.schema.listApiKeys.Response)
@@ -133,16 +134,16 @@ describe('GET /api-keys', () => {
133
134
 
134
135
  describe('DELETE /api-keys/:id', () => {
135
136
  test('revokes a key, after which it no longer resolves or lists', async () => {
136
- const { client, source } = TestAdmin.setup()
137
- const { record, token } = await source.mint(validBody)
137
+ const { client, store } = TestAdmin.setup()
138
+ const { record, token } = await core_ApiKeys.mint(store, validBody)
138
139
 
139
140
  const response = await client['api-keys'][':id'].$delete({ param: { id: record.id } })
140
141
  const body = await TestApp.json(response, ApiKeys.schema.revokeApiKey.Response)
141
142
 
142
143
  expect(response.status).toBe(200)
143
144
  expect(body).toEqual({ id: record.id })
144
- expect(await source.resolve(token)).toBeNull()
145
- expect(await source.list()).toEqual([])
145
+ expect(await core_ApiKeys.resolve(store, token)).toBeNull()
146
+ expect(await core_ApiKeys.list(store)).toEqual([])
146
147
  })
147
148
 
148
149
  test('unknown id → 404', async () => {
@@ -154,3 +155,54 @@ describe('DELETE /api-keys/:id', () => {
154
155
  expect(body.error?.code).toMatchInlineSnapshot(`"not_found"`)
155
156
  })
156
157
  })
158
+
159
+ describe('PATCH /api-keys/:id', () => {
160
+ test('re-attributes a key to an org and project', async () => {
161
+ const { client, store } = TestAdmin.setup()
162
+ const { record, token } = await core_ApiKeys.mint(store, validBody)
163
+
164
+ const response = await client['api-keys'][':id'].$patch({
165
+ json: { orgId: 'org_real', projectId: 'prj_real' },
166
+ param: { id: record.id },
167
+ })
168
+ expect(response.status).toBe(200)
169
+ const body = await TestApp.json(response, core_ApiKeys.schema.Record)
170
+ expect(body.orgId).toBe('org_real')
171
+ expect(body.projectId).toBe('prj_real')
172
+
173
+ // The original token keeps resolving, now carrying the attribution.
174
+ const resolved = await core_ApiKeys.resolve(store, token)
175
+ expect(resolved?.projectId).toBe('prj_real')
176
+ })
177
+
178
+ test('unknown id → 404', async () => {
179
+ const { client } = TestAdmin.setup()
180
+ const response = await client['api-keys'][':id'].$patch({
181
+ json: { projectId: 'prj_x' },
182
+ param: { id: 'key_missing' },
183
+ })
184
+ expect(response.status).toMatchInlineSnapshot(`404`)
185
+ })
186
+ })
187
+
188
+ describe('POST /api-keys/backfill', () => {
189
+ test('rebuilds index entries for legacy records', async () => {
190
+ const { client, store } = TestAdmin.setup()
191
+ const { record } = await core_ApiKeys.mint(store, validBody)
192
+
193
+ // Legacy state: records exist, index entries do not.
194
+ for (const prefix of ['apikey_id:', 'apikey_org:'])
195
+ for (const { name } of (await store.list({ prefix })).keys) await store.delete(name)
196
+ expect(await core_ApiKeys.listByOrg(store, 'org_test')).toEqual([])
197
+
198
+ const response = await client['api-keys'].backfill.$post()
199
+ expect(response.status).toBe(200)
200
+ expect(await TestApp.json(response, ApiKeys.schema.backfillApiKeys.Response)).toEqual({
201
+ indexed: 1,
202
+ scanned: 1,
203
+ })
204
+ expect((await core_ApiKeys.listByOrg(store, 'org_test')).map(({ id }) => id)).toEqual([
205
+ record.id,
206
+ ])
207
+ })
208
+ })
@@ -1,7 +1,7 @@
1
1
  import { Hono } from 'hono'
2
2
  import * as z from 'zod/mini'
3
3
 
4
- import * as ApiKeySource from '../../ApiKeySource.js'
4
+ import * as ApiKeys from '../../ApiKeys.js'
5
5
  import * as OpenApi from '../../internal/OpenApi.js'
6
6
  import * as Response from '../../internal/Response.js'
7
7
  import * as Schema from '../../internal/Schema.js'
@@ -16,13 +16,13 @@ export namespace schema {
16
16
  * server sets from the verified identity so it can't be spoofed).
17
17
  */
18
18
  export const Body = Schema.describe(
19
- z.omit(ApiKeySource.schema.MintInput, { createdBy: true }),
19
+ z.omit(ApiKeys.schema.MintInput, { createdBy: true }),
20
20
  'Fields accepted when minting an API key.',
21
21
  )
22
22
 
23
23
  /** Response: the record plus the one-time plaintext token. */
24
24
  export const Response = Schema.describe(
25
- z.extend(ApiKeySource.schema.Record, {
25
+ z.extend(ApiKeys.schema.Record, {
26
26
  token: z
27
27
  .string()
28
28
  .check(z.describe('The plaintext token, shown once and unrecoverable afterward.')),
@@ -46,13 +46,44 @@ export namespace schema {
46
46
  export const Response = Schema.describe(
47
47
  z.object({
48
48
  data: z
49
- .array(ApiKeySource.schema.Record)
49
+ .array(ApiKeys.schema.Record)
50
50
  .check(z.describe('API-key records, newest first (metadata only — never tokens).')),
51
51
  }),
52
52
  'A list of API-key records.',
53
53
  )
54
54
  }
55
55
 
56
+ /** Schemas for the attributeApiKey operation. */
57
+ export namespace attributeApiKey {
58
+ /** Request body re-attributing a key; omitted fields keep their value. */
59
+ export const Body = Schema.describe(
60
+ z.object({
61
+ orgId: z.optional(z.string()).check(z.describe('New owning organization id (`org_…`).')),
62
+ projectId: z.optional(z.string()).check(z.describe('New owning project id (`prj_…`).')),
63
+ }),
64
+ 'Attribution to apply to an API key.',
65
+ )
66
+
67
+ /** Path parameters for attributing a key. */
68
+ export const Params = z
69
+ .object({
70
+ id: z.string().check(z.describe('Stable id of the key to attribute.')),
71
+ })
72
+ .check(z.describe('Path parameters for attributing an API key.'))
73
+ }
74
+
75
+ /** Schemas for the backfillApiKeys operation. */
76
+ export namespace backfillApiKeys {
77
+ /** Result counts from the index rebuild. */
78
+ export const Response = Schema.describe(
79
+ z.object({
80
+ indexed: z.number().check(z.describe('Records whose index entries were written.')),
81
+ scanned: z.number().check(z.describe('Stored records scanned.')),
82
+ }),
83
+ 'Result of rebuilding the API-key indexes.',
84
+ )
85
+ }
86
+
56
87
  /** Schemas for the revokeApiKey operation. */
57
88
  export namespace revokeApiKey {
58
89
  /** Path parameters for revoking a key. */
@@ -70,16 +101,36 @@ export namespace schema {
70
101
  }
71
102
 
72
103
  /**
73
- * Provisioning routes for API keys, backed by the request's
74
- * {@link App.Environment} `source`:
104
+ * Provisioning routes for API keys, backed by the app's KV state store:
75
105
  *
76
106
  * - `POST /` mints a key, recording `createdBy` from the verified identity and
77
107
  * returning the one-time token.
78
108
  * - `GET /` lists key records (metadata only), optionally filtered by `orgId`.
79
109
  * - `DELETE /:id` revokes a key by id (`404` if absent).
110
+ * - `PATCH /:id` re-attributes a key to an org/project (the legacy backfill path).
111
+ * - `POST /backfill` rebuilds the id and org index entries for every record.
80
112
  */
81
113
  export function apiKeys() {
82
114
  return new Hono<App.Environment>()
115
+ .post(
116
+ '/backfill',
117
+ OpenApi.describeRoute({
118
+ description: 'Rebuild the id and org index entries for every stored key record. Records are never modified, so existing tokens keep resolving.', // prettier-ignore
119
+ operationId: 'backfillApiKeys',
120
+ responses: OpenApi.responses({
121
+ success: {
122
+ description: 'Scanned and indexed record counts.',
123
+ schema: schema.backfillApiKeys.Response,
124
+ },
125
+ }),
126
+ summary: 'Backfill key indexes',
127
+ tags: ['API keys'],
128
+ }),
129
+ async (c) => {
130
+ const result = await ApiKeys.backfill(c.get('kv').store)
131
+ return c.json(Response.validated(schema.backfillApiKeys.Response, result))
132
+ },
133
+ )
83
134
  .post(
84
135
  '/',
85
136
  OpenApi.validate('json', schema.createApiKey.Body, {
@@ -100,7 +151,7 @@ export function apiKeys() {
100
151
  async (c) => {
101
152
  // `createdBy` is the verified admin email, never client-supplied.
102
153
  // `requireAuth` guarantees identity on this gated route.
103
- const { record, token } = await c.get('source').mint({
154
+ const { record, token } = await ApiKeys.mint(c.get('kv').store, {
104
155
  ...c.req.valid('json'),
105
156
  createdBy: c.get('identity')!.email,
106
157
  })
@@ -123,7 +174,7 @@ export function apiKeys() {
123
174
  }),
124
175
  async (c) => {
125
176
  const { orgId } = c.req.valid('query')
126
- const data = await c.get('source').list(orgId ? { orgId } : {})
177
+ const data = await ApiKeys.list(c.get('kv').store, orgId ? { orgId } : {})
127
178
  return c.json(Response.validated(schema.listApiKeys.Response, { data }))
128
179
  },
129
180
  )
@@ -144,7 +195,7 @@ export function apiKeys() {
144
195
  }),
145
196
  async (c) => {
146
197
  const { id } = c.req.valid('param')
147
- const revoked = await c.get('source').revoke(id)
198
+ const revoked = await ApiKeys.revoke(c.get('kv').store, id)
148
199
  if (!revoked)
149
200
  return Response.error(c, {
150
201
  code: 'not_found',
@@ -154,4 +205,36 @@ export function apiKeys() {
154
205
  return c.json(Response.validated(schema.revokeApiKey.Response, { id }))
155
206
  },
156
207
  )
208
+ .patch(
209
+ '/:id',
210
+ OpenApi.validate('param', schema.attributeApiKey.Params, {
211
+ code: 'param_invalid',
212
+ message: 'Invalid path parameters',
213
+ }),
214
+ OpenApi.validate('json', schema.attributeApiKey.Body, {
215
+ code: 'body_invalid',
216
+ message: 'Invalid request body',
217
+ }),
218
+ OpenApi.describeRoute({
219
+ description: 'Re-attribute a key to an organization and/or project. The token is unchanged.', // prettier-ignore
220
+ operationId: 'attributeApiKey',
221
+ responses: OpenApi.responses({
222
+ errors: { 404: 'API key not found.' },
223
+ success: { description: 'The updated key record.', schema: ApiKeys.schema.Record },
224
+ }),
225
+ summary: 'Attribute API key',
226
+ tags: ['API keys'],
227
+ }),
228
+ async (c) => {
229
+ const { id } = c.req.valid('param')
230
+ const updated = await ApiKeys.attribute(c.get('kv').store, id, c.req.valid('json'))
231
+ if (!updated)
232
+ return Response.error(c, {
233
+ code: 'not_found',
234
+ message: 'API key not found.',
235
+ status: 404,
236
+ })
237
+ return c.json(Response.validated(ApiKeys.schema.Record, updated))
238
+ },
239
+ )
157
240
  }
@@ -22,6 +22,14 @@ describe('GET /scopes', () => {
22
22
  "description": "Run ad-hoc queries against the raw indexer passthrough.",
23
23
  "scope": "indexer:query",
24
24
  },
25
+ {
26
+ "description": "Fill and submit transactions through the relay.",
27
+ "scope": "rpc-relay:read",
28
+ },
29
+ {
30
+ "description": "Sponsor transaction fees through the relay as the managed fee payer.",
31
+ "scope": "rpc-relay:sponsor",
32
+ },
25
33
  {
26
34
  "description": "Read webhook subscriptions.",
27
35
  "scope": "webhooks:read",
@@ -1,5 +1,3 @@
1
- import { Store } from 'cadent'
2
-
3
1
  import * as TestAdmin from '../../../test/Admin.js'
4
2
  import * as TestApp from '../../../test/App.js'
5
3
  import * as Verified from './verified-tokens.js'
@@ -15,29 +13,14 @@ const novel = {
15
13
 
16
14
  const chainId = '42431' as const
17
15
 
18
- /** Write-enabled admin client backed by a fresh in-memory state store. */
16
+ /** Write-enabled admin client backed by a fresh schema-isolated database. */
19
17
  function writes() {
20
- return TestAdmin.setup({ verifiedTokens: { store: Store.memory() } })
18
+ return TestAdmin.setup()
21
19
  }
22
20
 
23
- describe('feature gate', () => {
24
- test('write routes return 404 when no store is configured', async () => {
25
- const { client } = TestAdmin.setup()
26
- const response = await client['verified-tokens'].$post({
27
- json: { ...novel, chainId: 42431 },
28
- })
29
- expect(response.status).toBe(404)
30
- const body = (await response.json()) as { error?: { code?: string } }
31
- expect(body.error?.code).toBe('verified_tokens_not_enabled')
32
- })
33
- })
34
-
35
21
  describe('authentication', () => {
36
22
  test('denied identity → 401', async () => {
37
- const { client } = TestAdmin.setup({
38
- identify: () => null,
39
- verifiedTokens: { store: Store.memory() },
40
- })
23
+ const { client } = TestAdmin.setup({ identify: () => null })
41
24
  const response = await client['verified-tokens'].$post({
42
25
  json: { ...novel, chainId: 42431 },
43
26
  })
@@ -46,12 +29,6 @@ describe('authentication', () => {
46
29
  })
47
30
 
48
31
  describe('list', () => {
49
- test('returns 404 when no store is configured', async () => {
50
- const { client } = TestAdmin.setup()
51
- const response = await client['verified-tokens'].$get({ query: { chainId } })
52
- expect(response.status).toBe(404)
53
- })
54
-
55
32
  test('empty list → data [] and null version', async () => {
56
33
  const { client } = writes()
57
34
  const response = await client['verified-tokens'].$get({ query: { chainId } })
@@ -176,7 +153,6 @@ describe('create with inline logo', () => {
176
153
  get: async (key) => stored.find((entry) => entry.key === key)?.content,
177
154
  put: async (key, content) => void stored.push({ content, key }),
178
155
  },
179
- verifiedTokens: { store: Store.memory() },
180
156
  })
181
157
  return { client, stored }
182
158
  }
@@ -219,7 +195,6 @@ describe('create with inline logo', () => {
219
195
  throw new Error('upload failed')
220
196
  },
221
197
  },
222
- verifiedTokens: { store: Store.memory() },
223
198
  })
224
199
  const response = await client['verified-tokens'].$post({
225
200
  json: { ...novel, chainId: 42431, logo: svg },
@@ -297,7 +272,6 @@ describe('PUT /verified-tokens/:address/logo', () => {
297
272
  stored.push({ content, key })
298
273
  },
299
274
  },
300
- verifiedTokens: { store: Store.memory() },
301
275
  })
302
276
  return { client, stored }
303
277
  }
@@ -375,7 +349,6 @@ describe('GET /verified-tokens/:address/logo', () => {
375
349
  get: async (key) => objects.get(key),
376
350
  put: async (key, content) => void objects.set(key, content),
377
351
  },
378
- verifiedTokens: { store: Store.memory() },
379
352
  })
380
353
  return { client, objects }
381
354
  }