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
@@ -3,7 +3,7 @@ import { createFileRoute, Link, useBlocker } from '@tanstack/react-router'
3
3
  import { NativeSelect } from '@tempoxyz/ds/platform'
4
4
  import { type ReactNode, useEffect, useId, useRef, useState } from 'react'
5
5
  import { Button, cx, Fields, Input, Rows, Tag, useCopy } from 'regen-ui'
6
- import { Check, KeyRound, Link as LinkIcon, Plus, X } from 'lucide-react'
6
+ import { Check, Link as LinkIcon, Plus, ShieldCheck, X } from 'lucide-react'
7
7
  import * as z from 'zod/mini'
8
8
 
9
9
  import * as ApiKeyForm from '../components/ApiKeyForm.js'
@@ -11,11 +11,10 @@ import * as Dialog from '../components/Dialog.js'
11
11
  import * as Frame from '../components/Page.js'
12
12
  import * as Config from '../lib/config.js'
13
13
  import * as Format from '../lib/format.js'
14
- import * as Scopes from '../lib/scopes.js'
15
- import * as ZoneKeyRequests from '../lib/zone-key-requests.js'
14
+ import * as DelegationRequests from '../lib/zone-delegation-requests.js'
16
15
 
17
- export const Route = createFileRoute('/zone-key-requests')({
18
- head: () => ({ meta: [{ title: 'Zone key requests | Tempo API Admin' }] }),
16
+ export const Route = createFileRoute('/zone-delegation-requests')({
17
+ head: () => ({ meta: [{ title: 'Delegation requests | Tempo API Admin' }] }),
19
18
  // `cursor` selects a page; `request` opens one request, even when it is on another page.
20
19
  validateSearch: z.object({
21
20
  cursor: z.catch(z.optional(z.string()), undefined),
@@ -25,10 +24,9 @@ export const Route = createFileRoute('/zone-key-requests')({
25
24
  loader: ({ context, deps }) =>
26
25
  // Preserve inline permission errors while allowing cached queries to refresh after navigation.
27
26
  Promise.allSettled([
28
- context.queryClient.ensureQueryData(ZoneKeyRequests.list.options(deps.cursor)),
29
- context.queryClient.ensureQueryData(Scopes.get.options()),
27
+ context.queryClient.ensureQueryData(DelegationRequests.list.options(deps.cursor)),
30
28
  ...(deps.request
31
- ? [context.queryClient.ensureQueryData(ZoneKeyRequests.get.options(deps.request))]
29
+ ? [context.queryClient.ensureQueryData(DelegationRequests.get.options(deps.request))]
32
30
  : []),
33
31
  ]),
34
32
  component: RouteComponent,
@@ -41,20 +39,20 @@ function RouteComponent() {
41
39
  const dirty = useRef(false)
42
40
  const config = Config.use()
43
41
  const requests = useQuery({
44
- ...ZoneKeyRequests.list.options(cursor),
42
+ ...DelegationRequests.list.options(cursor),
45
43
  placeholderData: keepPreviousData,
46
44
  })
47
45
  const rows = requests.data?.data ?? []
48
46
  const listed = rows.some((request) => request.id === selected)
49
- const create = ZoneKeyRequests.create.useMutation()
50
- const issue = ZoneKeyRequests.issue.useMutation()
47
+ const create = DelegationRequests.create.useMutation()
48
+ const apply = DelegationRequests.apply.useMutation()
51
49
  const email = config.data?.auth.identity?.email.toLowerCase()
52
50
  // A pending submission may still create the request, so navigation waits for it.
53
51
  useBlocker({
54
52
  enableBeforeUnload: () => dirty.current || create.isPending,
55
53
  shouldBlockFn: () =>
56
54
  create.isPending ||
57
- (dirty.current && !window.confirm('Discard this unsubmitted key request?')),
55
+ (dirty.current && !window.confirm('Discard this unsubmitted delegation request?')),
58
56
  })
59
57
 
60
58
  function onSubmit(form: FormData) {
@@ -62,36 +60,41 @@ function RouteComponent() {
62
60
  const value = form.get(key)
63
61
  return typeof value === 'string' ? value.trim() : ''
64
62
  }
65
- const scopes = ApiKeyForm.readScopes(form)
66
- if (!scopes) return
67
- if (!ZoneKeyRequests.required(scopes)) {
68
- setFormError('Add at least one Zone read scope. Other keys can be provisioned from API Keys.')
69
- return
70
- }
71
- setFormError(undefined)
72
- const allowedIps = [
63
+ const addresses = (key: string) => [
73
64
  ...new Set(
74
- field('allowedIps')
75
- .split(/[,\n]/)
65
+ field(key)
66
+ .split(/[\s,]+/)
76
67
  .map((value) => value.trim())
77
68
  .filter(Boolean),
78
69
  ),
79
70
  ]
80
- const expiresAt = field('expiresAt')
81
- const projectId = field('projectId')
82
- const rateLimit = field('rateLimit')
71
+ const accountsAll = form.get('accountsAll') === 'on'
72
+ const tokensAll = form.get('tokensAll') === 'on'
73
+ const accounts = addresses('accounts')
74
+ const tokens = addresses('tokens')
75
+ const chainId = Number(field('chainId'))
76
+ if (!Number.isInteger(chainId) || chainId <= 0) {
77
+ setFormError('Enter the Zone chain id as a positive integer.')
78
+ return
79
+ }
80
+ if (!accountsAll && accounts.length === 0) {
81
+ setFormError('List the covered accounts, or cover every account.')
82
+ return
83
+ }
84
+ if (!tokensAll && tokens.length === 0) {
85
+ setFormError('List the covered tokens, or cover every token.')
86
+ return
87
+ }
88
+ setFormError(undefined)
83
89
  create.mutate(
84
90
  {
85
- allowedIps,
91
+ ...(accountsAll ? {} : { accounts: accounts as DelegationRequests.create.Input['accounts'] }), // prettier-ignore
92
+ accountsAll,
93
+ chainId,
86
94
  environment: field('environment') === 'sandbox' ? 'sandbox' : 'production',
87
- ...(expiresAt ? { expiresAt: new Date(expiresAt).toISOString() } : {}),
88
- name: field('name'),
89
95
  orgId: field('orgId'),
90
- ...(projectId ? { projectId } : {}),
91
- ...(rateLimit
92
- ? { rateLimits: { '*': { limit: Number(rateLimit), period: 'minute' as const } } }
93
- : {}),
94
- scopes: scopes as ZoneKeyRequests.create.Input['scopes'],
96
+ ...(tokensAll ? {} : { tokens: tokens as DelegationRequests.create.Input['tokens'] }),
97
+ tokensAll,
95
98
  },
96
99
  {
97
100
  onError: (error) => setFormError(error.message),
@@ -108,7 +111,12 @@ function RouteComponent() {
108
111
  onOpenChange={(value) => {
109
112
  // A pending submission still creates the request, so it cannot be discarded.
110
113
  if (!value && create.isPending) return
111
- if (!value && dirty.current && !window.confirm('Discard this unsubmitted key request?'))
114
+ if (
115
+ !value &&
116
+ dirty.current &&
117
+ !window.confirm('Discard this unsubmitted delegation request?')
118
+ )
119
+ // prettier-ignore
112
120
  return
113
121
  if (!value) {
114
122
  dirty.current = false
@@ -119,28 +127,21 @@ function RouteComponent() {
119
127
  open={open}
120
128
  >
121
129
  <Frame.Page
122
- title="Zone key requests"
123
- description={`Zone read keys need ${ZoneKeyRequests.quorum} approvals from other members of the Zone issuers group before the requester can issue them.`}
130
+ title="Delegation requests"
131
+ description={`Zone delegations need ${DelegationRequests.quorum} approvals from other members of the Zone issuers group before the requester can apply them.`}
124
132
  action={
125
133
  <Dialog.Trigger
126
134
  render={
127
135
  <Button variant="primary">
128
136
  <Plus className="size-4" />
129
- Request a key
137
+ Request a delegation
130
138
  </Button>
131
139
  }
132
140
  />
133
141
  }
134
142
  >
135
- {issue.data ? (
136
- <ApiKeyForm.TokenBanner
137
- onDismiss={() => issue.reset()}
138
- title={`Key issued: ${issue.data.name ?? issue.data.id}`}
139
- token={issue.data.token}
140
- />
141
- ) : null}
142
143
  {selected && requests.data && !listed ? (
143
- <LinkedRequest email={email} id={selected} issue={issue} />
144
+ <LinkedRequest apply={apply} email={email} id={selected} />
144
145
  ) : null}
145
146
  {/* A failed background refresh keeps the loaded rows and offers a retry. */}
146
147
  {requests.isRefetchError ? (
@@ -171,14 +172,14 @@ function RouteComponent() {
171
172
  </span>
172
173
  </Frame.Notice>
173
174
  ) : rows.length === 0 ? (
174
- <Frame.Notice>No Zone key requests yet.</Frame.Notice>
175
+ <Frame.Notice>No delegation requests yet.</Frame.Notice>
175
176
  ) : (
176
177
  <Rows className="[&_[data-rows-divider]]:bg-divider/25!" variant="surface">
177
178
  {rows.map((request) => (
178
179
  <RequestRow
180
+ apply={apply}
179
181
  email={email}
180
182
  expanded={request.id === selected}
181
- issue={issue}
182
183
  key={request.id}
183
184
  request={request}
184
185
  />
@@ -189,12 +190,17 @@ function RouteComponent() {
189
190
  {cursor || requests.data?.nextCursor ? (
190
191
  <div className="flex justify-center gap-2">
191
192
  {cursor ? (
192
- <Button render={<Link search={{}} to="/zone-key-requests" />}>Newest requests</Button>
193
+ <Button render={<Link search={{}} to="/zone-delegation-requests" />}>
194
+ Newest requests
195
+ </Button>
193
196
  ) : null}
194
197
  {requests.data?.nextCursor ? (
195
198
  <Button
196
199
  render={
197
- <Link search={{ cursor: requests.data.nextCursor }} to="/zone-key-requests" />
200
+ <Link
201
+ search={{ cursor: requests.data.nextCursor }}
202
+ to="/zone-delegation-requests"
203
+ />
198
204
  }
199
205
  >
200
206
  Older requests
@@ -218,11 +224,14 @@ function RouteComponent() {
218
224
  }
219
225
 
220
226
  function RequestForm(options: RequestForm.Props) {
227
+ const [accountsAll, setAccountsAll] = useState(true)
228
+ const [tokensAll, setTokensAll] = useState(true)
221
229
  return (
222
230
  <>
223
- <Dialog.Title>Request a Zone key</Dialog.Title>
231
+ <Dialog.Title>Request a Zone delegation</Dialog.Title>
224
232
  <Dialog.Description>
225
- Settings are locked once submitted. Cancel and resubmit to change anything.
233
+ Settings are locked once submitted. Cancel and resubmit to change anything. To widen an
234
+ active delegation, revoke it and request a new one.
226
235
  </Dialog.Description>
227
236
  <form
228
237
  className="mt-6 flex min-h-0 flex-1 flex-col gap-8"
@@ -237,15 +246,6 @@ function RequestForm(options: RequestForm.Props) {
237
246
  variant="default"
238
247
  >
239
248
  <ApiKeyForm.OrganizationField required />
240
- <Input
241
- autoComplete="off"
242
- label="Project ID (optional)"
243
- name="projectId"
244
- pattern="prj_[A-Za-z0-9_\-]+"
245
- placeholder="prj_…"
246
- spellCheck={false}
247
- />
248
- <Input label="Name" name="name" placeholder="e.g. Partner Zone reader" required />
249
249
  <label className="flex flex-col gap-2">
250
250
  <span className="label-13 text-foreground-secondary">Environment</span>
251
251
  <NativeSelect
@@ -259,34 +259,46 @@ function RequestForm(options: RequestForm.Props) {
259
259
  </NativeSelect>
260
260
  </label>
261
261
  <Input
262
- label="Expires at (optional)"
263
- min={Format.localDateTimeCeil(new Date(Date.now() + 2 * 60_000))}
264
- name="expiresAt"
265
- type="datetime-local"
266
- />
267
- <Input
268
- defaultValue="10000"
269
- label="Rate limit"
270
- min={0}
271
- name="rateLimit"
272
- placeholder="Requests per minute"
273
- suffix="req/min"
262
+ inputMode="numeric"
263
+ label="Zone chain id"
264
+ min={1}
265
+ name="chainId"
266
+ placeholder="421700001"
267
+ required
274
268
  type="number"
275
269
  />
276
- <label className="flex min-w-0 flex-col gap-2">
277
- <span className="text-label-13 text-foreground-secondary">IP allowlist (optional)</span>
278
- <textarea
279
- className="min-h-24 w-full resize-y rounded-control border-2 border-transparent bg-secondary px-3 py-2.5 font-mono text-copy-13 text-foreground outline-none placeholder:font-sans placeholder:text-foreground-secondary/50 hover:bg-secondary-hover focus-visible:border-focus focus-visible:bg-secondary-hover"
280
- name="allowedIps"
281
- placeholder={'203.0.113.10\n198.51.100.0/24'}
282
- rows={4}
270
+ <Coverage
271
+ checked={accountsAll}
272
+ hint="Leave checked to cover every account; otherwise list the covered wallet addresses."
273
+ label="Cover every account"
274
+ name="accountsAll"
275
+ onChange={setAccountsAll}
276
+ />
277
+ {accountsAll ? null : (
278
+ <AddressList
279
+ hint="Separate account addresses with commas or new lines."
280
+ label="Covered accounts"
281
+ name="accounts"
282
+ placeholder={'0x…\n0x…'}
283
+ required
283
284
  />
284
- <span className="text-label-12 text-foreground-secondary">
285
- Separate exact IP addresses or CIDR ranges with commas or new lines. Leave empty for
286
- unrestricted access.
287
- </span>
288
- </label>
289
- <ApiKeyForm.ScopeFields defaultScopes={[]} />
285
+ )}
286
+ <Coverage
287
+ checked={tokensAll}
288
+ hint="Leave checked to cover every token; otherwise list the covered token contracts."
289
+ label="Cover every token"
290
+ name="tokensAll"
291
+ onChange={setTokensAll}
292
+ />
293
+ {tokensAll ? null : (
294
+ <AddressList
295
+ hint="Separate token contract addresses with commas or new lines."
296
+ label="Covered tokens"
297
+ name="tokens"
298
+ placeholder={'0x…\n0x…'}
299
+ required
300
+ />
301
+ )}
290
302
  </Fields>
291
303
  {options.error ? (
292
304
  <p
@@ -320,11 +332,66 @@ declare namespace RequestForm {
320
332
  }
321
333
  }
322
334
 
335
+ function Coverage(options: Coverage.Props) {
336
+ return (
337
+ <label className="flex flex-col gap-2">
338
+ <span className="flex items-center gap-2">
339
+ <input
340
+ checked={options.checked}
341
+ className="size-4 accent-[var(--background-color-invert)]"
342
+ name={options.name}
343
+ onChange={(event) => options.onChange(event.currentTarget.checked)}
344
+ type="checkbox"
345
+ />
346
+ <span className="text-label-13 text-foreground">{options.label}</span>
347
+ </span>
348
+ <span className="text-label-12 text-foreground-secondary">{options.hint}</span>
349
+ </label>
350
+ )
351
+ }
352
+
353
+ declare namespace Coverage {
354
+ type Props = {
355
+ checked: boolean
356
+ hint: string
357
+ label: string
358
+ name: string
359
+ onChange: (checked: boolean) => void
360
+ }
361
+ }
362
+
363
+ function AddressList(options: AddressList.Props) {
364
+ return (
365
+ <label className="flex min-w-0 flex-col gap-2">
366
+ <span className="text-label-13 text-foreground-secondary">{options.label}</span>
367
+ <textarea
368
+ className="min-h-24 w-full resize-y rounded-control border-2 border-transparent bg-secondary px-3 py-2.5 font-mono text-copy-13 text-foreground outline-none placeholder:font-sans placeholder:text-foreground-secondary/50 hover:bg-secondary-hover focus-visible:border-focus focus-visible:bg-secondary-hover"
369
+ name={options.name}
370
+ placeholder={options.placeholder}
371
+ required={options.required}
372
+ rows={4}
373
+ spellCheck={false}
374
+ />
375
+ <span className="text-label-12 text-foreground-secondary">{options.hint}</span>
376
+ </label>
377
+ )
378
+ }
379
+
380
+ declare namespace AddressList {
381
+ type Props = {
382
+ hint: string
383
+ label: string
384
+ name: string
385
+ placeholder: string
386
+ required?: boolean | undefined
387
+ }
388
+ }
389
+
323
390
  function RequestRow(options: RequestRow.Props) {
324
391
  const { expanded, request } = options
325
392
  const navigate = Route.useNavigate()
326
393
  const panelId = useId()
327
- const status = ZoneKeyRequests.status(request)
394
+ const status = DelegationRequests.status(request)
328
395
 
329
396
  return (
330
397
  <>
@@ -344,7 +411,9 @@ function RequestRow(options: RequestRow.Props) {
344
411
  >
345
412
  <span className="flex min-w-0 flex-1 flex-col gap-0.5">
346
413
  <span className="flex min-w-0 items-center gap-2">
347
- <span className="truncate text-label-14 text-foreground">{request.input.name}</span>
414
+ <span className="truncate text-label-14 text-foreground">
415
+ Zone {request.input.chainId}
416
+ </span>
348
417
  {request.input.environment === 'sandbox' ? <Tag intent="warning">sandbox</Tag> : null}
349
418
  </span>
350
419
  <span className="truncate text-label-12 text-foreground-secondary">
@@ -357,7 +426,7 @@ function RequestRow(options: RequestRow.Props) {
357
426
  </span>
358
427
  </Rows.Row>
359
428
  {expanded ? (
360
- <RequestPanel email={options.email} id={panelId} issue={options.issue} request={request} />
429
+ <RequestPanel apply={options.apply} email={options.email} id={panelId} request={request} />
361
430
  ) : null}
362
431
  </>
363
432
  )
@@ -365,18 +434,18 @@ function RequestRow(options: RequestRow.Props) {
365
434
 
366
435
  declare namespace RequestRow {
367
436
  type Props = {
437
+ apply: ReturnType<typeof DelegationRequests.apply.useMutation>
368
438
  /** Signed-in admin email, lowercased. */
369
439
  email: string | undefined
370
440
  /** Whether the URL selects this request. */
371
441
  expanded: boolean
372
- issue: ReturnType<typeof ZoneKeyRequests.issue.useMutation>
373
- request: ZoneKeyRequests.Request
442
+ request: DelegationRequests.Request
374
443
  }
375
444
  }
376
445
 
377
- /** A linked request missing from the newest-100 list. */
446
+ /** A linked request missing from the newest page. */
378
447
  function LinkedRequest(options: LinkedRequest.Props) {
379
- const detail = useQuery(ZoneKeyRequests.get.options(options.id))
448
+ const detail = useQuery(DelegationRequests.get.options(options.id))
380
449
  return (
381
450
  <Frame.Card>
382
451
  {detail.isPending ? (
@@ -385,7 +454,7 @@ function LinkedRequest(options: LinkedRequest.Props) {
385
454
  <Frame.Notice>{detail.error.message}</Frame.Notice>
386
455
  ) : (
387
456
  <Rows className="[&_[data-rows-divider]]:bg-divider/25!" variant="surface">
388
- <RequestRow email={options.email} expanded issue={options.issue} request={detail.data} />
457
+ <RequestRow apply={options.apply} email={options.email} expanded request={detail.data} />
389
458
  </Rows>
390
459
  )}
391
460
  </Frame.Card>
@@ -394,28 +463,29 @@ function LinkedRequest(options: LinkedRequest.Props) {
394
463
 
395
464
  declare namespace LinkedRequest {
396
465
  type Props = {
466
+ apply: ReturnType<typeof DelegationRequests.apply.useMutation>
397
467
  email: string | undefined
398
468
  /** Request id from the URL. */
399
469
  id: string
400
- issue: ReturnType<typeof ZoneKeyRequests.issue.useMutation>
401
470
  }
402
471
  }
403
472
 
404
473
  function RequestPanel(options: RequestPanel.Props) {
405
- const { email, issue } = options
474
+ const { apply, email } = options
406
475
  const queryClient = useQueryClient()
407
476
  const { copy, notifying } = useCopy()
408
477
  // Approvals arrive from other reviewers and can lapse while the panel is open.
409
478
  const detail = useQuery({
410
- ...ZoneKeyRequests.get.options(options.request.id),
479
+ ...DelegationRequests.get.options(options.request.id),
411
480
  refetchInterval: 15_000,
412
481
  })
413
- // The polled detail sees cancellation or issuance by others before the list does.
482
+ // The polled detail sees cancellation or application by others before the list does.
414
483
  const request = detail.data ?? options.request
415
- const approve = ZoneKeyRequests.approve.useMutation()
416
- const cancel = ZoneKeyRequests.cancel.useMutation()
417
- const pending = ZoneKeyRequests.status(request) === 'pending'
484
+ const approve = DelegationRequests.approve.useMutation()
485
+ const cancel = DelegationRequests.cancel.useMutation()
486
+ const pending = DelegationRequests.status(request) === 'pending'
418
487
  const [, setTick] = useState(0)
488
+ const approvals = detail.data ? DelegationRequests.validApprovals(detail.data) : []
419
489
 
420
490
  // Refetches return identical data, so schedule a render when the next approval or request lapses.
421
491
  useEffect(() => {
@@ -431,69 +501,40 @@ function RequestPanel(options: RequestPanel.Props) {
431
501
 
432
502
  useEffect(() => {
433
503
  if (detail.data && detail.data.status !== options.request.status)
434
- void queryClient.invalidateQueries({ queryKey: ZoneKeyRequests.list.key })
504
+ void queryClient.invalidateQueries({ queryKey: DelegationRequests.list.key })
435
505
  }, [detail.data, options.request.status, queryClient])
436
- const approvals = detail.data ? ZoneKeyRequests.validApprovals(detail.data) : []
437
- // Emails only hide self-approval; the API checks stable user ids, so Issue stays available.
506
+ // Emails only steer the buttons; the API checks stable user ids on every decision.
438
507
  const requester = request.requesterEmail.toLowerCase() === email
439
508
  const approved = approvals.some((approval) => approval.approverEmail.toLowerCase() === email)
440
- // Everyone can request and issue; only approver group members can approve.
509
+ // Everyone can request and apply; only approver group members can approve.
441
510
  // `null` means membership could not be checked; offer Approve and let the server decide.
442
- const approver = Config.use().data?.auth.zoneKeyApprover !== false
443
- const rateLimit = request.input.rateLimits?.['*']
511
+ const approver = Config.use().data?.auth.delegationApprover !== false
444
512
  const error =
445
- (issue.variables === request.id ? issue.error : null) ?? approve.error ?? cancel.error
513
+ (apply.variables === request.id ? apply.error : null) ?? approve.error ?? cancel.error
514
+ const { input } = request
446
515
 
447
516
  return (
448
517
  <Rows.Panel className="border-border/25! bg-surface!" id={options.id}>
449
518
  <dl className="flex flex-wrap gap-x-10 gap-y-4 px-5 py-4">
450
519
  <Detail label="Request ID">{request.id}</Detail>
451
- <Detail label="Organization">{request.input.orgId}</Detail>
452
- <Detail label="Project">{request.input.projectId ?? '-'}</Detail>
453
- <Detail label="Environment">{request.input.environment ?? 'production'}</Detail>
454
- <Detail label="Rate limit">
455
- {rateLimit === undefined
456
- ? 'Inherited'
457
- : `${rateLimit.limit} req/${rateLimit.period === 'minute' ? 'min' : 'sec'}`}
458
- </Detail>
459
- <Detail label="Key expires">
460
- {request.input.expiresAt ? Format.dateTime(request.input.expiresAt) : 'Never'}
461
- </Detail>
520
+ <Detail label="Organization">{input.orgId}</Detail>
521
+ <Detail label="Environment">{input.environment}</Detail>
522
+ <Detail label="Zone">{input.chainId}</Detail>
462
523
  <Detail label={pending ? 'Request expires' : 'Request expiry'}>
463
524
  {Format.dateTime(request.expiresAt)}
464
525
  </Detail>
465
- {request.keyId ? <Detail label="Key ID">{request.keyId}</Detail> : null}
466
- <Detail className="w-full" label="IP allowlist">
467
- {request.input.allowedIps?.length ? (
468
- <span className="flex flex-wrap gap-x-3 gap-y-1 font-mono">
469
- {request.input.allowedIps.map((address) => (
470
- <span className="break-all" key={address}>
471
- {address}
472
- </span>
473
- ))}
474
- </span>
475
- ) : (
476
- 'Unrestricted'
477
- )}
526
+ {request.delegationId ? (
527
+ <Detail label="Delegation ID">{request.delegationId}</Detail>
528
+ ) : null}
529
+ <Detail className="w-full" label="Accounts">
530
+ {input.accountsAll ? 'Every account' : <Addresses values={input.accounts ?? []} />}
478
531
  </Detail>
479
- <Detail className="w-full" label="Scopes">
480
- <span className="flex flex-wrap gap-x-3 gap-y-1">
481
- {request.input.scopes.map((scope) => (
482
- <span
483
- className={cx(
484
- 'text-label-13',
485
- ZoneKeyRequests.required([scope]) ? 'text-warning' : 'text-foreground',
486
- )}
487
- key={scope}
488
- >
489
- {scope}
490
- </span>
491
- ))}
492
- </span>
532
+ <Detail className="w-full" label="Tokens">
533
+ {input.tokensAll ? 'Every token' : <Addresses values={input.tokens ?? []} />}
493
534
  </Detail>
494
535
  <Detail
495
536
  className="w-full"
496
- label={`Approvals (${approvals.length} of ${ZoneKeyRequests.quorum} valid)`}
537
+ label={`Approvals (${approvals.length} of ${DelegationRequests.quorum} valid)`}
497
538
  >
498
539
  {detail.isPending ? (
499
540
  <span className="text-foreground-secondary">Loading approvals…</span>
@@ -525,14 +566,10 @@ function RequestPanel(options: RequestPanel.Props) {
525
566
  )}
526
567
  </Detail>
527
568
  </dl>
528
- {issue.data && issue.variables !== request.id && pending ? (
529
- <p className="border-t border-border/25 px-5 py-3 text-copy-13 text-foreground-secondary">
530
- Dismiss the issued token at the top of the page before issuing another key.
531
- </p>
532
- ) : null}
533
- {issue.data && issue.variables === request.id ? (
569
+ {apply.data && apply.variables === request.id ? (
534
570
  <p className="border-t border-border/25 px-5 py-3 text-copy-13 text-positive">
535
- Key issued. Copy the token from the top of the page now; it won't be shown again.
571
+ Delegation applied. Keys tagged for this Zone under the organization read it within 30
572
+ seconds.
536
573
  </p>
537
574
  ) : null}
538
575
  {error ? (
@@ -543,7 +580,7 @@ function RequestPanel(options: RequestPanel.Props) {
543
580
  <div className="flex flex-wrap justify-end gap-2 border-t border-border/25 px-5 py-3">
544
581
  <Button
545
582
  onClick={() =>
546
- copy(new URL(`zone-key-requests?request=${request.id}`, document.baseURI).href)
583
+ copy(new URL(`zone-delegation-requests?request=${request.id}`, document.baseURI).href)
547
584
  }
548
585
  size="small"
549
586
  >
@@ -555,7 +592,7 @@ function RequestPanel(options: RequestPanel.Props) {
555
592
  <Button
556
593
  loading={cancel.isPending}
557
594
  onClick={() => {
558
- if (window.confirm(`Cancel the request for ${request.input.name}?`))
595
+ if (window.confirm(`Cancel the delegation request for Zone ${input.chainId}?`))
559
596
  cancel.mutate(request.id)
560
597
  }}
561
598
  size="small"
@@ -573,18 +610,18 @@ function RequestPanel(options: RequestPanel.Props) {
573
610
  {approved ? 'Renew approval' : 'Approve'}
574
611
  </Button>
575
612
  )}
576
- <Button
577
- disabled={
578
- approvals.length < ZoneKeyRequests.quorum || issue.isPending || !!issue.data
579
- }
580
- loading={issue.isPending && issue.variables === request.id}
581
- onClick={() => issue.mutate(request.id)}
582
- size="small"
583
- variant="primary"
584
- >
585
- <KeyRound className="size-4" />
586
- Issue key
587
- </Button>
613
+ {requester ? (
614
+ <Button
615
+ disabled={approvals.length < DelegationRequests.quorum || apply.isPending}
616
+ loading={apply.isPending && apply.variables === request.id}
617
+ onClick={() => apply.mutate(request.id)}
618
+ size="small"
619
+ variant="primary"
620
+ >
621
+ <ShieldCheck className="size-4" />
622
+ Apply delegation
623
+ </Button>
624
+ ) : null}
588
625
  </>
589
626
  ) : null}
590
627
  </div>
@@ -594,21 +631,40 @@ function RequestPanel(options: RequestPanel.Props) {
594
631
 
595
632
  declare namespace RequestPanel {
596
633
  type Props = {
634
+ apply: ReturnType<typeof DelegationRequests.apply.useMutation>
597
635
  email: string | undefined
598
636
  id: string
599
- issue: ReturnType<typeof ZoneKeyRequests.issue.useMutation>
600
- request: ZoneKeyRequests.Request
637
+ request: DelegationRequests.Request
638
+ }
639
+ }
640
+
641
+ function Addresses(options: Addresses.Props) {
642
+ if (options.values.length === 0) return <span className="text-foreground-secondary">None</span>
643
+ return (
644
+ <span className="flex flex-wrap gap-x-3 gap-y-1 font-mono">
645
+ {options.values.map((address) => (
646
+ <span className="break-all" key={address}>
647
+ {address}
648
+ </span>
649
+ ))}
650
+ </span>
651
+ )
652
+ }
653
+
654
+ declare namespace Addresses {
655
+ type Props = {
656
+ values: readonly string[]
601
657
  }
602
658
  }
603
659
 
604
660
  function StatusTag(options: StatusTag.Props) {
605
661
  const intent = (
606
662
  {
663
+ applied: 'positive',
664
+ applying: 'info',
607
665
  cancelled: 'neutral',
608
666
  expired: 'neutral',
609
667
  failed: 'negative',
610
- issued: 'positive',
611
- issuing: 'info',
612
668
  pending: 'warning',
613
669
  } as const
614
670
  )[options.status]
@@ -621,7 +677,7 @@ function StatusTag(options: StatusTag.Props) {
621
677
 
622
678
  declare namespace StatusTag {
623
679
  type Props = {
624
- status: ReturnType<typeof ZoneKeyRequests.status>
680
+ status: ReturnType<typeof DelegationRequests.status>
625
681
  }
626
682
  }
627
683