tapimo 0.19.0 → 0.20.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 (494) hide show
  1. package/README.md +13 -5
  2. package/dist/ApiKey.d.ts +2 -2
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +2 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +85 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +218 -56
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +12543 -13912
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +4 -5
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +12 -20
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +20 -36
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +871 -828
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +14 -26
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +93 -186
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +3 -5
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/audit-logs.d.ts +18 -18
  27. package/dist/admin/apps/audit-logs.js +1 -1
  28. package/dist/admin/apps/audit-logs.js.map +1 -1
  29. package/dist/admin/apps/earn-vaults.d.ts +27 -27
  30. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  31. package/dist/admin/apps/earn-vaults.js +11 -5
  32. package/dist/admin/apps/earn-vaults.js.map +1 -1
  33. package/dist/admin/apps/organizations.d.ts +17 -17
  34. package/dist/admin/apps/prop-amms.d.ts +4 -4
  35. package/dist/admin/apps/routes-support.js +1 -38
  36. package/dist/admin/apps/routes-support.js.map +1 -1
  37. package/dist/admin/apps/routes.d.ts +153 -153
  38. package/dist/admin/apps/sentinel.d.ts +4 -4
  39. package/dist/admin/apps/verified-tokens.d.ts +24 -24
  40. package/dist/admin/apps/zone-delegation-requests.d.ts +332 -0
  41. package/dist/admin/apps/zone-delegation-requests.d.ts.map +1 -0
  42. package/dist/admin/apps/zone-delegation-requests.js +200 -0
  43. package/dist/admin/apps/zone-delegation-requests.js.map +1 -0
  44. package/dist/admin/apps/zone-delegations.d.ts +512 -52
  45. package/dist/admin/apps/zone-delegations.d.ts.map +1 -1
  46. package/dist/admin/apps/zone-delegations.js +134 -44
  47. package/dist/admin/apps/zone-delegations.js.map +1 -1
  48. package/dist/admin/index.d.ts +1 -1
  49. package/dist/admin/index.d.ts.map +1 -1
  50. package/dist/admin/index.js +1 -1
  51. package/dist/admin/index.js.map +1 -1
  52. package/dist/admin/ui.generated.d.ts +1 -1
  53. package/dist/admin/ui.generated.d.ts.map +1 -1
  54. package/dist/admin/ui.generated.js +341 -397
  55. package/dist/admin/ui.generated.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  57. package/dist/analytics/tables/requestEvents.js +4 -2
  58. package/dist/analytics/tables/requestEvents.js.map +1 -1
  59. package/dist/apps/data/App.d.ts +11932 -13214
  60. package/dist/apps/data/App.d.ts.map +1 -1
  61. package/dist/apps/data/App.js +32 -13
  62. package/dist/apps/data/App.js.map +1 -1
  63. package/dist/apps/data/ZoneSelection.d.ts +1 -1
  64. package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
  65. package/dist/apps/data/ZoneSelection.js +2 -2
  66. package/dist/apps/data/ZoneSelection.js.map +1 -1
  67. package/dist/apps/data/routes/activities.d.ts +60 -27
  68. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  69. package/dist/apps/data/routes/activities.js +91 -16
  70. package/dist/apps/data/routes/activities.js.map +1 -1
  71. package/dist/apps/data/routes/addresses.d.ts +893 -875
  72. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  73. package/dist/apps/data/routes/balances.d.ts +36 -36
  74. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  75. package/dist/apps/data/routes/balances.js +3 -1
  76. package/dist/apps/data/routes/balances.js.map +1 -1
  77. package/dist/apps/data/routes/blocks.d.ts +40 -40
  78. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  79. package/dist/apps/data/routes/blocks.js +3 -7
  80. package/dist/apps/data/routes/blocks.js.map +1 -1
  81. package/dist/apps/data/routes/coingecko.d.ts +236 -236
  82. package/dist/apps/data/routes/earn-transactions.d.ts +14 -14
  83. package/dist/apps/data/routes/earn.d.ts +261 -1445
  84. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  85. package/dist/apps/data/routes/earn.js +64 -490
  86. package/dist/apps/data/routes/earn.js.map +1 -1
  87. package/dist/apps/data/routes/exchanges.d.ts +144 -144
  88. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  89. package/dist/apps/data/routes/exchanges.js +5 -15
  90. package/dist/apps/data/routes/exchanges.js.map +1 -1
  91. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  92. package/dist/apps/data/routes/fee-amm.js +3 -9
  93. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  94. package/dist/apps/data/routes/indexer.d.ts +13 -13
  95. package/dist/apps/data/routes/receipts.d.ts +53 -53
  96. package/dist/apps/data/routes/receipts.js +1 -1
  97. package/dist/apps/data/routes/receipts.js.map +1 -1
  98. package/dist/apps/data/routes/rpc.d.ts +52 -0
  99. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  100. package/dist/apps/data/routes/rpc.js +19 -18
  101. package/dist/apps/data/routes/rpc.js.map +1 -1
  102. package/dist/apps/data/routes/tokenlist.d.ts +14 -14
  103. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  104. package/dist/apps/data/routes/tokenlist.js +1 -3
  105. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  106. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  107. package/dist/apps/data/routes/tokens.js +7 -5
  108. package/dist/apps/data/routes/tokens.js.map +1 -1
  109. package/dist/apps/data/routes/transactions.d.ts +281 -281
  110. package/dist/apps/data/routes/transactions.js +3 -3
  111. package/dist/apps/data/routes/transactions.js.map +1 -1
  112. package/dist/apps/data/routes/transfers.d.ts +12 -12
  113. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  114. package/dist/apps/data/routes/transfers.js +1 -3
  115. package/dist/apps/data/routes/transfers.js.map +1 -1
  116. package/dist/apps/data/routes/valuation.d.ts +30 -30
  117. package/dist/apps/data/routes/valuation.d.ts.map +1 -1
  118. package/dist/apps/data/routes/valuation.js +1 -3
  119. package/dist/apps/data/routes/valuation.js.map +1 -1
  120. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  121. package/dist/apps/data/routes/webhooks.d.ts +102 -102
  122. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  123. package/dist/apps/data/routes/webhooks.js +9 -23
  124. package/dist/apps/data/routes/webhooks.js.map +1 -1
  125. package/dist/apps/data/routes/zone-deposits.d.ts +16 -16
  126. package/dist/apps/data/routes/zone-withdrawals.d.ts +31 -31
  127. package/dist/apps/data/routes/zones.d.ts +28 -28
  128. package/dist/apps/management/App.d.ts +18 -102
  129. package/dist/apps/management/App.d.ts.map +1 -1
  130. package/dist/apps/management/App.js +1 -1
  131. package/dist/apps/management/App.js.map +1 -1
  132. package/dist/apps/management/routes/api-keys.d.ts +253 -339
  133. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  134. package/dist/apps/management/routes/api-keys.js +25 -11
  135. package/dist/apps/management/routes/api-keys.js.map +1 -1
  136. package/dist/apps/management/routes/billing.d.ts +92 -92
  137. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  138. package/dist/apps/management/routes/billing.js +5 -13
  139. package/dist/apps/management/routes/billing.js.map +1 -1
  140. package/dist/apps/management/routes/cli.d.ts.map +1 -1
  141. package/dist/apps/management/routes/cli.js +3 -9
  142. package/dist/apps/management/routes/cli.js.map +1 -1
  143. package/dist/apps/management/routes/faucet.d.ts +16 -16
  144. package/dist/apps/management/routes/fee-payer-usage.d.ts +38 -38
  145. package/dist/apps/management/routes/fee-payer-usage.d.ts.map +1 -1
  146. package/dist/apps/management/routes/fee-payer-usage.js +2 -4
  147. package/dist/apps/management/routes/fee-payer-usage.js.map +1 -1
  148. package/dist/apps/management/routes/invitations.d.ts +52 -52
  149. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  150. package/dist/apps/management/routes/invitations.js +4 -12
  151. package/dist/apps/management/routes/invitations.js.map +1 -1
  152. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  153. package/dist/apps/management/routes/invite-links.js +6 -14
  154. package/dist/apps/management/routes/invite-links.js.map +1 -1
  155. package/dist/apps/management/routes/me.d.ts +6 -6
  156. package/dist/apps/management/routes/me.d.ts.map +1 -1
  157. package/dist/apps/management/routes/me.js +3 -7
  158. package/dist/apps/management/routes/me.js.map +1 -1
  159. package/dist/apps/management/routes/members.d.ts +84 -84
  160. package/dist/apps/management/routes/members.d.ts.map +1 -1
  161. package/dist/apps/management/routes/members.js +2 -4
  162. package/dist/apps/management/routes/members.js.map +1 -1
  163. package/dist/apps/management/routes/orgs.d.ts +44 -44
  164. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  165. package/dist/apps/management/routes/orgs.js +2 -6
  166. package/dist/apps/management/routes/orgs.js.map +1 -1
  167. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  168. package/dist/apps/management/routes/projects.js +2 -6
  169. package/dist/apps/management/routes/projects.js.map +1 -1
  170. package/dist/apps/management/routes/route-usage.d.ts +34 -34
  171. package/dist/apps/management/routes/route-usage.d.ts.map +1 -1
  172. package/dist/apps/management/routes/route-usage.js +2 -4
  173. package/dist/apps/management/routes/route-usage.js.map +1 -1
  174. package/dist/apps/management/routes/routes-access-requests.d.ts +120 -91
  175. package/dist/apps/management/routes/routes-access-requests.d.ts.map +1 -1
  176. package/dist/apps/management/routes/routes-access-requests.js +49 -9
  177. package/dist/apps/management/routes/routes-access-requests.js.map +1 -1
  178. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  179. package/dist/apps/management/routes/usage.js +8 -16
  180. package/dist/apps/management/routes/usage.js.map +1 -1
  181. package/dist/apps/management/routes/verified-token-requests.d.ts +39 -39
  182. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  183. package/dist/apps/management/routes/verified-token-requests.js +3 -7
  184. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  185. package/dist/apps/management/routes/webhooks.d.ts +2089 -2089
  186. package/dist/apps/management/routes/zone-delegations.d.ts +14 -17
  187. package/dist/apps/management/routes/zone-delegations.d.ts.map +1 -1
  188. package/dist/apps/management/routes/zone-delegations.js +1 -6
  189. package/dist/apps/management/routes/zone-delegations.js.map +1 -1
  190. package/dist/apps/mpp/App.d.ts +44 -44
  191. package/dist/apps/mpp/App.js +3 -3
  192. package/dist/apps/mpp/App.js.map +1 -1
  193. package/dist/apps/mpp/internal/Adapter.js +1 -1
  194. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  195. package/dist/apps/mpp/internal/Error.d.ts.map +1 -1
  196. package/dist/apps/mpp/internal/Error.js +1 -0
  197. package/dist/apps/mpp/internal/Error.js.map +1 -1
  198. package/dist/apps/mpp/internal/Policy.d.ts +5 -1
  199. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  200. package/dist/apps/mpp/internal/Policy.js +35 -13
  201. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  202. package/dist/apps/relay/App.d.ts +2 -2
  203. package/dist/apps/relay/App.d.ts.map +1 -1
  204. package/dist/apps/relay/App.js +25 -16
  205. package/dist/apps/relay/App.js.map +1 -1
  206. package/dist/apps/routes/App.d.ts +311 -311
  207. package/dist/apps/routes/routes/deposit-addresses.d.ts +1099 -1099
  208. package/dist/apps/routes/routes/list.d.ts +74 -74
  209. package/dist/apps/routes/routes/transfers.d.ts +94 -94
  210. package/dist/cli/ApiKeys.d.ts +19 -26
  211. package/dist/cli/ApiKeys.d.ts.map +1 -1
  212. package/dist/db/Db.d.ts +3 -3
  213. package/dist/db/Db.d.ts.map +1 -1
  214. package/dist/db/Db.js +27 -0
  215. package/dist/db/Db.js.map +1 -1
  216. package/dist/db/Schema.d.ts +28 -62
  217. package/dist/db/Schema.d.ts.map +1 -1
  218. package/dist/db/Schema.js +18 -18
  219. package/dist/db/Schema.js.map +1 -1
  220. package/dist/db/tables/rewardRuns.d.ts +21 -0
  221. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  222. package/dist/db/tables/rewardRuns.js +19 -0
  223. package/dist/db/tables/rewardRuns.js.map +1 -1
  224. package/dist/db/tables/routesAccessRequests.d.ts +13 -0
  225. package/dist/db/tables/routesAccessRequests.d.ts.map +1 -1
  226. package/dist/db/tables/routesAccessRequests.js +12 -0
  227. package/dist/db/tables/routesAccessRequests.js.map +1 -1
  228. package/dist/db/tables/zoneDelegationRequests.d.ts +165 -0
  229. package/dist/db/tables/zoneDelegationRequests.d.ts.map +1 -0
  230. package/dist/db/tables/{zoneKeyRequests.js → zoneDelegationRequests.js} +43 -42
  231. package/dist/db/tables/zoneDelegationRequests.js.map +1 -0
  232. package/dist/db/tables/zoneDelegations.d.ts +11 -5
  233. package/dist/db/tables/zoneDelegations.d.ts.map +1 -1
  234. package/dist/db/tables/zoneDelegations.js +21 -3
  235. package/dist/db/tables/zoneDelegations.js.map +1 -1
  236. package/dist/handlers/internal/accounts.d.ts +7 -0
  237. package/dist/handlers/internal/accounts.d.ts.map +1 -0
  238. package/dist/handlers/internal/{multisig.js → accounts.js} +10 -10
  239. package/dist/handlers/internal/{multisig.js.map → accounts.js.map} +1 -1
  240. package/dist/handlers/internal/sponsorship.js +17 -17
  241. package/dist/handlers/internal/sponsorship.js.map +1 -1
  242. package/dist/handlers/relay.d.ts +6 -6
  243. package/dist/handlers/relay.d.ts.map +1 -1
  244. package/dist/handlers/relay.js +15 -15
  245. package/dist/handlers/relay.js.map +1 -1
  246. package/dist/internal/Auth.d.ts.map +1 -1
  247. package/dist/internal/Auth.js +4 -8
  248. package/dist/internal/Auth.js.map +1 -1
  249. package/dist/internal/EarnRates.d.ts.map +1 -1
  250. package/dist/internal/EarnRates.js +1 -3
  251. package/dist/internal/EarnRates.js.map +1 -1
  252. package/dist/internal/EarnVaults.js +2 -2
  253. package/dist/internal/Log.d.ts +2 -4
  254. package/dist/internal/Log.d.ts.map +1 -1
  255. package/dist/internal/Log.js +0 -3
  256. package/dist/internal/Log.js.map +1 -1
  257. package/dist/internal/Response.d.ts +1 -1
  258. package/dist/internal/Response.d.ts.map +1 -1
  259. package/dist/internal/Response.js +0 -3
  260. package/dist/internal/Response.js.map +1 -1
  261. package/dist/internal/Schema.d.ts +11 -0
  262. package/dist/internal/Schema.d.ts.map +1 -1
  263. package/dist/internal/Schema.js +24 -1
  264. package/dist/internal/Schema.js.map +1 -1
  265. package/dist/internal/ZoneAccess.d.ts +70 -35
  266. package/dist/internal/ZoneAccess.d.ts.map +1 -1
  267. package/dist/internal/ZoneAccess.js +312 -131
  268. package/dist/internal/ZoneAccess.js.map +1 -1
  269. package/dist/internal/ZoneDelegation.d.ts +7 -19
  270. package/dist/internal/ZoneDelegation.d.ts.map +1 -1
  271. package/dist/internal/ZoneDelegation.js +8 -29
  272. package/dist/internal/ZoneDelegation.js.map +1 -1
  273. package/dist/internal/{ZoneKeyApproval.d.ts → ZoneDelegationApproval.d.ts} +3 -5
  274. package/dist/internal/ZoneDelegationApproval.d.ts.map +1 -0
  275. package/dist/internal/ZoneDelegationApproval.js +16 -0
  276. package/dist/internal/ZoneDelegationApproval.js.map +1 -0
  277. package/dist/internal/ZoneKeyRewrite.d.ts +98 -0
  278. package/dist/internal/ZoneKeyRewrite.d.ts.map +1 -0
  279. package/dist/internal/ZoneKeyRewrite.js +151 -0
  280. package/dist/internal/ZoneKeyRewrite.js.map +1 -0
  281. package/dist/internal/rewards/Campaigns.d.ts +2 -0
  282. package/dist/internal/rewards/Campaigns.d.ts.map +1 -1
  283. package/dist/internal/rewards/Campaigns.js.map +1 -1
  284. package/dist/internal/rewards/Distributions.d.ts.map +1 -1
  285. package/dist/internal/rewards/Distributions.js +2 -6
  286. package/dist/internal/rewards/Distributions.js.map +1 -1
  287. package/dist/internal/rewards/Monitor.d.ts +4 -1
  288. package/dist/internal/rewards/Monitor.d.ts.map +1 -1
  289. package/dist/internal/rewards/Monitor.js +19 -2
  290. package/dist/internal/rewards/Monitor.js.map +1 -1
  291. package/dist/internal/rewards/Runner.d.ts.map +1 -1
  292. package/dist/internal/rewards/Runner.js +9 -1
  293. package/dist/internal/rewards/Runner.js.map +1 -1
  294. package/dist/internal/routes/Action.d.ts.map +1 -1
  295. package/dist/internal/routes/Action.js +2 -3
  296. package/dist/internal/routes/Action.js.map +1 -1
  297. package/dist/internal/routes/Deposit.d.ts.map +1 -1
  298. package/dist/internal/routes/Deposit.js +2 -6
  299. package/dist/internal/routes/Deposit.js.map +1 -1
  300. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  301. package/dist/internal/routes/DepositAddress.js +4 -10
  302. package/dist/internal/routes/DepositAddress.js.map +1 -1
  303. package/dist/internal/routes/Policy.d.ts.map +1 -1
  304. package/dist/internal/routes/Policy.js +2 -1
  305. package/dist/internal/routes/Policy.js.map +1 -1
  306. package/dist/internal/routes/Provider.js +8 -8
  307. package/dist/internal/routes/Provider.js.map +1 -1
  308. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  309. package/dist/internal/routes/Reconciliation.js +3 -2
  310. package/dist/internal/routes/Reconciliation.js.map +1 -1
  311. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  312. package/dist/internal/routes/Transfer.js +4 -12
  313. package/dist/internal/routes/Transfer.js.map +1 -1
  314. package/dist/internal/routes/UniversalDepositAddress.d.ts.map +1 -1
  315. package/dist/internal/routes/UniversalDepositAddress.js +3 -6
  316. package/dist/internal/routes/UniversalDepositAddress.js.map +1 -1
  317. package/dist/internal/routes/providers/SquidOrder.d.ts.map +1 -1
  318. package/dist/internal/routes/providers/SquidOrder.js +3 -2
  319. package/dist/internal/routes/providers/SquidOrder.js.map +1 -1
  320. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  321. package/dist/internal/routes/providers/relay.js +4 -3
  322. package/dist/internal/routes/providers/relay.js.map +1 -1
  323. package/package.json +20 -5
  324. package/src/ApiKey.ts +2 -2
  325. package/src/ApiKeys.test.ts +284 -51
  326. package/src/ApiKeys.ts +297 -64
  327. package/src/App.ts +4 -5
  328. package/src/Client.test-d.ts +33 -126
  329. package/src/Scope.test.ts +26 -45
  330. package/src/Scope.ts +24 -37
  331. package/src/admin/App.test.ts +51 -4
  332. package/src/admin/App.ts +25 -33
  333. package/src/admin/Mcp.test.ts +2 -1
  334. package/src/admin/apps/api-keys.test.ts +90 -20
  335. package/src/admin/apps/api-keys.ts +5 -8
  336. package/src/admin/apps/audit-logs.ts +1 -1
  337. package/src/admin/apps/earn-vaults.test.ts +19 -19
  338. package/src/admin/apps/earn-vaults.ts +11 -5
  339. package/src/admin/apps/routes-support.test.ts +254 -3
  340. package/src/admin/apps/routes-support.ts +1 -44
  341. package/src/admin/apps/scopes.test.ts +3 -3
  342. package/src/admin/apps/zone-delegation-requests.test.ts +246 -0
  343. package/src/admin/apps/zone-delegation-requests.ts +240 -0
  344. package/src/admin/apps/zone-delegations.test.ts +218 -58
  345. package/src/admin/apps/zone-delegations.ts +146 -46
  346. package/src/admin/index.ts +1 -1
  347. package/src/admin/ui/src/components/ApiKeyForm.tsx +4 -3
  348. package/src/admin/ui/src/lib/config.ts +3 -3
  349. package/src/admin/ui/src/lib/query-client.ts +1 -1
  350. package/src/admin/ui/src/lib/review-queues.ts +10 -10
  351. package/src/admin/ui/src/lib/routes-setup.test.ts +1 -2
  352. package/src/admin/ui/src/lib/routes-setup.ts +3 -5
  353. package/src/admin/ui/src/lib/scopes.test.ts +3 -6
  354. package/src/admin/ui/src/lib/scopes.ts +2 -9
  355. package/src/admin/ui/src/lib/{zone-key-requests.ts → zone-delegation-requests.ts} +27 -31
  356. package/src/admin/ui/src/routeTree.gen.ts +17 -17
  357. package/src/admin/ui/src/routes/__root.tsx +1 -1
  358. package/src/admin/ui/src/routes/api-keys.tsx +2 -15
  359. package/src/admin/ui/src/routes/audit-logs.tsx +2 -2
  360. package/src/admin/ui/src/routes/index.tsx +11 -11
  361. package/src/admin/ui/src/routes/organizations.tsx +3 -1
  362. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +3 -1
  363. package/src/admin/ui/src/routes/organizations_.$orgId_.setup.tsx +1 -3
  364. package/src/admin/ui/src/routes/{zone-key-requests.tsx → zone-delegation-requests.tsx} +228 -172
  365. package/src/admin/ui/vite.config.ts +14 -1
  366. package/src/admin/ui.generated.ts +412 -583
  367. package/src/analytics/tables/requestEvents.test.ts +13 -3
  368. package/src/analytics/tables/requestEvents.ts +4 -3
  369. package/src/apps/data/App.test.ts +72 -35
  370. package/src/apps/data/App.ts +29 -13
  371. package/src/apps/data/ZoneSelection.test.ts +53 -70
  372. package/src/apps/data/ZoneSelection.ts +2 -2
  373. package/src/apps/data/routes/activities.test.ts +140 -6
  374. package/src/apps/data/routes/activities.ts +124 -18
  375. package/src/apps/data/routes/balances.ts +5 -1
  376. package/src/apps/data/routes/blocks.ts +9 -13
  377. package/src/apps/data/routes/earn-transactions.local.test.ts +6 -1
  378. package/src/apps/data/routes/earn-transactions.test.ts +7 -3
  379. package/src/apps/data/routes/earn.bench.ts +0 -14
  380. package/src/apps/data/routes/earn.discovery.test.ts +4 -39
  381. package/src/apps/data/routes/earn.local.test.ts +27 -34
  382. package/src/apps/data/routes/earn.test.ts +172 -490
  383. package/src/apps/data/routes/earn.ts +103 -652
  384. package/src/apps/data/routes/exchanges.ts +20 -30
  385. package/src/apps/data/routes/fee-amm.ts +12 -18
  386. package/src/apps/data/routes/indexer.test.ts +14 -12
  387. package/src/apps/data/routes/receipts.ts +1 -1
  388. package/src/apps/data/routes/rpc.test.ts +23 -18
  389. package/src/apps/data/routes/rpc.ts +21 -21
  390. package/src/apps/data/routes/rpc.zone.test.ts +60 -6
  391. package/src/apps/data/routes/tokenlist.ts +4 -6
  392. package/src/apps/data/routes/tokens.test.ts +20 -0
  393. package/src/apps/data/routes/tokens.ts +10 -5
  394. package/src/apps/data/routes/transactions.ts +3 -3
  395. package/src/apps/data/routes/transfers.ts +4 -6
  396. package/src/apps/data/routes/valuation.test.ts +2 -4
  397. package/src/apps/data/routes/valuation.ts +4 -6
  398. package/src/apps/data/routes/webhooks.test.ts +1 -5
  399. package/src/apps/data/routes/webhooks.ts +30 -44
  400. package/src/apps/data/routes/zones.test.ts +35 -19
  401. package/src/apps/management/App.ts +3 -1
  402. package/src/apps/management/routes/api-keys.test.ts +112 -22
  403. package/src/apps/management/routes/api-keys.ts +30 -15
  404. package/src/apps/management/routes/billing.ts +17 -25
  405. package/src/apps/management/routes/cli.ts +12 -18
  406. package/src/apps/management/routes/fee-payer-usage.ts +5 -4
  407. package/src/apps/management/routes/invitations.ts +16 -21
  408. package/src/apps/management/routes/invite-links.ts +18 -26
  409. package/src/apps/management/routes/me.ts +9 -13
  410. package/src/apps/management/routes/members.ts +5 -7
  411. package/src/apps/management/routes/orgs.ts +8 -12
  412. package/src/apps/management/routes/projects.ts +8 -12
  413. package/src/apps/management/routes/route-usage.ts +5 -4
  414. package/src/apps/management/routes/routes-access-requests.test.ts +64 -2
  415. package/src/apps/management/routes/routes-access-requests.ts +99 -15
  416. package/src/apps/management/routes/scopes.test.ts +3 -3
  417. package/src/apps/management/routes/usage.ts +20 -28
  418. package/src/apps/management/routes/verified-token-requests.ts +9 -13
  419. package/src/apps/management/routes/zone-delegations.test.ts +3 -5
  420. package/src/apps/management/routes/zone-delegations.ts +4 -9
  421. package/src/apps/mpp/App.ts +3 -3
  422. package/src/apps/mpp/Mpp.zone.test.ts +49 -18
  423. package/src/apps/mpp/internal/Adapter.ts +1 -1
  424. package/src/apps/mpp/internal/Error.test.ts +3 -0
  425. package/src/apps/mpp/internal/Error.ts +1 -0
  426. package/src/apps/mpp/internal/Policy.test.ts +9 -8
  427. package/src/apps/mpp/internal/Policy.ts +37 -14
  428. package/src/apps/relay/App.sandbox.test.ts +15 -14
  429. package/src/apps/relay/App.test.ts +120 -61
  430. package/src/apps/relay/App.ts +28 -18
  431. package/src/apps/relay/App.zone-billing.test.ts +9 -4
  432. package/src/apps/routes/App.test.ts +21 -22
  433. package/src/db/Db.ts +34 -3
  434. package/src/db/Schema.ts +26 -26
  435. package/src/db/tables/rewardRuns.ts +39 -0
  436. package/src/db/tables/routesAccessRequests.test.ts +65 -0
  437. package/src/db/tables/routesAccessRequests.ts +25 -0
  438. package/src/db/tables/{zoneKeyRequests.test.ts → zoneDelegationRequests.test.ts} +36 -77
  439. package/src/db/tables/{zoneKeyRequests.ts → zoneDelegationRequests.ts} +69 -52
  440. package/src/db/tables/zoneDelegations.test.ts +5 -6
  441. package/src/db/tables/zoneDelegations.ts +25 -8
  442. package/src/handlers/internal/{multisig.store.test.ts → accounts.store.test.ts} +16 -16
  443. package/src/handlers/internal/{multisig.test.ts → accounts.test.ts} +85 -82
  444. package/src/handlers/internal/{multisig.ts → accounts.ts} +9 -9
  445. package/src/handlers/internal/sponsorship.ts +20 -20
  446. package/src/handlers/relay.test.ts +48 -46
  447. package/src/handlers/relay.ts +26 -26
  448. package/src/internal/Auth.test.ts +6 -2
  449. package/src/internal/Auth.ts +4 -10
  450. package/src/internal/EarnRates.ts +4 -6
  451. package/src/internal/EarnVaults.ts +2 -2
  452. package/src/internal/Log.test-d.ts +1 -0
  453. package/src/internal/Log.test.ts +4 -6
  454. package/src/internal/Log.ts +2 -6
  455. package/src/internal/Response.ts +0 -3
  456. package/src/internal/Schema.test.ts +42 -0
  457. package/src/internal/Schema.ts +36 -1
  458. package/src/internal/ZoneAccess.test.ts +515 -312
  459. package/src/internal/ZoneAccess.ts +410 -158
  460. package/src/internal/ZoneDelegation.test.ts +1 -41
  461. package/src/internal/ZoneDelegation.ts +10 -48
  462. package/src/internal/ZoneDelegationApproval.test.ts +22 -0
  463. package/src/internal/{ZoneKeyApproval.ts → ZoneDelegationApproval.ts} +4 -11
  464. package/src/internal/ZoneKeyRewrite.ts +231 -0
  465. package/src/internal/rewards/Campaigns.ts +2 -0
  466. package/src/internal/rewards/Distributions.ts +8 -12
  467. package/src/internal/rewards/Monitor.test.ts +64 -0
  468. package/src/internal/rewards/Monitor.ts +27 -4
  469. package/src/internal/rewards/Runner.ts +9 -1
  470. package/src/internal/routes/Action.ts +5 -6
  471. package/src/internal/routes/Deposit.ts +8 -12
  472. package/src/internal/routes/DepositAddress.ts +13 -19
  473. package/src/internal/routes/Policy.ts +2 -1
  474. package/src/internal/routes/Provider.ts +8 -8
  475. package/src/internal/routes/Reconciliation.ts +3 -2
  476. package/src/internal/routes/Transfer.ts +16 -24
  477. package/src/internal/routes/UniversalDepositAddress.ts +9 -12
  478. package/src/internal/routes/providers/SquidOrder.ts +3 -2
  479. package/src/internal/routes/providers/relay.ts +4 -3
  480. package/dist/admin/apps/zone-key-requests.d.ts +0 -406
  481. package/dist/admin/apps/zone-key-requests.d.ts.map +0 -1
  482. package/dist/admin/apps/zone-key-requests.js +0 -183
  483. package/dist/admin/apps/zone-key-requests.js.map +0 -1
  484. package/dist/db/tables/zoneKeyRequests.d.ts +0 -289
  485. package/dist/db/tables/zoneKeyRequests.d.ts.map +0 -1
  486. package/dist/db/tables/zoneKeyRequests.js.map +0 -1
  487. package/dist/handlers/internal/multisig.d.ts +0 -7
  488. package/dist/handlers/internal/multisig.d.ts.map +0 -1
  489. package/dist/internal/ZoneKeyApproval.d.ts.map +0 -1
  490. package/dist/internal/ZoneKeyApproval.js +0 -21
  491. package/dist/internal/ZoneKeyApproval.js.map +0 -1
  492. package/src/admin/apps/zone-key-requests.test.ts +0 -272
  493. package/src/admin/apps/zone-key-requests.ts +0 -231
  494. package/src/internal/ZoneKeyApproval.test.ts +0 -46
