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.
- package/README.md +13 -5
- package/dist/ApiKey.d.ts +2 -2
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +2 -2
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +85 -11
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +218 -56
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12543 -13912
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +4 -5
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +12 -20
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +20 -36
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +871 -828
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +14 -26
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +93 -186
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +3 -5
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/audit-logs.d.ts +18 -18
- package/dist/admin/apps/audit-logs.js +1 -1
- package/dist/admin/apps/audit-logs.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +27 -27
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +11 -5
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +17 -17
- package/dist/admin/apps/prop-amms.d.ts +4 -4
- package/dist/admin/apps/routes-support.js +1 -38
- package/dist/admin/apps/routes-support.js.map +1 -1
- package/dist/admin/apps/routes.d.ts +153 -153
- package/dist/admin/apps/sentinel.d.ts +4 -4
- package/dist/admin/apps/verified-tokens.d.ts +24 -24
- package/dist/admin/apps/zone-delegation-requests.d.ts +332 -0
- package/dist/admin/apps/zone-delegation-requests.d.ts.map +1 -0
- package/dist/admin/apps/zone-delegation-requests.js +200 -0
- package/dist/admin/apps/zone-delegation-requests.js.map +1 -0
- package/dist/admin/apps/zone-delegations.d.ts +512 -52
- package/dist/admin/apps/zone-delegations.d.ts.map +1 -1
- package/dist/admin/apps/zone-delegations.js +134 -44
- package/dist/admin/apps/zone-delegations.js.map +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +341 -397
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +4 -2
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +11932 -13214
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +32 -13
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +1 -1
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
- package/dist/apps/data/ZoneSelection.js +2 -2
- package/dist/apps/data/ZoneSelection.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +60 -27
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +91 -16
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +893 -875
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +36 -36
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +3 -1
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +40 -40
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +3 -7
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +236 -236
- package/dist/apps/data/routes/earn-transactions.d.ts +14 -14
- package/dist/apps/data/routes/earn.d.ts +261 -1445
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +64 -490
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +144 -144
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +5 -15
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +3 -9
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +13 -13
- package/dist/apps/data/routes/receipts.d.ts +53 -53
- package/dist/apps/data/routes/receipts.js +1 -1
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +52 -0
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +19 -18
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +14 -14
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +1 -3
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +7 -5
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +281 -281
- package/dist/apps/data/routes/transactions.js +3 -3
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +12 -12
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +1 -3
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +30 -30
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +1 -3
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
- package/dist/apps/data/routes/webhooks.d.ts +102 -102
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +9 -23
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zone-deposits.d.ts +16 -16
- package/dist/apps/data/routes/zone-withdrawals.d.ts +31 -31
- package/dist/apps/data/routes/zones.d.ts +28 -28
- package/dist/apps/management/App.d.ts +18 -102
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +1 -1
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +253 -339
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +25 -11
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +92 -92
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +5 -13
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/cli.d.ts.map +1 -1
- package/dist/apps/management/routes/cli.js +3 -9
- package/dist/apps/management/routes/cli.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +16 -16
- package/dist/apps/management/routes/fee-payer-usage.d.ts +38 -38
- package/dist/apps/management/routes/fee-payer-usage.d.ts.map +1 -1
- package/dist/apps/management/routes/fee-payer-usage.js +2 -4
- package/dist/apps/management/routes/fee-payer-usage.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +52 -52
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +4 -12
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +6 -14
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +3 -7
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +84 -84
- package/dist/apps/management/routes/members.d.ts.map +1 -1
- package/dist/apps/management/routes/members.js +2 -4
- package/dist/apps/management/routes/members.js.map +1 -1
- package/dist/apps/management/routes/orgs.d.ts +44 -44
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +2 -6
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +2 -6
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/route-usage.d.ts +34 -34
- package/dist/apps/management/routes/route-usage.d.ts.map +1 -1
- package/dist/apps/management/routes/route-usage.js +2 -4
- package/dist/apps/management/routes/route-usage.js.map +1 -1
- package/dist/apps/management/routes/routes-access-requests.d.ts +120 -91
- package/dist/apps/management/routes/routes-access-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/routes-access-requests.js +49 -9
- package/dist/apps/management/routes/routes-access-requests.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +8 -16
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +39 -39
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +3 -7
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +2089 -2089
- package/dist/apps/management/routes/zone-delegations.d.ts +14 -17
- package/dist/apps/management/routes/zone-delegations.d.ts.map +1 -1
- package/dist/apps/management/routes/zone-delegations.js +1 -6
- package/dist/apps/management/routes/zone-delegations.js.map +1 -1
- package/dist/apps/mpp/App.d.ts +44 -44
- package/dist/apps/mpp/App.js +3 -3
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +1 -1
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/apps/mpp/internal/Error.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Error.js +1 -0
- package/dist/apps/mpp/internal/Error.js.map +1 -1
- package/dist/apps/mpp/internal/Policy.d.ts +5 -1
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Policy.js +35 -13
- package/dist/apps/mpp/internal/Policy.js.map +1 -1
- package/dist/apps/relay/App.d.ts +2 -2
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +25 -16
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/routes/App.d.ts +311 -311
- package/dist/apps/routes/routes/deposit-addresses.d.ts +1099 -1099
- package/dist/apps/routes/routes/list.d.ts +74 -74
- package/dist/apps/routes/routes/transfers.d.ts +94 -94
- package/dist/cli/ApiKeys.d.ts +19 -26
- package/dist/cli/ApiKeys.d.ts.map +1 -1
- package/dist/db/Db.d.ts +3 -3
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +27 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +28 -62
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +18 -18
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/rewardRuns.d.ts +21 -0
- package/dist/db/tables/rewardRuns.d.ts.map +1 -1
- package/dist/db/tables/rewardRuns.js +19 -0
- package/dist/db/tables/rewardRuns.js.map +1 -1
- package/dist/db/tables/routesAccessRequests.d.ts +13 -0
- package/dist/db/tables/routesAccessRequests.d.ts.map +1 -1
- package/dist/db/tables/routesAccessRequests.js +12 -0
- package/dist/db/tables/routesAccessRequests.js.map +1 -1
- package/dist/db/tables/zoneDelegationRequests.d.ts +165 -0
- package/dist/db/tables/zoneDelegationRequests.d.ts.map +1 -0
- package/dist/db/tables/{zoneKeyRequests.js → zoneDelegationRequests.js} +43 -42
- package/dist/db/tables/zoneDelegationRequests.js.map +1 -0
- package/dist/db/tables/zoneDelegations.d.ts +11 -5
- package/dist/db/tables/zoneDelegations.d.ts.map +1 -1
- package/dist/db/tables/zoneDelegations.js +21 -3
- package/dist/db/tables/zoneDelegations.js.map +1 -1
- package/dist/handlers/internal/accounts.d.ts +7 -0
- package/dist/handlers/internal/accounts.d.ts.map +1 -0
- package/dist/handlers/internal/{multisig.js → accounts.js} +10 -10
- package/dist/handlers/internal/{multisig.js.map → accounts.js.map} +1 -1
- package/dist/handlers/internal/sponsorship.js +17 -17
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/relay.d.ts +6 -6
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +15 -15
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +4 -8
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/EarnRates.d.ts.map +1 -1
- package/dist/internal/EarnRates.js +1 -3
- package/dist/internal/EarnRates.js.map +1 -1
- package/dist/internal/EarnVaults.js +2 -2
- package/dist/internal/Log.d.ts +2 -4
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +0 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +0 -3
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +11 -0
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +24 -1
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/ZoneAccess.d.ts +70 -35
- package/dist/internal/ZoneAccess.d.ts.map +1 -1
- package/dist/internal/ZoneAccess.js +312 -131
- package/dist/internal/ZoneAccess.js.map +1 -1
- package/dist/internal/ZoneDelegation.d.ts +7 -19
- package/dist/internal/ZoneDelegation.d.ts.map +1 -1
- package/dist/internal/ZoneDelegation.js +8 -29
- package/dist/internal/ZoneDelegation.js.map +1 -1
- package/dist/internal/{ZoneKeyApproval.d.ts → ZoneDelegationApproval.d.ts} +3 -5
- package/dist/internal/ZoneDelegationApproval.d.ts.map +1 -0
- package/dist/internal/ZoneDelegationApproval.js +16 -0
- package/dist/internal/ZoneDelegationApproval.js.map +1 -0
- package/dist/internal/ZoneKeyRewrite.d.ts +98 -0
- package/dist/internal/ZoneKeyRewrite.d.ts.map +1 -0
- package/dist/internal/ZoneKeyRewrite.js +151 -0
- package/dist/internal/ZoneKeyRewrite.js.map +1 -0
- package/dist/internal/rewards/Campaigns.d.ts +2 -0
- package/dist/internal/rewards/Campaigns.d.ts.map +1 -1
- package/dist/internal/rewards/Campaigns.js.map +1 -1
- package/dist/internal/rewards/Distributions.d.ts.map +1 -1
- package/dist/internal/rewards/Distributions.js +2 -6
- package/dist/internal/rewards/Distributions.js.map +1 -1
- package/dist/internal/rewards/Monitor.d.ts +4 -1
- package/dist/internal/rewards/Monitor.d.ts.map +1 -1
- package/dist/internal/rewards/Monitor.js +19 -2
- package/dist/internal/rewards/Monitor.js.map +1 -1
- package/dist/internal/rewards/Runner.d.ts.map +1 -1
- package/dist/internal/rewards/Runner.js +9 -1
- package/dist/internal/rewards/Runner.js.map +1 -1
- package/dist/internal/routes/Action.d.ts.map +1 -1
- package/dist/internal/routes/Action.js +2 -3
- package/dist/internal/routes/Action.js.map +1 -1
- package/dist/internal/routes/Deposit.d.ts.map +1 -1
- package/dist/internal/routes/Deposit.js +2 -6
- package/dist/internal/routes/Deposit.js.map +1 -1
- package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
- package/dist/internal/routes/DepositAddress.js +4 -10
- package/dist/internal/routes/DepositAddress.js.map +1 -1
- package/dist/internal/routes/Policy.d.ts.map +1 -1
- package/dist/internal/routes/Policy.js +2 -1
- package/dist/internal/routes/Policy.js.map +1 -1
- package/dist/internal/routes/Provider.js +8 -8
- package/dist/internal/routes/Provider.js.map +1 -1
- package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
- package/dist/internal/routes/Reconciliation.js +3 -2
- package/dist/internal/routes/Reconciliation.js.map +1 -1
- package/dist/internal/routes/Transfer.d.ts.map +1 -1
- package/dist/internal/routes/Transfer.js +4 -12
- package/dist/internal/routes/Transfer.js.map +1 -1
- package/dist/internal/routes/UniversalDepositAddress.d.ts.map +1 -1
- package/dist/internal/routes/UniversalDepositAddress.js +3 -6
- package/dist/internal/routes/UniversalDepositAddress.js.map +1 -1
- package/dist/internal/routes/providers/SquidOrder.d.ts.map +1 -1
- package/dist/internal/routes/providers/SquidOrder.js +3 -2
- package/dist/internal/routes/providers/SquidOrder.js.map +1 -1
- package/dist/internal/routes/providers/relay.d.ts.map +1 -1
- package/dist/internal/routes/providers/relay.js +4 -3
- package/dist/internal/routes/providers/relay.js.map +1 -1
- package/package.json +20 -5
- package/src/ApiKey.ts +2 -2
- package/src/ApiKeys.test.ts +284 -51
- package/src/ApiKeys.ts +297 -64
- package/src/App.ts +4 -5
- package/src/Client.test-d.ts +33 -126
- package/src/Scope.test.ts +26 -45
- package/src/Scope.ts +24 -37
- package/src/admin/App.test.ts +51 -4
- package/src/admin/App.ts +25 -33
- package/src/admin/Mcp.test.ts +2 -1
- package/src/admin/apps/api-keys.test.ts +90 -20
- package/src/admin/apps/api-keys.ts +5 -8
- package/src/admin/apps/audit-logs.ts +1 -1
- package/src/admin/apps/earn-vaults.test.ts +19 -19
- package/src/admin/apps/earn-vaults.ts +11 -5
- package/src/admin/apps/routes-support.test.ts +254 -3
- package/src/admin/apps/routes-support.ts +1 -44
- package/src/admin/apps/scopes.test.ts +3 -3
- package/src/admin/apps/zone-delegation-requests.test.ts +246 -0
- package/src/admin/apps/zone-delegation-requests.ts +240 -0
- package/src/admin/apps/zone-delegations.test.ts +218 -58
- package/src/admin/apps/zone-delegations.ts +146 -46
- package/src/admin/index.ts +1 -1
- package/src/admin/ui/src/components/ApiKeyForm.tsx +4 -3
- package/src/admin/ui/src/lib/config.ts +3 -3
- package/src/admin/ui/src/lib/query-client.ts +1 -1
- package/src/admin/ui/src/lib/review-queues.ts +10 -10
- package/src/admin/ui/src/lib/routes-setup.test.ts +1 -2
- package/src/admin/ui/src/lib/routes-setup.ts +3 -5
- package/src/admin/ui/src/lib/scopes.test.ts +3 -6
- package/src/admin/ui/src/lib/scopes.ts +2 -9
- package/src/admin/ui/src/lib/{zone-key-requests.ts → zone-delegation-requests.ts} +27 -31
- package/src/admin/ui/src/routeTree.gen.ts +17 -17
- package/src/admin/ui/src/routes/__root.tsx +1 -1
- package/src/admin/ui/src/routes/api-keys.tsx +2 -15
- package/src/admin/ui/src/routes/audit-logs.tsx +2 -2
- package/src/admin/ui/src/routes/index.tsx +11 -11
- package/src/admin/ui/src/routes/organizations.tsx +3 -1
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +3 -1
- package/src/admin/ui/src/routes/organizations_.$orgId_.setup.tsx +1 -3
- package/src/admin/ui/src/routes/{zone-key-requests.tsx → zone-delegation-requests.tsx} +228 -172
- package/src/admin/ui/vite.config.ts +14 -1
- package/src/admin/ui.generated.ts +412 -583
- package/src/analytics/tables/requestEvents.test.ts +13 -3
- package/src/analytics/tables/requestEvents.ts +4 -3
- package/src/apps/data/App.test.ts +72 -35
- package/src/apps/data/App.ts +29 -13
- package/src/apps/data/ZoneSelection.test.ts +53 -70
- package/src/apps/data/ZoneSelection.ts +2 -2
- package/src/apps/data/routes/activities.test.ts +140 -6
- package/src/apps/data/routes/activities.ts +124 -18
- package/src/apps/data/routes/balances.ts +5 -1
- package/src/apps/data/routes/blocks.ts +9 -13
- package/src/apps/data/routes/earn-transactions.local.test.ts +6 -1
- package/src/apps/data/routes/earn-transactions.test.ts +7 -3
- package/src/apps/data/routes/earn.bench.ts +0 -14
- package/src/apps/data/routes/earn.discovery.test.ts +4 -39
- package/src/apps/data/routes/earn.local.test.ts +27 -34
- package/src/apps/data/routes/earn.test.ts +172 -490
- package/src/apps/data/routes/earn.ts +103 -652
- package/src/apps/data/routes/exchanges.ts +20 -30
- package/src/apps/data/routes/fee-amm.ts +12 -18
- package/src/apps/data/routes/indexer.test.ts +14 -12
- package/src/apps/data/routes/receipts.ts +1 -1
- package/src/apps/data/routes/rpc.test.ts +23 -18
- package/src/apps/data/routes/rpc.ts +21 -21
- package/src/apps/data/routes/rpc.zone.test.ts +60 -6
- package/src/apps/data/routes/tokenlist.ts +4 -6
- package/src/apps/data/routes/tokens.test.ts +20 -0
- package/src/apps/data/routes/tokens.ts +10 -5
- package/src/apps/data/routes/transactions.ts +3 -3
- package/src/apps/data/routes/transfers.ts +4 -6
- package/src/apps/data/routes/valuation.test.ts +2 -4
- package/src/apps/data/routes/valuation.ts +4 -6
- package/src/apps/data/routes/webhooks.test.ts +1 -5
- package/src/apps/data/routes/webhooks.ts +30 -44
- package/src/apps/data/routes/zones.test.ts +35 -19
- package/src/apps/management/App.ts +3 -1
- package/src/apps/management/routes/api-keys.test.ts +112 -22
- package/src/apps/management/routes/api-keys.ts +30 -15
- package/src/apps/management/routes/billing.ts +17 -25
- package/src/apps/management/routes/cli.ts +12 -18
- package/src/apps/management/routes/fee-payer-usage.ts +5 -4
- package/src/apps/management/routes/invitations.ts +16 -21
- package/src/apps/management/routes/invite-links.ts +18 -26
- package/src/apps/management/routes/me.ts +9 -13
- package/src/apps/management/routes/members.ts +5 -7
- package/src/apps/management/routes/orgs.ts +8 -12
- package/src/apps/management/routes/projects.ts +8 -12
- package/src/apps/management/routes/route-usage.ts +5 -4
- package/src/apps/management/routes/routes-access-requests.test.ts +64 -2
- package/src/apps/management/routes/routes-access-requests.ts +99 -15
- package/src/apps/management/routes/scopes.test.ts +3 -3
- package/src/apps/management/routes/usage.ts +20 -28
- package/src/apps/management/routes/verified-token-requests.ts +9 -13
- package/src/apps/management/routes/zone-delegations.test.ts +3 -5
- package/src/apps/management/routes/zone-delegations.ts +4 -9
- package/src/apps/mpp/App.ts +3 -3
- package/src/apps/mpp/Mpp.zone.test.ts +49 -18
- package/src/apps/mpp/internal/Adapter.ts +1 -1
- package/src/apps/mpp/internal/Error.test.ts +3 -0
- package/src/apps/mpp/internal/Error.ts +1 -0
- package/src/apps/mpp/internal/Policy.test.ts +9 -8
- package/src/apps/mpp/internal/Policy.ts +37 -14
- package/src/apps/relay/App.sandbox.test.ts +15 -14
- package/src/apps/relay/App.test.ts +120 -61
- package/src/apps/relay/App.ts +28 -18
- package/src/apps/relay/App.zone-billing.test.ts +9 -4
- package/src/apps/routes/App.test.ts +21 -22
- package/src/db/Db.ts +34 -3
- package/src/db/Schema.ts +26 -26
- package/src/db/tables/rewardRuns.ts +39 -0
- package/src/db/tables/routesAccessRequests.test.ts +65 -0
- package/src/db/tables/routesAccessRequests.ts +25 -0
- package/src/db/tables/{zoneKeyRequests.test.ts → zoneDelegationRequests.test.ts} +36 -77
- package/src/db/tables/{zoneKeyRequests.ts → zoneDelegationRequests.ts} +69 -52
- package/src/db/tables/zoneDelegations.test.ts +5 -6
- package/src/db/tables/zoneDelegations.ts +25 -8
- package/src/handlers/internal/{multisig.store.test.ts → accounts.store.test.ts} +16 -16
- package/src/handlers/internal/{multisig.test.ts → accounts.test.ts} +85 -82
- package/src/handlers/internal/{multisig.ts → accounts.ts} +9 -9
- package/src/handlers/internal/sponsorship.ts +20 -20
- package/src/handlers/relay.test.ts +48 -46
- package/src/handlers/relay.ts +26 -26
- package/src/internal/Auth.test.ts +6 -2
- package/src/internal/Auth.ts +4 -10
- package/src/internal/EarnRates.ts +4 -6
- package/src/internal/EarnVaults.ts +2 -2
- package/src/internal/Log.test-d.ts +1 -0
- package/src/internal/Log.test.ts +4 -6
- package/src/internal/Log.ts +2 -6
- package/src/internal/Response.ts +0 -3
- package/src/internal/Schema.test.ts +42 -0
- package/src/internal/Schema.ts +36 -1
- package/src/internal/ZoneAccess.test.ts +515 -312
- package/src/internal/ZoneAccess.ts +410 -158
- package/src/internal/ZoneDelegation.test.ts +1 -41
- package/src/internal/ZoneDelegation.ts +10 -48
- package/src/internal/ZoneDelegationApproval.test.ts +22 -0
- package/src/internal/{ZoneKeyApproval.ts → ZoneDelegationApproval.ts} +4 -11
- package/src/internal/ZoneKeyRewrite.ts +231 -0
- package/src/internal/rewards/Campaigns.ts +2 -0
- package/src/internal/rewards/Distributions.ts +8 -12
- package/src/internal/rewards/Monitor.test.ts +64 -0
- package/src/internal/rewards/Monitor.ts +27 -4
- package/src/internal/rewards/Runner.ts +9 -1
- package/src/internal/routes/Action.ts +5 -6
- package/src/internal/routes/Deposit.ts +8 -12
- package/src/internal/routes/DepositAddress.ts +13 -19
- package/src/internal/routes/Policy.ts +2 -1
- package/src/internal/routes/Provider.ts +8 -8
- package/src/internal/routes/Reconciliation.ts +3 -2
- package/src/internal/routes/Transfer.ts +16 -24
- package/src/internal/routes/UniversalDepositAddress.ts +9 -12
- package/src/internal/routes/providers/SquidOrder.ts +3 -2
- package/src/internal/routes/providers/relay.ts +4 -3
- package/dist/admin/apps/zone-key-requests.d.ts +0 -406
- package/dist/admin/apps/zone-key-requests.d.ts.map +0 -1
- package/dist/admin/apps/zone-key-requests.js +0 -183
- package/dist/admin/apps/zone-key-requests.js.map +0 -1
- package/dist/db/tables/zoneKeyRequests.d.ts +0 -289
- package/dist/db/tables/zoneKeyRequests.d.ts.map +0 -1
- package/dist/db/tables/zoneKeyRequests.js.map +0 -1
- package/dist/handlers/internal/multisig.d.ts +0 -7
- package/dist/handlers/internal/multisig.d.ts.map +0 -1
- package/dist/internal/ZoneKeyApproval.d.ts.map +0 -1
- package/dist/internal/ZoneKeyApproval.js +0 -21
- package/dist/internal/ZoneKeyApproval.js.map +0 -1
- package/src/admin/apps/zone-key-requests.test.ts +0 -272
- package/src/admin/apps/zone-key-requests.ts +0 -231
- package/src/internal/ZoneKeyApproval.test.ts +0 -46
package/src/apps/relay/App.ts
CHANGED
|
@@ -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
|
|
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('
|
|
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
|
|
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
|
-
|
|
555
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
//
|
|
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.
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
23
|
-
export const
|
|
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<
|
|
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', '
|
|
47
|
+
status: z.enum(['pending', 'applying', 'applied', 'failed', 'cancelled']),
|
|
33
48
|
})
|
|
34
|
-
/** Columns of the
|
|
35
|
-
export type
|
|
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
|
|
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
|
|
46
|
-
export type
|
|
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
|