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
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as ZoneKeyApproval from '../../internal/ZoneKeyApproval.js'
|
|
3
|
-
import * as Store from '../../internal/Store.js'
|
|
1
|
+
import * as ZoneDelegationApproval from '../../internal/ZoneDelegationApproval.js'
|
|
4
2
|
import * as TestApp from '../../../test/App.js'
|
|
5
|
-
import * as Requests from './
|
|
6
|
-
import * as ApiKeyAdmissions from './apiKeyAdmissions.js'
|
|
3
|
+
import * as Requests from './zoneDelegationRequests.js'
|
|
7
4
|
|
|
8
5
|
// Sessions outlive the approval lifetime so tests can isolate each bound.
|
|
9
|
-
const expiresAt = new Date(Date.now() + 2 *
|
|
6
|
+
const expiresAt = new Date(Date.now() + 2 * ZoneDelegationApproval.approvalLifetime).toISOString()
|
|
10
7
|
const requester = {
|
|
11
8
|
email: 'requester@tempo.xyz',
|
|
12
9
|
eligible: false,
|
|
@@ -17,17 +14,17 @@ const first = { email: 'first@tempo.xyz', eligible: true, expiresAt, id: 'employ
|
|
|
17
14
|
const second = { email: 'second@tempo.xyz', eligible: true, expiresAt, id: 'employee_second' }
|
|
18
15
|
const groupId = 'app-tempo-api-zone-issuers'
|
|
19
16
|
const input = {
|
|
20
|
-
|
|
17
|
+
accountsAll: true,
|
|
18
|
+
chainId: 421_700_001,
|
|
21
19
|
environment: 'production' as const,
|
|
22
|
-
name: 'Zone reader',
|
|
23
20
|
orgId: 'org_fixture',
|
|
24
|
-
|
|
21
|
+
tokensAll: true,
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
describe('get', () => {
|
|
28
25
|
test('reads only the requested approvals and returns null for a missing request', async () => {
|
|
29
26
|
const db = TestApp.database()
|
|
30
|
-
expect(await Requests.get(db, '
|
|
27
|
+
expect(await Requests.get(db, 'zdr_missing')).toBeNull()
|
|
31
28
|
const request = await Requests.create(db, { groupId, input, requester })
|
|
32
29
|
expect((await Requests.get(db, request.id))?.approvals).toEqual([])
|
|
33
30
|
const other = await Requests.create(db, { groupId, input, requester })
|
|
@@ -57,7 +54,7 @@ describe('approve', () => {
|
|
|
57
54
|
lookup: async () => users,
|
|
58
55
|
member: first,
|
|
59
56
|
}),
|
|
60
|
-
).rejects.toThrow(
|
|
57
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
61
58
|
await expect(
|
|
62
59
|
Requests.approve(db, {
|
|
63
60
|
groupId,
|
|
@@ -83,7 +80,7 @@ describe('approve', () => {
|
|
|
83
80
|
])
|
|
84
81
|
await expect(
|
|
85
82
|
Requests.approve(db, { lookup, groupId, id: request.id, member }),
|
|
86
|
-
).rejects.toThrow(
|
|
83
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
87
84
|
await Requests.approve(db, { lookup, groupId, id: request.id, member: first })
|
|
88
85
|
await Requests.approve(db, {
|
|
89
86
|
lookup,
|
|
@@ -113,7 +110,7 @@ describe('claim', () => {
|
|
|
113
110
|
lookup: () => lookup([requester.id, first.id, first.id, 'employee_unrecorded']),
|
|
114
111
|
member: requester,
|
|
115
112
|
}),
|
|
116
|
-
).rejects.toThrow(
|
|
113
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
117
114
|
expect((await Requests.get(db, request.id))?.status).toBe('pending')
|
|
118
115
|
})
|
|
119
116
|
|
|
@@ -137,7 +134,7 @@ describe('claim', () => {
|
|
|
137
134
|
lookup: async () => users,
|
|
138
135
|
member: requester,
|
|
139
136
|
}),
|
|
140
|
-
).rejects.toThrow(
|
|
137
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
141
138
|
expect((await Requests.get(db, request.id))?.status).toBe('pending')
|
|
142
139
|
}
|
|
143
140
|
await expect(
|
|
@@ -150,7 +147,7 @@ describe('claim', () => {
|
|
|
150
147
|
member: requester,
|
|
151
148
|
}),
|
|
152
149
|
).rejects.toThrow('Directory unavailable')
|
|
153
|
-
expect((await Requests.get(db, request.id))?.
|
|
150
|
+
expect((await Requests.get(db, request.id))?.status).toBe('pending')
|
|
154
151
|
await expect(
|
|
155
152
|
Requests.claim(db, { groupId, id: request.id, lookup, member: requester }),
|
|
156
153
|
).resolves.toMatchObject({ input })
|
|
@@ -171,11 +168,11 @@ describe('claim', () => {
|
|
|
171
168
|
id: request.id,
|
|
172
169
|
member: requester,
|
|
173
170
|
lookup: async (ids) => {
|
|
174
|
-
vi.setSystemTime(now +
|
|
171
|
+
vi.setSystemTime(now + ZoneDelegationApproval.approvalLifetime)
|
|
175
172
|
return lookup(ids)
|
|
176
173
|
},
|
|
177
174
|
}),
|
|
178
|
-
).rejects.toThrow(
|
|
175
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
179
176
|
expect((await Requests.get(db, request.id))?.status).toBe('pending')
|
|
180
177
|
} finally {
|
|
181
178
|
vi.useRealTimers()
|
|
@@ -197,11 +194,11 @@ describe('claim', () => {
|
|
|
197
194
|
short.expiresAt,
|
|
198
195
|
)
|
|
199
196
|
expect(stored?.approvals.find((a) => a.approverId === second.id)?.expiresAt).toBe(
|
|
200
|
-
new Date(now +
|
|
197
|
+
new Date(now + ZoneDelegationApproval.approvalLifetime).toISOString(),
|
|
201
198
|
)
|
|
202
199
|
vi.setSystemTime(now + 30_000)
|
|
203
200
|
const claim = { lookup, groupId, id: request.id, member: requester }
|
|
204
|
-
await expect(Requests.claim(db, claim)).rejects.toThrow(
|
|
201
|
+
await expect(Requests.claim(db, claim)).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
205
202
|
await Requests.approve(db, { lookup, groupId, id: request.id, member: first })
|
|
206
203
|
expect((await Requests.get(db, request.id))?.approvals).toHaveLength(2)
|
|
207
204
|
await expect(Requests.claim(db, claim)).resolves.toMatchObject({ input })
|
|
@@ -220,13 +217,13 @@ describe('claim', () => {
|
|
|
220
217
|
for (const member of [first, second])
|
|
221
218
|
await Requests.approve(db, { lookup, groupId, id: request.id, member })
|
|
222
219
|
expect((await Requests.get(db, request.id))?.approvals.map((a) => a.expiresAt)).toEqual([
|
|
223
|
-
new Date(now +
|
|
224
|
-
new Date(now +
|
|
220
|
+
new Date(now + ZoneDelegationApproval.approvalLifetime).toISOString(),
|
|
221
|
+
new Date(now + ZoneDelegationApproval.approvalLifetime).toISOString(),
|
|
225
222
|
])
|
|
226
|
-
vi.setSystemTime(now +
|
|
223
|
+
vi.setSystemTime(now + ZoneDelegationApproval.approvalLifetime)
|
|
227
224
|
await expect(
|
|
228
225
|
Requests.claim(db, { lookup, groupId, id: request.id, member: requester }),
|
|
229
|
-
).rejects.toThrow(
|
|
226
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
230
227
|
expect((await Requests.get(db, request.id))?.status).toBe('pending')
|
|
231
228
|
} finally {
|
|
232
229
|
vi.useRealTimers()
|
|
@@ -237,9 +234,9 @@ describe('claim', () => {
|
|
|
237
234
|
const db = TestApp.database()
|
|
238
235
|
const request = await Requests.create(db, { groupId, input, requester })
|
|
239
236
|
const claim = { lookup, groupId, id: request.id, member: requester }
|
|
240
|
-
await expect(Requests.claim(db, claim)).rejects.toThrow(
|
|
237
|
+
await expect(Requests.claim(db, claim)).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
241
238
|
await Requests.approve(db, { lookup, groupId, id: request.id, member: first })
|
|
242
|
-
await expect(Requests.claim(db, claim)).rejects.toThrow(
|
|
239
|
+
await expect(Requests.claim(db, claim)).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
243
240
|
await Requests.approve(db, { lookup, groupId, id: request.id, member: second })
|
|
244
241
|
for (const options of [
|
|
245
242
|
{ ...claim, member: { ...requester, id: 'employee_recreated' } },
|
|
@@ -248,14 +245,15 @@ describe('claim', () => {
|
|
|
248
245
|
{ ...claim, member: null },
|
|
249
246
|
{ ...claim, groupId: 'replacement-group' },
|
|
250
247
|
])
|
|
251
|
-
await expect(Requests.claim(db, options)).rejects.toThrow(
|
|
248
|
+
await expect(Requests.claim(db, options)).rejects.toThrow(
|
|
249
|
+
ZoneDelegationApproval.RequiredError,
|
|
250
|
+
)
|
|
252
251
|
const claimed = await Requests.claim(db, claim)
|
|
253
252
|
expect(claimed.input).toEqual(input)
|
|
254
|
-
expect(
|
|
255
|
-
await expect(Requests.claim(db, claim)).rejects.toThrow(ZoneKeyApproval.RequiredError)
|
|
253
|
+
await expect(Requests.claim(db, claim)).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
256
254
|
})
|
|
257
255
|
|
|
258
|
-
test('allows only one concurrent claim and
|
|
256
|
+
test('allows only one concurrent claim and never replays a finished one', async () => {
|
|
259
257
|
const factory = TestApp.databaseFactory()
|
|
260
258
|
const db = factory()
|
|
261
259
|
const request = await Requests.create(db, { groupId, input, requester })
|
|
@@ -273,19 +271,19 @@ describe('claim', () => {
|
|
|
273
271
|
]
|
|
274
272
|
`)
|
|
275
273
|
const stored = await Requests.get(db, request.id)
|
|
276
|
-
expect(stored?.status).toBe('
|
|
277
|
-
|
|
278
|
-
await Requests.
|
|
279
|
-
await expect(Requests.claim(db, options)).rejects.toThrow(
|
|
274
|
+
expect(stored?.status).toBe('applying')
|
|
275
|
+
await Requests.finish(db, request.id, { status: 'failed' })
|
|
276
|
+
expect((await Requests.get(db, request.id))?.status).toBe('failed')
|
|
277
|
+
await expect(Requests.claim(db, options)).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
280
278
|
})
|
|
281
279
|
|
|
282
|
-
test('cancellation prevents approval and
|
|
280
|
+
test('cancellation prevents approval and application', async () => {
|
|
283
281
|
const db = TestApp.database()
|
|
284
282
|
const request = await Requests.create(db, { groupId, input, requester })
|
|
285
283
|
await Requests.cancel(db, request.id)
|
|
286
284
|
await expect(
|
|
287
285
|
Requests.approve(db, { lookup, groupId, id: request.id, member: first }),
|
|
288
|
-
).rejects.toThrow(
|
|
286
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
289
287
|
await expect(
|
|
290
288
|
Requests.claim(db, {
|
|
291
289
|
lookup,
|
|
@@ -293,7 +291,7 @@ describe('claim', () => {
|
|
|
293
291
|
id: request.id,
|
|
294
292
|
member: requester,
|
|
295
293
|
}),
|
|
296
|
-
).rejects.toThrow(
|
|
294
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
297
295
|
})
|
|
298
296
|
|
|
299
297
|
test('requests expire after 24 hours', async () => {
|
|
@@ -304,53 +302,14 @@ describe('claim', () => {
|
|
|
304
302
|
vi.setSystemTime(new Date(Date.parse(request.expiresAt) + 1))
|
|
305
303
|
await expect(
|
|
306
304
|
Requests.approve(db, { lookup, groupId, id: request.id, member: first }),
|
|
307
|
-
).rejects.toThrow(
|
|
305
|
+
).rejects.toThrow(ZoneDelegationApproval.RequiredError)
|
|
308
306
|
} finally {
|
|
309
307
|
vi.useRealTimers()
|
|
310
308
|
}
|
|
311
309
|
})
|
|
312
310
|
})
|
|
313
311
|
|
|
314
|
-
|
|
315
|
-
test('does not publish a protected scope intent through an ordinary update', async () => {
|
|
316
|
-
const db = TestApp.database()
|
|
317
|
-
const store = Store.memory()
|
|
318
|
-
const { record } = await ApiKeys.mintBounded(db, store, { orgId: 'org_fixture', scopes: [] })
|
|
319
|
-
await db.transaction(async (tx) => {
|
|
320
|
-
await ApiKeyAdmissions.lock(tx, record.id)
|
|
321
|
-
await ApiKeyAdmissions.setPendingScopes(tx, record.id, ['*'])
|
|
322
|
-
})
|
|
323
|
-
await expect(ApiKeys.updateBounded(db, store, record.id, { name: 'Changed' })).rejects.toThrow(
|
|
324
|
-
ZoneKeyApproval.RequiredError,
|
|
325
|
-
)
|
|
326
|
-
expect((await ApiKeys.get(store, record.id))?.scopes).toEqual([])
|
|
327
|
-
})
|
|
328
|
-
test('blocks Zone read and wildcard minting at the shared admission boundary', async () => {
|
|
329
|
-
const db = TestApp.database()
|
|
330
|
-
const store = Store.memory()
|
|
331
|
-
for (const scopes of [['zone:421700001:read'], ['*']])
|
|
332
|
-
await expect(ApiKeys.mintBounded(db, store, { scopes })).rejects.toThrow(
|
|
333
|
-
ZoneKeyApproval.RequiredError,
|
|
334
|
-
)
|
|
335
|
-
expect(await ApiKeys.list(store)).toEqual([])
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
test('blocks elevation and edits to existing protected keys while allowing revocation', async () => {
|
|
339
|
-
const db = TestApp.database()
|
|
340
|
-
const store = Store.memory()
|
|
341
|
-
const plain = await ApiKeys.mint(store, { scopes: ['data:read'] })
|
|
342
|
-
const protectedKey = await ApiKeys.mint(store, { scopes: ['zone:421700001:read'] })
|
|
343
|
-
await expect(
|
|
344
|
-
ApiKeys.updateBounded(db, store, plain.record.id, { scopes: ['*'] }),
|
|
345
|
-
).rejects.toThrow(ZoneKeyApproval.RequiredError)
|
|
346
|
-
await expect(
|
|
347
|
-
ApiKeys.updateBounded(db, store, protectedKey.record.id, { allowedIps: [] }),
|
|
348
|
-
).rejects.toThrow(ZoneKeyApproval.RequiredError)
|
|
349
|
-
expect(await ApiKeys.revokeBounded(db, store, protectedKey.record.id)).toBe(true)
|
|
350
|
-
})
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
async function lookup(ids: readonly string[]): Promise<ZoneKeyApproval.Status[]> {
|
|
312
|
+
async function lookup(ids: readonly string[]): Promise<ZoneDelegationApproval.Status[]> {
|
|
354
313
|
return ids.map((id) => ({
|
|
355
314
|
active: true,
|
|
356
315
|
eligible: id !== 'employee_requester' && id !== 'employee_nonmember',
|
|
@@ -1,34 +1,37 @@
|
|
|
1
1
|
import type { JSONColumnType } from 'kysely'
|
|
2
2
|
import { jsonArrayFrom } from 'kysely/helpers/postgres'
|
|
3
3
|
|
|
4
|
-
import * as ApiKey from '../../ApiKey.js'
|
|
5
4
|
import * as Cursor from '../../internal/Cursor.js'
|
|
6
5
|
import * as Id from '../../internal/Id.js'
|
|
7
|
-
import * as
|
|
6
|
+
import * as ZoneDelegationApproval from '../../internal/ZoneDelegationApproval.js'
|
|
8
7
|
import type * as Db from '../Db.js'
|
|
9
8
|
import type * as Schema from '../Schema.js'
|
|
9
|
+
import type * as ZoneDelegations from './zoneDelegations.js'
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
export type
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
/** Settings a request asks approvers to review: the delegation to create. */
|
|
12
|
+
export type Input = ZoneDelegations.create.Input
|
|
13
|
+
|
|
14
|
+
/** Persisted immutable request for one Zone delegation. */
|
|
15
|
+
export type Table = Omit<Schema.ZoneDelegationRequest, 'input'> & {
|
|
16
|
+
/** Validated delegation settings persisted as JSON. */
|
|
17
|
+
input: JSONColumnType<Schema.ZoneDelegationRequest['input']>
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
/** One unique approver's decision. */
|
|
18
|
-
export type ApprovalTable = Schema.
|
|
21
|
+
export type ApprovalTable = Schema.ZoneDelegationApproval
|
|
19
22
|
|
|
20
|
-
/** Stores an immutable
|
|
23
|
+
/** Stores an immutable delegation request that expires after 24 hours. */
|
|
21
24
|
export async function create(db: Db.Db, options: create.Options) {
|
|
22
25
|
const now = new Date()
|
|
23
26
|
return db.kysely
|
|
24
|
-
.insertInto('
|
|
27
|
+
.insertInto('zone_delegation_requests')
|
|
25
28
|
.values({
|
|
26
29
|
createdAt: now.toISOString(),
|
|
30
|
+
delegationId: null,
|
|
27
31
|
expiresAt: new Date(now.getTime() + 86_400_000).toISOString(),
|
|
28
32
|
groupId: options.groupId,
|
|
29
|
-
id: Id.generate('
|
|
33
|
+
id: Id.generate('zdr'),
|
|
30
34
|
input: JSON.stringify(options.input),
|
|
31
|
-
keyId: null,
|
|
32
35
|
requesterEmail: options.requester.email,
|
|
33
36
|
requesterId: options.requester.id,
|
|
34
37
|
status: 'pending',
|
|
@@ -42,10 +45,10 @@ export declare namespace create {
|
|
|
42
45
|
type Options = {
|
|
43
46
|
/** Approver group pinned for this request. */
|
|
44
47
|
groupId: string
|
|
45
|
-
/** Exact
|
|
46
|
-
input: Schema.
|
|
48
|
+
/** Exact delegation settings reviewed by approvers. */
|
|
49
|
+
input: Schema.ZoneDelegationRequest['input']
|
|
47
50
|
/** Requester from the verified internal identity session. */
|
|
48
|
-
requester:
|
|
51
|
+
requester: ZoneDelegationApproval.Member
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -53,14 +56,14 @@ export declare namespace create {
|
|
|
53
56
|
export async function get(db: Db.Db, id: string) {
|
|
54
57
|
return (
|
|
55
58
|
(await db.kysely
|
|
56
|
-
.selectFrom('
|
|
59
|
+
.selectFrom('zone_delegation_requests')
|
|
57
60
|
.selectAll()
|
|
58
61
|
.select((eb) =>
|
|
59
62
|
jsonArrayFrom(
|
|
60
63
|
eb
|
|
61
|
-
.selectFrom('
|
|
64
|
+
.selectFrom('zone_delegation_approvals')
|
|
62
65
|
.selectAll()
|
|
63
|
-
.whereRef('requestId', '=', '
|
|
66
|
+
.whereRef('requestId', '=', 'zone_delegation_requests.id')
|
|
64
67
|
.orderBy('approvedAt'),
|
|
65
68
|
).as('approvals'),
|
|
66
69
|
)
|
|
@@ -74,7 +77,7 @@ export async function list(db: Db.Db, options: list.Options = {}) {
|
|
|
74
77
|
const limit = 50
|
|
75
78
|
const cursor = options.cursor ? Cursor.decode(options.cursor, ['timestamp', 'id']) : undefined
|
|
76
79
|
const rows = await db.kysely
|
|
77
|
-
.selectFrom('
|
|
80
|
+
.selectFrom('zone_delegation_requests')
|
|
78
81
|
.selectAll()
|
|
79
82
|
.$if(Boolean(cursor), (query) =>
|
|
80
83
|
query.where((eb) =>
|
|
@@ -99,26 +102,31 @@ export declare namespace list {
|
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
/** Records one independent approval while serializing with
|
|
105
|
+
/** Records one independent approval while serializing with application and cancellation. */
|
|
103
106
|
export async function approve(db: Db.Db, options: approve.Options) {
|
|
104
107
|
return db.transaction(async (tx) => {
|
|
105
108
|
const request = await pending(tx, options.id, options.groupId)
|
|
106
109
|
const member = options.member
|
|
107
|
-
if (
|
|
108
|
-
|
|
110
|
+
if (
|
|
111
|
+
!ZoneDelegationApproval.active(member) ||
|
|
112
|
+
!member.eligible ||
|
|
113
|
+
member.id === request.requesterId
|
|
114
|
+
)
|
|
115
|
+
// prettier-ignore
|
|
116
|
+
throw new ZoneDelegationApproval.RequiredError(
|
|
109
117
|
'Approval requires an active group member other than the requester.',
|
|
110
118
|
)
|
|
111
119
|
const users = await options.lookup([member.id])
|
|
112
120
|
if (!users.some((user) => user.id === member.id && user.active && user.eligible))
|
|
113
|
-
throw new
|
|
114
|
-
if (!
|
|
115
|
-
throw new
|
|
121
|
+
throw new ZoneDelegationApproval.RequiredError('Approval requires a current active group member.') // prettier-ignore
|
|
122
|
+
if (!ZoneDelegationApproval.active(member) || Date.parse(request.expiresAt) <= Date.now())
|
|
123
|
+
throw new ZoneDelegationApproval.RequiredError('Approval request or session expired.')
|
|
116
124
|
const now = new Date()
|
|
117
125
|
const expiresAt = new Date(
|
|
118
|
-
Math.min(Date.parse(member.expiresAt), now.getTime() +
|
|
126
|
+
Math.min(Date.parse(member.expiresAt), now.getTime() + ZoneDelegationApproval.approvalLifetime), // prettier-ignore
|
|
119
127
|
).toISOString()
|
|
120
128
|
await tx.kysely
|
|
121
|
-
.insertInto('
|
|
129
|
+
.insertInto('zone_delegation_approvals')
|
|
122
130
|
.values({
|
|
123
131
|
approvedAt: now.toISOString(),
|
|
124
132
|
approverEmail: member.email,
|
|
@@ -146,30 +154,30 @@ export declare namespace approve {
|
|
|
146
154
|
/** Request being approved. */
|
|
147
155
|
id: string
|
|
148
156
|
/** Fetches current account and approval-group status without caching. */
|
|
149
|
-
lookup:
|
|
157
|
+
lookup: ZoneDelegationApproval.Lookup
|
|
150
158
|
/** Identity from the current verified session. */
|
|
151
|
-
member:
|
|
159
|
+
member: ZoneDelegationApproval.Member | null
|
|
152
160
|
}
|
|
153
161
|
}
|
|
154
162
|
|
|
155
|
-
/** Consumes approval once, before
|
|
163
|
+
/** Consumes approval once, before the delegation is written, so a failed write cannot be replayed. */
|
|
156
164
|
export async function claim(db: Db.Db, options: claim.Options) {
|
|
157
165
|
return db.transaction(async (tx) => {
|
|
158
166
|
const request = await pending(tx, options.id, options.groupId)
|
|
159
167
|
const requester = options.member
|
|
160
|
-
if (!
|
|
161
|
-
throw new
|
|
162
|
-
'Only the original active requester can
|
|
168
|
+
if (!ZoneDelegationApproval.active(requester) || requester.id !== request.requesterId)
|
|
169
|
+
throw new ZoneDelegationApproval.RequiredError(
|
|
170
|
+
'Only the original active requester can apply this delegation.',
|
|
163
171
|
)
|
|
164
172
|
const approvals = await tx.kysely
|
|
165
|
-
.selectFrom('
|
|
173
|
+
.selectFrom('zone_delegation_approvals')
|
|
166
174
|
.selectAll()
|
|
167
175
|
.where('requestId', '=', request.id)
|
|
168
176
|
.where('approverId', '!=', requester.id)
|
|
169
177
|
.where('expiresAt', '>', new Date().toISOString())
|
|
170
178
|
.execute()
|
|
171
|
-
if (approvals.length <
|
|
172
|
-
throw new
|
|
179
|
+
if (approvals.length < ZoneDelegationApproval.quorum)
|
|
180
|
+
throw new ZoneDelegationApproval.RequiredError(
|
|
173
181
|
'Two distinct, unexpired group approvals are required.',
|
|
174
182
|
)
|
|
175
183
|
// Keep the request locked while revalidating the requester and recorded approvers.
|
|
@@ -178,25 +186,24 @@ export async function claim(db: Db.Db, options: claim.Options) {
|
|
|
178
186
|
...approvals.map((approval) => approval.approverId),
|
|
179
187
|
])
|
|
180
188
|
if (!users.some((user) => user.id === requester.id && user.active))
|
|
181
|
-
throw new
|
|
189
|
+
throw new ZoneDelegationApproval.RequiredError('The requester is no longer active.')
|
|
182
190
|
const current = new Set(
|
|
183
191
|
users.filter((user) => user.active && user.eligible).map((user) => user.id),
|
|
184
192
|
)
|
|
185
193
|
const valid = approvals.filter(
|
|
186
194
|
(approval) => current.has(approval.approverId) && Date.parse(approval.expiresAt) > Date.now(),
|
|
187
195
|
)
|
|
188
|
-
if (valid.length <
|
|
189
|
-
throw new
|
|
196
|
+
if (valid.length < ZoneDelegationApproval.quorum)
|
|
197
|
+
throw new ZoneDelegationApproval.RequiredError('Two current active group approvals are required.') // prettier-ignore
|
|
190
198
|
// Lookup latency must not extend the request, session, or approval lifetime.
|
|
191
|
-
if (!
|
|
192
|
-
throw new
|
|
193
|
-
const keyId = ApiKey.generateId()
|
|
199
|
+
if (!ZoneDelegationApproval.active(requester) || Date.parse(request.expiresAt) <= Date.now())
|
|
200
|
+
throw new ZoneDelegationApproval.RequiredError('Approval request expired.')
|
|
194
201
|
await tx.kysely
|
|
195
|
-
.updateTable('
|
|
196
|
-
.set({
|
|
202
|
+
.updateTable('zone_delegation_requests')
|
|
203
|
+
.set({ status: 'applying' })
|
|
197
204
|
.where('id', '=', request.id)
|
|
198
205
|
.execute()
|
|
199
|
-
return
|
|
206
|
+
return request
|
|
200
207
|
})
|
|
201
208
|
}
|
|
202
209
|
|
|
@@ -205,20 +212,30 @@ export declare namespace claim {
|
|
|
205
212
|
type Options = approve.Options
|
|
206
213
|
}
|
|
207
214
|
|
|
208
|
-
/** Records the terminal
|
|
209
|
-
export async function finish(db: Db.Db, id: string,
|
|
215
|
+
/** Records the terminal outcome; a failed or interrupted claim cannot be replayed. */
|
|
216
|
+
export async function finish(db: Db.Db, id: string, outcome: finish.Outcome) {
|
|
210
217
|
await db.kysely
|
|
211
|
-
.updateTable('
|
|
212
|
-
.set({ status })
|
|
218
|
+
.updateTable('zone_delegation_requests')
|
|
219
|
+
.set({ delegationId: outcome.delegationId ?? null, status: outcome.status })
|
|
213
220
|
.where('id', '=', id)
|
|
214
|
-
.where('status', '=', '
|
|
221
|
+
.where('status', '=', 'applying')
|
|
215
222
|
.execute()
|
|
216
223
|
}
|
|
217
224
|
|
|
225
|
+
export declare namespace finish {
|
|
226
|
+
/** How the claimed request ended. */
|
|
227
|
+
type Outcome = {
|
|
228
|
+
/** Delegation the request created, when applied. */
|
|
229
|
+
delegationId?: string | undefined
|
|
230
|
+
/** Terminal status. */
|
|
231
|
+
status: 'applied' | 'failed'
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
218
235
|
/** Cancels a pending request without needing quorum. */
|
|
219
236
|
export async function cancel(db: Db.Db, id: string) {
|
|
220
237
|
return db.kysely
|
|
221
|
-
.updateTable('
|
|
238
|
+
.updateTable('zone_delegation_requests')
|
|
222
239
|
.set({ status: 'cancelled' })
|
|
223
240
|
.where('id', '=', id)
|
|
224
241
|
.where('status', '=', 'pending')
|
|
@@ -229,7 +246,7 @@ export async function cancel(db: Db.Db, id: string) {
|
|
|
229
246
|
/** Locks and validates the request before a state transition. */
|
|
230
247
|
async function pending(db: Db.Db, id: string, groupId: string) {
|
|
231
248
|
const request = await db.kysely
|
|
232
|
-
.selectFrom('
|
|
249
|
+
.selectFrom('zone_delegation_requests')
|
|
233
250
|
.selectAll()
|
|
234
251
|
.where('id', '=', id)
|
|
235
252
|
.forUpdate()
|
|
@@ -240,7 +257,7 @@ async function pending(db: Db.Db, id: string, groupId: string) {
|
|
|
240
257
|
request.groupId !== groupId ||
|
|
241
258
|
Date.parse(request.expiresAt) <= Date.now()
|
|
242
259
|
)
|
|
243
|
-
throw new
|
|
260
|
+
throw new ZoneDelegationApproval.RequiredError(
|
|
244
261
|
'Request is missing, expired, consumed, cancelled, or belongs to a different approver group.',
|
|
245
262
|
)
|
|
246
263
|
return request
|
|
@@ -26,7 +26,6 @@ describe('create', () => {
|
|
|
26
26
|
"chainId": 421700001,
|
|
27
27
|
"environment": "production",
|
|
28
28
|
"orgId": "org_zd",
|
|
29
|
-
"projects": "all",
|
|
30
29
|
"tokensAll": true,
|
|
31
30
|
}
|
|
32
31
|
`)
|
|
@@ -58,13 +57,13 @@ describe('create', () => {
|
|
|
58
57
|
})
|
|
59
58
|
|
|
60
59
|
describe('update', () => {
|
|
61
|
-
test('changes flags
|
|
60
|
+
test('changes flags of an active delegation only', async () => {
|
|
62
61
|
const db = TestApp.database()
|
|
63
62
|
await Organizations.create(db, { id: 'org_up', name: 'Update' })
|
|
64
|
-
const input = { accountsAll: true, chainId, environment: 'production', orgId: 'org_up',
|
|
63
|
+
const input = { accountsAll: true, chainId, environment: 'production', orgId: 'org_up', tokensAll: true } as const // prettier-ignore
|
|
65
64
|
const created = await ZoneDelegations.create(db, input)
|
|
66
|
-
const updated = await ZoneDelegations.update(db, created.id, { accountsAll: false
|
|
67
|
-
expect([updated?.id === created.id, updated?.accountsAll, updated?.
|
|
65
|
+
const updated = await ZoneDelegations.update(db, created.id, { accountsAll: false })
|
|
66
|
+
expect([updated?.id === created.id, updated?.accountsAll, updated?.tokensAll]).toEqual([true, false, true]) // prettier-ignore
|
|
68
67
|
await ZoneDelegations.revoke(db, created.id)
|
|
69
68
|
expect(await ZoneDelegations.update(db, created.id, { accountsAll: true })).toBeUndefined()
|
|
70
69
|
expect(await ZoneDelegations.update(db, 'zd_missing', { accountsAll: true })).toBeUndefined()
|
|
@@ -119,7 +118,7 @@ describe('Members', () => {
|
|
|
119
118
|
test('pages by address with a cursor', async () => {
|
|
120
119
|
const db = TestApp.database()
|
|
121
120
|
await Organizations.create(db, { id: 'org_p', name: 'Pages' })
|
|
122
|
-
const created = await ZoneDelegations.create(db, { accountsAll: false, chainId, environment: 'sandbox', orgId: 'org_p',
|
|
121
|
+
const created = await ZoneDelegations.create(db, { accountsAll: false, chainId, environment: 'sandbox', orgId: 'org_p', tokensAll: true }) // prettier-ignore
|
|
123
122
|
const addresses = Array.from({ length: 150 }, (_, i) => `0x${i.toString(16).padStart(40, '0')}`)
|
|
124
123
|
await ZoneDelegations.Members.add(db, { addresses, id: created.id, kind: 'account' })
|
|
125
124
|
const first = await ZoneDelegations.Members.list(db, { id: created.id, kind: 'account' }) // prettier-ignore
|
|
@@ -17,8 +17,8 @@ export type Table = Omit<Schema.ZoneDelegation, 'chainId' | 'projects'> & {
|
|
|
17
17
|
/** Columns of the `zone_delegation_members` table. */
|
|
18
18
|
export type MemberTable = Schema.ZoneDelegationMember
|
|
19
19
|
|
|
20
|
-
/** A stored delegation; a `null` revocation reads as absent. */
|
|
21
|
-
export type Record = Omit<Schema.ZoneDelegation, 'revokedAt'> & {
|
|
20
|
+
/** A stored delegation; a `null` revocation reads as absent. The retired `projects` column is not surfaced. */
|
|
21
|
+
export type Record = Omit<Schema.ZoneDelegation, 'projects' | 'revokedAt'> & {
|
|
22
22
|
/** When the delegation was revoked (ISO 8601); absent while active. */
|
|
23
23
|
revokedAt?: string | undefined
|
|
24
24
|
}
|
|
@@ -36,7 +36,7 @@ export type Scope = Pick<Record, 'chainId' | 'environment' | 'orgId'>
|
|
|
36
36
|
export type Owner = Pick<Record, 'environment' | 'orgId'>
|
|
37
37
|
|
|
38
38
|
/** Coverage settings on the delegation row itself. */
|
|
39
|
-
export type Coverage = Pick<Record, 'accountsAll' | '
|
|
39
|
+
export type Coverage = Pick<Record, 'accountsAll' | 'tokensAll'>
|
|
40
40
|
|
|
41
41
|
/** Creates an active delegation with optional initial members; an active one for the same Zone is a conflict. */
|
|
42
42
|
export function create(db: Db.Db, input: create.Input): Promise<Record> {
|
|
@@ -164,7 +164,6 @@ export async function update(
|
|
|
164
164
|
.updateTable('zone_delegations')
|
|
165
165
|
.set({
|
|
166
166
|
...(patch.accountsAll === undefined ? {} : { accountsAll: patch.accountsAll }),
|
|
167
|
-
...(patch.projects === undefined ? {} : { projects: JSON.stringify(patch.projects) }),
|
|
168
167
|
...(patch.tokensAll === undefined ? {} : { tokensAll: patch.tokensAll }),
|
|
169
168
|
updatedAt: new Date().toISOString(),
|
|
170
169
|
})
|
|
@@ -180,8 +179,6 @@ export declare namespace update {
|
|
|
180
179
|
type Patch = {
|
|
181
180
|
/** Whether every account is covered. */
|
|
182
181
|
accountsAll?: boolean | undefined
|
|
183
|
-
/** Covered projects (`all` or a list of ids). */
|
|
184
|
-
projects?: ZoneDelegation.Selection | undefined
|
|
185
182
|
/** Whether every token is covered. */
|
|
186
183
|
tokensAll?: boolean | undefined
|
|
187
184
|
}
|
|
@@ -217,6 +214,25 @@ export namespace Members {
|
|
|
217
214
|
})
|
|
218
215
|
}
|
|
219
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Adds members only while the list's flag is `all`, so the add changes no live
|
|
219
|
+
* access; `widens` when the list is enforced. The row stays locked through the
|
|
220
|
+
* insert, so a concurrent narrowing cannot turn the add into a widening.
|
|
221
|
+
*/
|
|
222
|
+
export function addInert(
|
|
223
|
+
db: Db.Db,
|
|
224
|
+
options: Options,
|
|
225
|
+
): Promise<Mutation<readonly Member[]> | { status: 'widens' }> {
|
|
226
|
+
return db.transaction(async (tx) => {
|
|
227
|
+
const now = new Date().toISOString()
|
|
228
|
+
const claimed = await claim(tx, options.id, now)
|
|
229
|
+
if (claimed.status !== 'ok') return claimed
|
|
230
|
+
if (!claimed.all[options.kind]) return { status: 'widens' } as const
|
|
231
|
+
const data = await insertMembers(tx, { ...options, now })
|
|
232
|
+
return { all: true, data, status: 'ok' }
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
220
236
|
/** Removes active members and returns the addresses removed. */
|
|
221
237
|
export function remove(db: Db.Db, options: Options): Promise<Mutation<readonly string[]>> {
|
|
222
238
|
return db.transaction(async (tx) => {
|
|
@@ -370,7 +386,8 @@ function storage(input: ensure.Input, now: string) {
|
|
|
370
386
|
environment: input.environment,
|
|
371
387
|
id: Id.generate('zd'),
|
|
372
388
|
orgId: input.orgId,
|
|
373
|
-
|
|
389
|
+
// The column stays NOT NULL until a later cleanup drops it; every row covers every project.
|
|
390
|
+
projects: JSON.stringify('all'),
|
|
374
391
|
revokedAt: null,
|
|
375
392
|
tokensAll: input.tokensAll,
|
|
376
393
|
updatedAt: now,
|
|
@@ -378,7 +395,7 @@ function storage(input: ensure.Input, now: string) {
|
|
|
378
395
|
}
|
|
379
396
|
|
|
380
397
|
function domain(row: Selectable<Table>): Record {
|
|
381
|
-
const { revokedAt, ...rest } = row
|
|
398
|
+
const { projects: _projects, revokedAt, ...rest } = row
|
|
382
399
|
return {
|
|
383
400
|
...rest,
|
|
384
401
|
chainId: Number(row.chainId),
|