@@ -26,7 +26,7 @@ import * as Viem from '../../internal/Viem.js'
26
26
  import * as ZoneAccess from '../../internal/ZoneAccess.js'
27
27
  import * as ZoneRpc from '../../internal/ZoneRpc.js'
28
28
  import * as Utils from '../../handlers/internal/utils.js'
29
- import * as Multisig from '../../handlers/internal/multisig.js'
29
+ import * as Accounts from '../../handlers/internal/accounts.js'
30
30
  import * as Sponsorship from '../../handlers/internal/sponsorship.js'
31
31
  import * as Scope from '../../Scope.js'
32
32
 
@@ -43,7 +43,7 @@ import * as Scope from '../../Scope.js'
43
43
  */
44
44
  /** Methods that broadcast or approve a Zone transaction, requiring the write scope. */
45
45
  function isZoneWriteMethod(method: string): boolean {
46
- return ZoneRpc.writeMethods.has(method) || method.startsWith('multisig_approve')
46
+ return ZoneRpc.writeMethods.has(method) || method.startsWith('account_approve')
47
47
  }
48
48
 
49
49
  export function relay(options: relay.Options = {}) {
@@ -81,6 +81,8 @@ export function relay(options: relay.Options = {}) {
81
81
  export declare namespace relay {
82
82
  /** Options for the relay route group. */
83
83
  type Options = {
84
+ /** Configurable account coordination backed by authoritative atomic storage. */
85
+ accounts?: Handler.relay.Options['accounts'] | undefined
84
86
  feePayer?:
85
87
  | (Pick<
86
88
  NonNullable<Handler.relay.Options['feePayer']>,
@@ -97,8 +99,6 @@ export declare namespace relay {
97
99
  txFeeLimit?: string | undefined
98
100
  })
99
101
  | undefined
100
- /** Native multisig coordination backed by authoritative atomic storage. */
101
- multisig?: Handler.relay.Options['multisig'] | undefined
102
102
  }
103
103
  }
104
104
 
@@ -491,7 +491,15 @@ function middleware(options: middleware.Options) {
491
491
  })()
492
492
  const chainId_query = query?.success ? query.data : undefined
493
493
  const chainId_selected = chainId_path ?? chainId_query
494
+ // Batch items run concurrently, but their Zone decisions settle in item order, so an
495
+ // admitted item after a denial is what stays recorded whatever their reads take.
496
+ let decisions: Promise<unknown> = Promise.resolve()
494
497
  const authorizeChainId = (chainId: number | undefined, method?: string) => {
498
+ const next = decisions.then(() => decideChainId(chainId, method))
499
+ decisions = next.catch(() => undefined)
500
+ return next
501
+ }
502
+ const decideChainId = async (chainId: number | undefined, method?: string) => {
495
503
  // A malformed selector must not silently fall back to the default chain.
496
504
  if (query && !query.success)
497
505
  throw new RpcResponse.InvalidParamsError({ message: 'Invalid chain id.' })
@@ -521,7 +529,7 @@ function middleware(options: middleware.Options) {
521
529
  // A refused mainnet Zone still records the attempt against that Zone,
522
530
  // unless another batch item already recorded its decision.
523
531
  if (c.get('zones').has(resolved) && c.get('zoneAccess') === undefined) {
524
- ZoneAccess.authorize(c, {
532
+ await ZoneAccess.authorize(c, {
525
533
  chainId: resolved,
526
534
  verb: 'read',
527
535
  zoneToken: zoneToken !== undefined,
@@ -540,7 +548,7 @@ function middleware(options: middleware.Options) {
540
548
  })
541
549
  }
542
550
  if (c.get('zones').has(resolved)) {
543
- // Broadcasts and multisig approvals need the write scope, other methods
551
+ // Broadcasts and configurable account approvals need the write scope, other methods
544
552
  // the read scope; a Zone token admits both. Decided on the executing chain.
545
553
  const options_access = {
546
554
  chainId: resolved,
@@ -548,21 +556,23 @@ function middleware(options: middleware.Options) {
548
556
  verb: method !== undefined && isZoneWriteMethod(method) ? 'write' : 'read',
549
557
  zoneToken: zoneToken !== undefined,
550
558
  } as const
551
- const result = ZoneAccess.check(c, options_access)
552
559
  // A request keeps one decision: the first, or an admitted item after a denial.
553
560
  const recorded = c.get('zoneAccess')
554
- if (recorded === undefined || (result.allowed && recorded.grant === undefined))
555
- ZoneAccess.authorize(c, options_access)
561
+ const result =
562
+ recorded === undefined || recorded.grant === undefined
563
+ ? await ZoneAccess.authorize(c, options_access)
564
+ : ZoneAccess.check(c, options_access)
556
565
  if (result.allowed) return resolved
557
- const { message } = result.error
566
+ const { code, message } = result.error
558
567
  if (sponsorshipRequired)
559
568
  rejectSponsorship({
560
569
  chainId: resolved,
561
570
  message,
562
- reason: 'api_key_forbidden',
571
+ // An unreadable delegation keeps its retriable code instead of reading as a missing grant.
572
+ reason: code,
563
573
  })
564
574
  throw new RpcResponse.InvalidParamsError({
565
- data: { code: 'api_key_forbidden' },
575
+ data: { code },
566
576
  message,
567
577
  })
568
578
  }
@@ -574,9 +584,9 @@ function middleware(options: middleware.Options) {
574
584
  chainId: number | undefined,
575
585
  options: Handler.relay.GetClientOptions = {},
576
586
  ) => {
577
- const resolved = authorizeChainId(chainId, options.method) as Viem.ChainId
587
+ const resolved = (await authorizeChainId(chainId, options.method)) as Viem.ChainId
578
588
  const zone = c.get('zones').get(resolved)
579
- // Verify the resolved client chain, including raw envelopes and stored multisig operations, before any upstream access.
589
+ // Verify the resolved client chain, including raw envelopes and stored configurable account operations, before any upstream access.
580
590
  if (zone?.sourceId !== undefined && Viem.isMainnet(zone.sourceId)) {
581
591
  const policy = c.get('vercelOidc')
582
592
  if (policy?.applies(principal)) {
@@ -617,7 +627,7 @@ function middleware(options: middleware.Options) {
617
627
  cache: c.get('store'),
618
628
  ...(options.features ? { features: options.features } : {}),
619
629
  getClient,
620
- ...(options.multisig ? { multisig: options.multisig } : {}),
630
+ ...(options.accounts ? { accounts: options.accounts } : {}),
621
631
  onRequest: async (request) => {
622
632
  const method = sponsorshipMethod(request.method)
623
633
  const params = 'params' in request && Array.isArray(request.params) ? request.params : []
@@ -645,19 +655,19 @@ function middleware(options: middleware.Options) {
645
655
  })()
646
656
  // Zone-scoped keys without a token reach the operator RPC, so the
647
657
  // allowlist applies regardless of token; account-scoped reads need one.
648
- // Multisig coordination stays local and authorizes its stored chain via `getClient`.
658
+ // Configurable account coordination stays local and authorizes its stored chain via `getClient`.
649
659
  if (
650
660
  c.get('zones').has(chainId) &&
651
661
  !ZoneRpc.readMethods.has(request.method) &&
652
662
  !ZoneRpc.writeMethods.has(request.method) &&
653
663
  !(zoneToken && ZoneRpc.tokenMethods.has(request.method)) &&
654
- !(options.multisig && Multisig.methods.has(request.method)) &&
664
+ !(options.accounts && Accounts.methods.has(request.method)) &&
655
665
  !rawSponsorship
656
666
  ) {
657
667
  // The method refusal precedes the chain gate, so record the denied Zone
658
668
  // attempt unless an admitted batch item already recorded its decision.
659
669
  if (c.get('zoneAccess') === undefined) {
660
- ZoneAccess.authorize(c, { chainId, verb: 'read', zoneToken: zoneToken !== undefined })
670
+ await ZoneAccess.authorize(c, { chainId, verb: 'read', zoneToken: zoneToken !== undefined }) // prettier-ignore
661
671
  ZoneAccess.deny(c)
662
672
  }
663
673
  throw new RpcResponse.MethodNotSupportedError({
@@ -128,7 +128,7 @@ describe('Zone sponsorship billing', () => {
128
128
  test('counts Zone spend against the shared attribution promotion', async () => {
129
129
  const { app, db } = await setup()
130
130
  await StripeCustomers.setStatus(db, 'org_zone', 'active')
131
- await Organizations.create(db, { id: 'org_zone', name: 'Zone' })
131
+ // The organization row exists: the delegation fixture created it.
132
132
  await Organizations.setSponsorshipSubsidy(db, 'org_zone', {
133
133
  attributionSpendLimit: '0.75',
134
134
  durationDays: 90,
@@ -209,6 +209,8 @@ async function setup(options: setup.Options = {}) {
209
209
  )
210
210
  for (const id of chainIds) await VerifiedTokens.replace(db, id, [token])
211
211
  await StripeCustomers.create(db, { orgId: 'org_zone', stripeCustomerId: 'cus_zone' })
212
+ await TestApp.delegateZone(db, { chainIds, orgId: 'org_zone' })
213
+ await TestApp.delegateZone(db, { chainIds, environment: 'sandbox', orgId: 'org_zone' })
212
214
  const app = TestApp.create({
213
215
  auth: {
214
216
  keys: [
@@ -216,22 +218,25 @@ async function setup(options: setup.Options = {}) {
216
218
  environment: 'production',
217
219
  id: 'key_production',
218
220
  orgId: 'org_zone',
219
- scopes: ['rpc-relay:sponsor', ...chainIds.map((id) => `zone:${id}:read` as const)],
221
+ scopes: ['rpc-relay:sponsor', 'zone:read'],
220
222
  token: 'production',
223
+ zoneTags: chainIds,
221
224
  },
222
225
  {
223
226
  environment: 'sandbox',
224
227
  id: 'key_sandbox',
225
228
  orgId: 'org_zone',
226
- scopes: ['rpc-relay:sponsor', `zone:${chainId}:read`],
229
+ scopes: ['rpc-relay:sponsor', 'zone:read'],
227
230
  token: 'sandbox',
231
+ zoneTags: [chainId],
228
232
  },
229
233
  {
230
234
  environment: 'sandbox',
231
235
  id: 'key_sandbox_wildcard',
232
236
  orgId: 'org_zone',
233
- scopes: ['*'],
237
+ scopes: ['*', 'zone:read', 'zone:write'],
234
238
  token: 'sandbox_wildcard',
239
+ zoneTags: chainIds,
235
240
  },
236
241
  ],
237
242
  },
@@ -43,13 +43,12 @@ describe('routes access', () => {
43
43
 
44
44
  test('rejects sandbox keys on a mainnet-backed default Zone', async () => {
45
45
  const chainId = 421_700_001
46
- const key = {
47
- ...sandbox,
48
- scopes: [...sandbox.scopes, `zone:${chainId}:read`],
49
- } satisfies TestApp.kvStore.Key
46
+ const key = TestApp.zoneReader(sandbox, [chainId])
47
+ const db = TestApp.database()
48
+ await TestApp.delegateZone(db, { chainIds: [chainId], environment: 'sandbox', orgId: key.orgId }) // prettier-ignore
50
49
  const app = App.create({
51
50
  auth: {},
52
- db: TestApp.database(),
51
+ db,
53
52
  defaultChainId: chainId,
54
53
  kv: { store: TestApp.kvStore({ keys: [key] }) },
55
54
  zones: [
@@ -121,18 +120,18 @@ describe('routes access', () => {
121
120
  },
122
121
  )
123
122
 
124
- test('requires a matching Zone scope and bypasses the edge cache', async () => {
123
+ test('requires a delegated Zone tag and bypasses the edge cache', async () => {
125
124
  const chainId = 421_700_001
126
- const reader = {
127
- id: 'key_zone_routes',
128
- orgId: 'org_test',
129
- scopes: ['data:read', `zone:${chainId}:read`],
130
- token: 'secret_zone_routes',
131
- } satisfies TestApp.kvStore.Key
125
+ const reader = TestApp.zoneReader(
126
+ { id: 'key_zone_routes', orgId: 'org_test', scopes: ['data:read'], token: 'secret_zone_routes' }, // prettier-ignore
127
+ [chainId],
128
+ )
129
+ const db = TestApp.database()
130
+ await TestApp.delegateZone(db, { chainIds: [chainId] })
132
131
  const app = App.create({
133
132
  auth: {},
134
133
  cache: { store: Store.memory() },
135
- db: TestApp.database(),
134
+ db,
136
135
  defaultChainId: chainId,
137
136
  kv: { store: TestApp.kvStore({ keys: [reader] }) },
138
137
  zones: [TestApp.zone({ chainId, rpcUrl: `https://${chainId}.rpc.test` })],
@@ -146,18 +145,18 @@ describe('routes access', () => {
146
145
  expect(anonymous.status).toBe(403)
147
146
  })
148
147
 
149
- test('a Zone read scope reads but never writes routes', async () => {
148
+ test('a Zone read grant reads but never writes routes', async () => {
150
149
  const chainId = 421_700_001
151
- const reader = {
152
- id: 'key_zone_reader',
153
- orgId: 'org_test',
154
- scopes: ['data:read', 'routes:write', `zone:${chainId}:read`],
155
- token: 'secret_zone_reader',
156
- } satisfies TestApp.kvStore.Key
150
+ const reader = TestApp.zoneReader(
151
+ { id: 'key_zone_reader', orgId: 'org_test', scopes: ['data:read', 'routes:write'], token: 'secret_zone_reader' }, // prettier-ignore
152
+ [chainId],
153
+ )
154
+ const db = TestApp.database()
155
+ await TestApp.delegateZone(db, { chainIds: [chainId] })
157
156
  const app = App.create({
158
157
  auth: {},
159
158
  cache: { store: Store.memory() },
160
- db: TestApp.database(),
159
+ db,
161
160
  defaultChainId: chainId,
162
161
  kv: { store: TestApp.kvStore({ keys: [reader] }) },
163
162
  zones: [TestApp.zone({ chainId, rpcUrl: `https://${chainId}.rpc.test` })],
@@ -171,7 +170,7 @@ describe('routes access', () => {
171
170
  expect(await write.json()).toMatchObject({
172
171
  error: {
173
172
  code: 'api_key_forbidden',
174
- message: `Broadcasting to zone ${chainId} requires \`zone:${chainId}:write\`.`,
173
+ message: `Broadcasting to zone ${chainId} requires \`zone:write\` with a tag for Zone ${chainId}, issued to an organization delegated that Zone.`,
175
174
  },
176
175
  })
177
176
  })
package/src/db/Db.ts CHANGED
@@ -73,8 +73,8 @@ import type * as WebhookDeliveries from './tables/webhookDeliveries.js'
73
73
  import type * as WebhookQueueCompletions from './tables/webhookQueueCompletions.js'
74
74
  import type * as WebhookQueueEvents from './tables/webhookQueueEvents.js'
75
75
  import type * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
76
+ import type * as ZoneDelegationRequests from './tables/zoneDelegationRequests.js'
76
77
  import type * as ZoneDelegations from './tables/zoneDelegations.js'
77
- import type * as ZoneKeyRequests from './tables/zoneKeyRequests.js'
78
78
 
79
79
  /**
80
80
  * Kysely schema with camelCase columns. {@link CamelCasePlugin} maps table
@@ -155,10 +155,10 @@ export type Database = {
155
155
  webhook_queue_completions: WebhookQueueCompletions.Table
156
156
  webhook_queue_events: WebhookQueueEvents.Table
157
157
  webhook_subscriptions: WebhookSubscriptions.Table
158
+ zone_delegation_approvals: ZoneDelegationRequests.ApprovalTable
158
159
  zone_delegation_members: ZoneDelegations.MemberTable
160
+ zone_delegation_requests: ZoneDelegationRequests.Table
159
161
  zone_delegations: ZoneDelegations.Table
160
- zone_key_approvals: ZoneKeyRequests.ApprovalTable
161
- zone_key_requests: ZoneKeyRequests.Table
162
162
  }
163
163
 
164
164
  /**
@@ -3928,6 +3928,37 @@ export const migrations: readonly Migration[] = [
3928
3928
  // Accounts and tokens a delegation covers; a removed member keeps its row so re-adding is an update.
3929
3929
  up: (db) => raw(db, sql`CREATE TABLE IF NOT EXISTS zone_delegation_members (delegation_id text NOT NULL REFERENCES zone_delegations(id) ON DELETE CASCADE, kind text NOT NULL CHECK (kind IN ('account', 'token')), address text NOT NULL, added_at text NOT NULL, removed_at text, PRIMARY KEY (delegation_id, kind, address))`), // prettier-ignore
3930
3930
  },
3931
+ {
3932
+ name: '0365_zone_delegation_requests',
3933
+ up: (db) =>
3934
+ db.schema
3935
+ .createTable('zone_delegation_requests')
3936
+ .ifNotExists()
3937
+ .addColumn('id', 'text', (c) => c.primaryKey())
3938
+ .addColumn('createdAt', 'text', (c) => c.notNull())
3939
+ .addColumn('delegationId', 'text')
3940
+ .addColumn('expiresAt', 'text', (c) => c.notNull())
3941
+ .addColumn('groupId', 'text', (c) => c.notNull())
3942
+ .addColumn('input', 'jsonb', (c) => c.notNull())
3943
+ .addColumn('requesterEmail', 'text', (c) => c.notNull())
3944
+ .addColumn('requesterId', 'text', (c) => c.notNull())
3945
+ .addColumn('status', 'text', (c) => c.notNull()),
3946
+ },
3947
+ {
3948
+ name: '0366_zone_delegation_approvals',
3949
+ up: (db) =>
3950
+ db.schema
3951
+ .createTable('zone_delegation_approvals')
3952
+ .ifNotExists()
3953
+ .addColumn('requestId', 'text', (c) =>
3954
+ c.notNull().references('zone_delegation_requests.id'),
3955
+ )
3956
+ .addColumn('approverId', 'text', (c) => c.notNull())
3957
+ .addColumn('approverEmail', 'text', (c) => c.notNull())
3958
+ .addColumn('approvedAt', 'text', (c) => c.notNull())
3959
+ .addColumn('expiresAt', 'text', (c) => c.notNull())
3960
+ .addPrimaryKeyConstraint('zone_delegation_approvals_pkey', ['requestId', 'approverId']),
3961
+ },
3931
3962
  ]
3932
3963
 
3933
3964
  /**
package/src/db/Schema.ts CHANGED
@@ -16,49 +16,49 @@ import type * as internal_Schema from '../internal/Schema.js'
16
16
  import type * as Sentinel from '../internal/Sentinel.js'
17
17
  import type * as Webhooks from '../internal/Webhooks.js'
18
18
  import type * as internal_ZoneDelegation from '../internal/ZoneDelegation.js'
19
+ import type * as ZoneDelegationRequests from './tables/zoneDelegationRequests.js'
19
20
  import type * as Scope from '../Scope.js'
20
- import type * as ApiKeys from '../ApiKeys.js'
21
21
 
22
- /** Immutable Zone key issuance request and its terminal outcome. */
23
- export const ZoneKeyRequest = z.object({
22
+ /** Columns of the `zone_delegations` table. */
23
+ export const ZoneDelegation = z.object({
24
+ accountsAll: z.boolean(),
25
+ chainId: z.number().check(z.int()),
26
+ createdAt: z.string(),
27
+ environment: z.enum(['production', 'sandbox']),
28
+ id: z.string(),
29
+ orgId: z.string(),
30
+ projects: z.custom<internal_ZoneDelegation.Selection>(),
31
+ revokedAt: z.nullable(z.string()),
32
+ tokensAll: z.boolean(),
33
+ updatedAt: z.string(),
34
+ })
35
+ export type ZoneDelegation = z.output<typeof ZoneDelegation>
36
+
37
+ /** Immutable Zone delegation request and its terminal outcome. */
38
+ export const ZoneDelegationRequest = z.object({
24
39
  createdAt: z.string(),
40
+ delegationId: z.nullable(z.string()),
25
41
  expiresAt: z.string(),
26
42
  groupId: z.string(),
27
43
  id: z.string(),
28
- input: z.custom<ApiKeys.MintInput & { orgId: string }>(),
29
- keyId: z.nullable(z.string()),
44
+ input: z.custom<ZoneDelegationRequests.Input>(),
30
45
  requesterEmail: z.string(),
31
46
  requesterId: z.string(),
32
- status: z.enum(['pending', 'issuing', 'issued', 'failed', 'cancelled']),
47
+ status: z.enum(['pending', 'applying', 'applied', 'failed', 'cancelled']),
33
48
  })
34
- /** Columns of the Zone key request table. */
35
- export type ZoneKeyRequest = z.output<typeof ZoneKeyRequest>
49
+ /** Columns of the `zone_delegation_requests` table. */
50
+ export type ZoneDelegationRequest = z.output<typeof ZoneDelegationRequest>
36
51
 
37
52
  /** One approver's immutable, timestamped decision. */
38
- export const ZoneKeyApproval = z.object({
53
+ export const ZoneDelegationApproval = z.object({
39
54
  approvedAt: z.string(),
40
55
  approverEmail: z.string(),
41
56
  approverId: z.string(),
42
57
  expiresAt: z.string(),
43
58
  requestId: z.string(),
44
59
  })
45
- /** Columns of the Zone key approval table. */
46
- export type ZoneKeyApproval = z.output<typeof ZoneKeyApproval>
47
-
48
- /** Columns of the `zone_delegations` table. */
49
- export const ZoneDelegation = z.object({
50
- accountsAll: z.boolean(),
51
- chainId: z.number().check(z.int()),
52
- createdAt: z.string(),
53
- environment: z.enum(['production', 'sandbox']),
54
- id: z.string(),
55
- orgId: z.string(),
56
- projects: z.custom<internal_ZoneDelegation.Selection>(),
57
- revokedAt: z.nullable(z.string()),
58
- tokensAll: z.boolean(),
59
- updatedAt: z.string(),
60
- })
61
- export type ZoneDelegation = z.output<typeof ZoneDelegation>
60
+ /** Columns of the `zone_delegation_approvals` table. */
61
+ export type ZoneDelegationApproval = z.output<typeof ZoneDelegationApproval>
62
62
 
63
63
  /** Columns of the `zone_delegation_members` table. */
64
64
  export const ZoneDelegationMember = z.object({
@@ -578,6 +578,45 @@ export declare namespace listDeliveredSince {
578
578
  }
579
579
  }
580
580
 
581
+ /**
582
+ * Lists runs that paid a treasury in one digest window, oldest first, so each payout reports exactly once.
583
+ *
584
+ * A run carrying `deliveredAt` counts when delivered in `[since, until)` shifted back by the settling
585
+ * margin. A run delivered before `deliveredAt` was recorded keeps the closing-boundary window its
586
+ * earlier digests used.
587
+ */
588
+ export async function listTreasuryPayoutsDelivered(
589
+ db: Db.Db,
590
+ options: listTreasuryPayoutsDelivered.Options,
591
+ ): Promise<Pick<Record, 'evidence' | 'vaultAddress'>[]> {
592
+ const deliveredAt = sql<number>`(evidence ->> 'deliveredAt')::bigint`
593
+ return (await db.kysely
594
+ .selectFrom('reward_runs')
595
+ .select(['evidence', 'vaultAddress'])
596
+ .where('chainId', '=', String(options.chainId))
597
+ .where('phase', '=', 'delivered')
598
+ .where(sql<boolean>`evidence ->> 'treasuryPayoutTransactionHash' is not null`)
599
+ .where(
600
+ sql<boolean>`((${deliveredAt} >= ${options.since - options.settlingSeconds} AND ${deliveredAt} < ${options.until - options.settlingSeconds}) OR (evidence ->> 'deliveredAt' IS NULL AND ends_at::bigint >= ${options.since} AND ends_at::bigint < ${options.until}))`,
601
+ )
602
+ .orderBy(sql`coalesce(${deliveredAt}, ends_at::bigint)`, 'asc')
603
+ .execute()) as Pick<Record, 'evidence' | 'vaultAddress'>[]
604
+ }
605
+
606
+ export declare namespace listTreasuryPayoutsDelivered {
607
+ /** Digest window selector. */
608
+ type Options = {
609
+ /** Chain containing the campaigns. */
610
+ chainId: number
611
+ /** Seconds the delivery window trails the digest window, covering deliveries still committing. */
612
+ settlingSeconds: number
613
+ /** Inclusive Unix start of the digest window. */
614
+ since: number
615
+ /** Exclusive Unix end of the digest window. */
616
+ until: number
617
+ }
618
+ }
619
+
581
620
  /** Reads each vault's latest delivered run closing at or before a boundary. */
582
621
  export async function listLatestDeliveredBefore(
583
622
  db: Db.Db,
@@ -0,0 +1,65 @@
1
+ import * as TestApp from '../../../test/App.js'
2
+ import * as RoutesAccessRequests from './routesAccessRequests.js'
3
+
4
+ describe('hasRecent', () => {
5
+ test('counts other requests from the same organization inside the window', async () => {
6
+ const db = TestApp.database()
7
+ const orgId = 'org_1a2b3c4d5e6f7g8h9j0k1m2n'
8
+ vi.useFakeTimers({ toFake: ['Date'] })
9
+ try {
10
+ vi.setSystemTime(new Date('2026-10-22T12:00:00Z'))
11
+ await request(db, { orgId, projectId: 'prj_1a2b3c4d5e6f7g8h9j0k1m2n' })
12
+ vi.setSystemTime(new Date('2026-10-22T12:05:00Z'))
13
+ const second = await request(db, { orgId, projectId: 'prj_2b3c4d5e6f7g8h9j0k1m2n3p' })
14
+ const otherOrgId = 'org_9z8y7x6w5v4u3t2s1r0q9p8n'
15
+ const other = await request(db, {
16
+ orgId: otherOrgId,
17
+ projectId: 'prj_3c4d5e6f7g8h9j0k1m2n3p4q',
18
+ })
19
+
20
+ expect({
21
+ afterWindow: await RoutesAccessRequests.hasRecent(db, {
22
+ excludeId: second.id,
23
+ orgId,
24
+ since: '2026-10-22T12:01:00.000Z',
25
+ }),
26
+ insideWindow: await RoutesAccessRequests.hasRecent(db, {
27
+ excludeId: second.id,
28
+ orgId,
29
+ since: '2026-10-22T11:55:00.000Z',
30
+ }),
31
+ otherOrganization: await RoutesAccessRequests.hasRecent(db, {
32
+ excludeId: other.id,
33
+ orgId: otherOrgId,
34
+ since: '2026-10-22T11:50:00.000Z',
35
+ }),
36
+ }).toMatchInlineSnapshot(`
37
+ {
38
+ "afterWindow": false,
39
+ "insideWindow": true,
40
+ "otherOrganization": false,
41
+ }
42
+ `)
43
+ } finally {
44
+ vi.useRealTimers()
45
+ }
46
+ })
47
+ })
48
+
49
+ async function request(db: ReturnType<typeof TestApp.database>, ids: request.Ids) {
50
+ const record = await RoutesAccessRequests.create(db, {
51
+ environment: 'production',
52
+ keyIds: [],
53
+ orgId: ids.orgId,
54
+ projectId: ids.projectId,
55
+ requestedBy: 'usr_1a2b3c4d5e6f7g8h9j0k1m2n',
56
+ routes: [],
57
+ subsidy: false,
58
+ })
59
+ if (!record) throw new Error('Request was not created')
60
+ return record
61
+ }
62
+
63
+ declare namespace request {
64
+ type Ids = { orgId: string; projectId: string }
65
+ }
@@ -91,6 +91,31 @@ export function list(db: Db.Db, orgId: string): Promise<Record[]> {
91
91
  .execute()
92
92
  }
93
93
 
94
+ /** Whether the organization created another request at or after `since`. */
95
+ export async function hasRecent(db: Db.Db, options: hasRecent.Options): Promise<boolean> {
96
+ const row = await db.kysely
97
+ .selectFrom('routes_access_requests')
98
+ .select('id')
99
+ .where('orgId', '=', options.orgId)
100
+ .where('createdAt', '>=', options.since)
101
+ .where('id', '!=', options.excludeId)
102
+ .limit(1)
103
+ .executeTakeFirst()
104
+ return row !== undefined
105
+ }
106
+
107
+ export declare namespace hasRecent {
108
+ /** Window and request to compare against. */
109
+ type Options = {
110
+ /** Request to leave out, usually the one just created. */
111
+ excludeId: string
112
+ /** Organization whose requests count. */
113
+ orgId: string
114
+ /** ISO timestamp opening the window. */
115
+ since: string
116
+ }
117
+ }
118
+
94
119
  /** Joins the organization, project, and requester names that still exist. */
95
120
  function detailed(db: Db.Db) {
96
121
  return db.kysely