tapimo 0.11.0 → 0.13.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/dist/App.d.ts +6396 -4575
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +39 -4
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +15 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +7 -0
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +176 -78
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +84 -4
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +123 -9
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +60 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +4 -2
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +90 -90
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +71 -71
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +16 -16
- package/dist/apps/Zones.js +4 -4
- package/dist/apps/data/App.d.ts +1699 -749
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +58 -9
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +62 -0
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
- package/dist/apps/data/ZoneSelection.js +44 -0
- package/dist/apps/data/ZoneSelection.js.map +1 -0
- package/dist/apps/data/routes/activities.d.ts +2417 -50
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1896 -1293
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +471 -340
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +12 -12
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +44 -17
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +42 -42
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +22 -12
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +179 -179
- package/dist/apps/data/routes/earn.d.ts +144 -19
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +160 -28
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +719 -13
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +16 -13
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +9 -11
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +34 -34
- package/dist/apps/data/routes/receipts.d.ts +363 -263
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +29 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.js +24 -10
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +16 -15
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +112 -98
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +85 -35
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +38 -18
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +25 -21
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
- package/dist/apps/data/routes/webhooks.d.ts +15 -15
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +2 -2
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +32 -32
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +38 -27
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.js +5 -4
- package/dist/apps/funding/routes/chains.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +24 -19
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/providers.d.ts +13 -13
- package/dist/apps/funding/routes/providers.d.ts.map +1 -1
- package/dist/apps/funding/routes/providers.js +3 -2
- package/dist/apps/funding/routes/providers.js.map +1 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
- package/dist/apps/funding/routes/quotes.js +2 -2
- package/dist/apps/funding/routes/quotes.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +60 -48
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +27 -19
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +4558 -3700
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +19 -6
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +786 -175
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +312 -34
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +103 -30
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +91 -32
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/faucet.d.ts.map +1 -1
- package/dist/apps/management/routes/faucet.js +23 -12
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +46 -13
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +79 -29
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +120 -75
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +100 -41
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +5 -5
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +14 -10
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +99 -78
- package/dist/apps/management/routes/members.d.ts.map +1 -1
- package/dist/apps/management/routes/members.js +37 -18
- package/dist/apps/management/routes/members.js.map +1 -1
- package/dist/apps/management/routes/orgs.d.ts +48 -8
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +48 -19
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +108 -46
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +72 -21
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/scopes.d.ts.map +1 -1
- package/dist/apps/management/routes/scopes.js +8 -5
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +82 -82
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +41 -31
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +35 -7
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +36 -17
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +200 -183
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +80 -35
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +12 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +52 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +26 -3
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +24 -5
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +5 -0
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
- package/dist/db/tables/webhookDeliveries.js +10 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -1
- package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
- package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
- package/dist/db/tables/webhookQueueCompletions.js +32 -0
- package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
- package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +68 -47
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +29 -5
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +19 -6
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +11 -7
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +43 -4
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +167 -0
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +3 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +30 -24
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +140 -41
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +14 -9
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +16 -5
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +11 -10
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +14 -9
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +28 -6
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +121 -25
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +2 -0
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +23 -6
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +29 -12
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +37 -20
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/Deposit.d.ts +2 -2
- package/dist/internal/funding/Deposit.d.ts.map +1 -1
- package/dist/internal/funding/Deposit.js +9 -8
- package/dist/internal/funding/Deposit.js.map +1 -1
- package/dist/internal/funding/DepositAddress.d.ts +4 -4
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
- package/dist/internal/funding/DepositAddress.js +9 -8
- package/dist/internal/funding/DepositAddress.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +68 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +42 -20
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +13 -12
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +23 -21
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +38 -0
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
- package/dist/internal/funding/providers/stargate.js +277 -0
- package/dist/internal/funding/providers/stargate.js.map +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +3 -3
- package/src/App.test.ts +148 -0
- package/src/App.ts +45 -4
- package/src/Assets.test.ts +18 -0
- package/src/Assets.ts +22 -0
- package/src/Client.test-d.ts +311 -16
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +143 -0
- package/src/admin/apps/earn-vaults.ts +84 -7
- package/src/admin/apps/organizations.ts +6 -2
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/routes/api-keys.tsx +125 -2
- package/src/admin/ui.generated.ts +71 -71
- package/src/apps/Zones.test.ts +4 -4
- package/src/apps/Zones.ts +4 -4
- package/src/apps/composition.test.ts +1 -1
- package/src/apps/data/App.test.ts +72 -0
- package/src/apps/data/App.ts +58 -10
- package/src/apps/data/ZoneSelection.test.ts +196 -0
- package/src/apps/data/ZoneSelection.ts +108 -0
- package/src/apps/data/routes/activities.test.ts +1843 -2
- package/src/apps/data/routes/activities.ts +2211 -1388
- package/src/apps/data/routes/balances.ts +134 -98
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +36 -17
- package/src/apps/data/routes/earn.test.ts +187 -25
- package/src/apps/data/routes/earn.ts +228 -32
- package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
- package/src/apps/data/routes/exchanges.test.ts +31 -1
- package/src/apps/data/routes/exchanges.ts +19 -15
- package/src/apps/data/routes/fee-amm.ts +18 -11
- package/src/apps/data/routes/receipts.ts +48 -17
- package/src/apps/data/routes/rpc.test.ts +75 -0
- package/src/apps/data/routes/rpc.ts +23 -9
- package/src/apps/data/routes/tokenlist.ts +21 -18
- package/src/apps/data/routes/tokens.test.ts +607 -0
- package/src/apps/data/routes/tokens.ts +312 -231
- package/src/apps/data/routes/transactions.ts +69 -30
- package/src/apps/data/routes/transfers.test.ts +424 -3
- package/src/apps/data/routes/transfers.ts +57 -36
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/webhooks.ts +6 -2
- package/src/apps/data/routes/zones.test.ts +21 -15
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/chains.test.ts +211 -7
- package/src/apps/funding/routes/chains.ts +19 -12
- package/src/apps/funding/routes/deposit-addresses.test.ts +416 -0
- package/src/apps/funding/routes/deposit-addresses.ts +101 -84
- package/src/apps/funding/routes/providers.ts +9 -5
- package/src/apps/funding/routes/quotes.test.ts +42 -0
- package/src/apps/funding/routes/quotes.ts +8 -5
- package/src/apps/funding/routes/transfers.test.ts +430 -40
- package/src/apps/funding/routes/transfers.ts +76 -59
- package/src/apps/management/Billing.test.ts +26 -0
- package/src/apps/management/Billing.ts +24 -7
- package/src/apps/management/routes/api-keys.test.ts +398 -0
- package/src/apps/management/routes/api-keys.ts +481 -145
- package/src/apps/management/routes/billing.test.ts +209 -0
- package/src/apps/management/routes/billing.ts +254 -177
- package/src/apps/management/routes/faucet.test.ts +39 -0
- package/src/apps/management/routes/faucet.ts +75 -41
- package/src/apps/management/routes/invitations.test.ts +216 -0
- package/src/apps/management/routes/invitations.ts +186 -109
- package/src/apps/management/routes/invite-links.test.ts +263 -1
- package/src/apps/management/routes/invite-links.ts +295 -214
- package/src/apps/management/routes/me.test.ts +49 -0
- package/src/apps/management/routes/me.ts +42 -32
- package/src/apps/management/routes/members.test.ts +124 -1
- package/src/apps/management/routes/members.ts +81 -51
- package/src/apps/management/routes/orgs.test.ts +176 -0
- package/src/apps/management/routes/orgs.ts +101 -59
- package/src/apps/management/routes/projects.test.ts +183 -0
- package/src/apps/management/routes/projects.ts +124 -60
- package/src/apps/management/routes/scopes.test.ts +44 -0
- package/src/apps/management/routes/scopes.ts +37 -28
- package/src/apps/management/routes/usage.test.ts +92 -0
- package/src/apps/management/routes/usage.ts +186 -151
- package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
- package/src/apps/management/routes/verified-token-requests.ts +166 -133
- package/src/apps/management/routes/webhooks.test.ts +234 -0
- package/src/apps/management/routes/webhooks.ts +191 -78
- package/src/apps/mpp/internal/Adapter.ts +13 -1
- package/src/db/Db.test.ts +41 -0
- package/src/db/Db.ts +75 -1
- package/src/db/Schema.ts +33 -5
- package/src/db/tables/earnVaults.test.ts +22 -0
- package/src/db/tables/earnVaults.ts +11 -1
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/db/tables/webhookDeliveries.ts +13 -0
- package/src/db/tables/webhookQueueCompletions.ts +55 -0
- package/src/db/tables/webhookQueueEvents.ts +95 -61
- package/src/db/tables/webhookSubscriptions.ts +45 -6
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +35 -9
- package/src/internal/Cache.ts +14 -7
- package/src/internal/EarnVaults.capabilities.test.ts +33 -0
- package/src/internal/EarnVaults.test.ts +79 -0
- package/src/internal/EarnVaults.ts +277 -0
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +20 -5
- package/src/internal/OpenApi.ts +177 -51
- package/src/internal/Response.test.ts +95 -0
- package/src/internal/Response.ts +41 -3
- package/src/internal/Schema.test.ts +18 -0
- package/src/internal/Schema.ts +19 -9
- package/src/internal/Store.test.ts +364 -0
- package/src/internal/Store.ts +153 -27
- package/src/internal/Tidx.test.ts +21 -1
- package/src/internal/Tidx.ts +23 -6
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/Webhooks.test.ts +122 -8
- package/src/internal/Webhooks.ts +59 -29
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/Deposit.ts +71 -64
- package/src/internal/funding/DepositAddress.ts +50 -43
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +246 -170
- package/src/internal/funding/Transfer.ts +133 -110
- package/src/internal/funding/providers/index.test.ts +22 -0
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/stargate.test.ts +163 -0
- package/src/internal/funding/providers/stargate.ts +409 -0
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/providers/index.test.ts +1 -0
- package/src/providers/index.ts +9 -0
|
@@ -12,82 +12,86 @@ import * as Billing from '../Billing.js'
|
|
|
12
12
|
import * as OpenApi from '../../../internal/OpenApi.js'
|
|
13
13
|
import * as Response from '../../../internal/Response.js'
|
|
14
14
|
import * as Schema from '../../../internal/Schema.js'
|
|
15
|
+
import * as Store from '../../../internal/Store.js'
|
|
15
16
|
import * as Scope from '../../../Scope.js'
|
|
16
17
|
import * as ManagementError from '../Error.js'
|
|
17
18
|
|
|
18
19
|
/** Zod schemas owned by the API-keys resource. */
|
|
19
20
|
export namespace schema {
|
|
20
21
|
/** One API key: metadata only — the token appears once, at mint. */
|
|
21
|
-
export const Key =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'Client IP addresses and CIDR ranges allowed to use this key. An empty list means unrestricted.',
|
|
26
|
-
),
|
|
27
|
-
z.meta({ examples: [['203.0.113.0/24', '2001:db8::1']] }),
|
|
28
|
-
),
|
|
29
|
-
createdAt: z
|
|
30
|
-
.string()
|
|
31
|
-
.check(
|
|
32
|
-
z.describe('When the key was minted (ISO 8601).'),
|
|
33
|
-
z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
|
|
34
|
-
),
|
|
35
|
-
createdBy: z
|
|
36
|
-
.optional(z.string())
|
|
37
|
-
.check(
|
|
38
|
-
z.describe('Identity that minted the key (`usr_…`, or `super_admin`).'),
|
|
39
|
-
z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
40
|
-
),
|
|
41
|
-
environment: z
|
|
42
|
-
.enum(['production', 'sandbox'])
|
|
43
|
-
.check(z.describe('Key environment.'), z.meta({ examples: ['sandbox'] })),
|
|
44
|
-
expiresAt: z
|
|
45
|
-
.optional(z.string())
|
|
46
|
-
.check(
|
|
47
|
-
z.describe('When the key expires (ISO 8601). Absent for a non-expiring key.'),
|
|
48
|
-
z.meta({ examples: ['2027-01-01T00:00:00.000Z'] }),
|
|
49
|
-
),
|
|
50
|
-
id: z
|
|
51
|
-
.string()
|
|
52
|
-
.check(
|
|
53
|
-
z.describe('Opaque key id (`key_…`).'),
|
|
54
|
-
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
55
|
-
),
|
|
56
|
-
lastUsedAt: z
|
|
57
|
-
.optional(z.string())
|
|
58
|
-
.check(
|
|
59
|
-
z.describe('When the key last authenticated a request (ISO 8601).'),
|
|
60
|
-
z.meta({ examples: ['2026-07-21T12:34:56.000Z'] }),
|
|
61
|
-
),
|
|
62
|
-
name: z
|
|
63
|
-
.optional(z.string())
|
|
64
|
-
.check(z.describe('Human-readable key name.'), z.meta({ examples: ['CI'] })),
|
|
65
|
-
orgId: z
|
|
66
|
-
.string()
|
|
67
|
-
.check(
|
|
68
|
-
z.describe('Owning organization id (`org_…`).'),
|
|
69
|
-
z.meta({ examples: ['org_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
70
|
-
),
|
|
71
|
-
projectId: z.optional(z.string()).check(
|
|
72
|
-
z.describe('Attributed project id (`prj_…`).'), // prettier-ignore
|
|
73
|
-
z.meta({ examples: ['prj_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
74
|
-
),
|
|
75
|
-
scopes: z
|
|
76
|
-
.array(z.string().check(z.minLength(1)))
|
|
77
|
-
.check(
|
|
22
|
+
export const Key = OpenApi.component(
|
|
23
|
+
Schema.describe(
|
|
24
|
+
z.object({
|
|
25
|
+
allowedIps: ApiKey.schema.AllowedIps.check(
|
|
78
26
|
z.describe(
|
|
79
|
-
|
|
27
|
+
'Client IP addresses and CIDR ranges allowed to use this key. An empty list means unrestricted.',
|
|
80
28
|
),
|
|
81
|
-
z.meta({ examples: [['
|
|
29
|
+
z.meta({ examples: [['203.0.113.0/24', '2001:db8::1']] }),
|
|
82
30
|
),
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
31
|
+
createdAt: z.iso
|
|
32
|
+
.datetime()
|
|
33
|
+
.check(
|
|
34
|
+
z.describe('When the key was minted (ISO 8601).'),
|
|
35
|
+
z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
|
|
36
|
+
),
|
|
37
|
+
createdBy: z
|
|
38
|
+
.optional(z.string())
|
|
39
|
+
.check(
|
|
40
|
+
z.describe('Identity that minted the key (`usr_…`, or `super_admin`).'),
|
|
41
|
+
z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
42
|
+
),
|
|
43
|
+
environment: z
|
|
44
|
+
.enum(['production', 'sandbox'])
|
|
45
|
+
.check(z.describe('Key environment.'), z.meta({ examples: ['sandbox'] })),
|
|
46
|
+
expiresAt: z
|
|
47
|
+
.optional(z.iso.datetime())
|
|
48
|
+
.check(
|
|
49
|
+
z.describe('When the key expires (ISO 8601). Absent for a non-expiring key.'),
|
|
50
|
+
z.meta({ examples: ['2027-01-01T00:00:00.000Z'] }),
|
|
51
|
+
),
|
|
52
|
+
id: z
|
|
53
|
+
.string()
|
|
54
|
+
.check(
|
|
55
|
+
z.describe('Opaque key id (`key_…`).'),
|
|
56
|
+
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
57
|
+
),
|
|
58
|
+
lastUsedAt: z
|
|
59
|
+
.optional(z.iso.datetime())
|
|
60
|
+
.check(
|
|
61
|
+
z.describe('When the key last authenticated a request (ISO 8601).'),
|
|
62
|
+
z.meta({ examples: ['2026-07-21T12:34:56.000Z'] }),
|
|
63
|
+
),
|
|
64
|
+
name: z
|
|
65
|
+
.optional(z.string())
|
|
66
|
+
.check(z.describe('Human-readable key name.'), z.meta({ examples: ['CI'] })),
|
|
67
|
+
orgId: z
|
|
68
|
+
.string()
|
|
69
|
+
.check(
|
|
70
|
+
z.describe('Owning organization id (`org_…`).'),
|
|
71
|
+
z.meta({ examples: ['org_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
72
|
+
),
|
|
73
|
+
projectId: z.optional(z.string()).check(
|
|
74
|
+
z.describe('Attributed project id (`prj_…`).'), // prettier-ignore
|
|
75
|
+
z.meta({ examples: ['prj_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
88
76
|
),
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
scopes: z
|
|
78
|
+
.array(z.string().check(z.minLength(1)))
|
|
79
|
+
.check(
|
|
80
|
+
z.describe(
|
|
81
|
+
"Granted scopes. '*' and non-self-serve scopes appear only on keys minted by the super admin.",
|
|
82
|
+
),
|
|
83
|
+
z.meta({ examples: [['data:read']] }),
|
|
84
|
+
),
|
|
85
|
+
tokenLast4: z
|
|
86
|
+
.string()
|
|
87
|
+
.check(
|
|
88
|
+
z.describe('Last 4 characters of the plaintext token.'),
|
|
89
|
+
z.meta({ examples: ['a1b2'] }),
|
|
90
|
+
),
|
|
91
|
+
}),
|
|
92
|
+
'An API key: metadata only — the token appears once, at mint.',
|
|
93
|
+
),
|
|
94
|
+
'ApiKey',
|
|
91
95
|
)
|
|
92
96
|
|
|
93
97
|
/** Path parameters addressing a project's key collection. */
|
|
@@ -144,53 +148,88 @@ export namespace schema {
|
|
|
144
148
|
})
|
|
145
149
|
.check(z.describe('Path parameters for one API key.'))
|
|
146
150
|
|
|
147
|
-
/**
|
|
148
|
-
export const
|
|
151
|
+
/** Path parameters addressing one organization-level API key. */
|
|
152
|
+
export const OrgKeyParams = z
|
|
149
153
|
.object({
|
|
150
|
-
|
|
151
|
-
.
|
|
154
|
+
keyId: z
|
|
155
|
+
.string()
|
|
152
156
|
.check(
|
|
153
|
-
z.describe(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
z.describe('The key id (`key_…`).'),
|
|
158
|
+
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
159
|
+
),
|
|
160
|
+
orgId: z
|
|
161
|
+
.string()
|
|
162
|
+
.check(
|
|
163
|
+
z.describe('The organization id (`org_…`).'),
|
|
164
|
+
z.meta({ examples: ['org_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
157
165
|
),
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
})
|
|
167
|
+
.check(z.describe('Path parameters for one organization-level API key.'))
|
|
168
|
+
|
|
169
|
+
/** Request body minting a key. The wildcard scope is not issuable here. */
|
|
170
|
+
export const CreateApiKeyRequest = OpenApi.component(
|
|
171
|
+
z
|
|
172
|
+
.object({
|
|
173
|
+
allowedIps: z
|
|
174
|
+
.optional(ApiKey.schema.AllowedIps)
|
|
175
|
+
.check(
|
|
176
|
+
z.describe(
|
|
177
|
+
'Client IP addresses and CIDR ranges allowed to use the key. Omit or use an empty list for unrestricted access.',
|
|
170
178
|
),
|
|
179
|
+
z.meta({ examples: [['203.0.113.0/24']] }),
|
|
171
180
|
),
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
environment: z
|
|
182
|
+
._default(z.enum(['production', 'sandbox']), 'production')
|
|
183
|
+
.check(z.describe('Key environment.'), z.meta({ examples: ['sandbox'] })),
|
|
184
|
+
name: z
|
|
185
|
+
.optional(z.string().check(z.minLength(1), z.maxLength(100)))
|
|
186
|
+
.check(z.describe('Human-readable key name.'), z.meta({ examples: ['CI'] })),
|
|
187
|
+
scopes: z
|
|
188
|
+
._default(
|
|
189
|
+
z.array(
|
|
190
|
+
z.string().check(
|
|
191
|
+
z.minLength(1),
|
|
192
|
+
z.refine((scope) => scope !== Scope.wildcard),
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
[],
|
|
196
|
+
)
|
|
197
|
+
.check(z.describe('Scopes to grant.'), z.meta({ examples: [['data:read']] })),
|
|
198
|
+
})
|
|
199
|
+
.check(z.describe('Fields for minting an API key.')),
|
|
200
|
+
'CreateApiKeyRequest',
|
|
201
|
+
)
|
|
177
202
|
|
|
178
203
|
/** Schemas for the createApiKey operation. */
|
|
179
204
|
export namespace createApiKey {
|
|
180
205
|
/** The minted key plus its one-time token. */
|
|
181
|
-
export const Response =
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
206
|
+
export const Response = OpenApi.component(
|
|
207
|
+
Schema.describe(
|
|
208
|
+
z.extend(Key, {
|
|
209
|
+
token: z
|
|
210
|
+
.string()
|
|
211
|
+
.check(
|
|
212
|
+
z.describe('The plaintext token — shown once, unrecoverable afterward.'),
|
|
213
|
+
z.meta({ examples: ['tempo_sandbox:sk:…'] }),
|
|
214
|
+
),
|
|
215
|
+
}),
|
|
216
|
+
'The minted key, including its one-time token.',
|
|
217
|
+
),
|
|
218
|
+
'CreateApiKeyResponse',
|
|
191
219
|
)
|
|
192
220
|
}
|
|
193
221
|
|
|
222
|
+
/** Non-paginated list of API key metadata. */
|
|
223
|
+
export const ApiKeyList = OpenApi.component(
|
|
224
|
+
Schema.describe(
|
|
225
|
+
z.object({
|
|
226
|
+
data: z.array(Key).check(z.describe('The API keys, newest first.')),
|
|
227
|
+
}),
|
|
228
|
+
'A non-paginated list of API key metadata.',
|
|
229
|
+
),
|
|
230
|
+
'ApiKeyList',
|
|
231
|
+
)
|
|
232
|
+
|
|
194
233
|
/** Schemas for the listApiKeys operation. */
|
|
195
234
|
export namespace listApiKeys {
|
|
196
235
|
/** Query parameters filtering a project's keys. */
|
|
@@ -199,12 +238,7 @@ export namespace schema {
|
|
|
199
238
|
.check(z.describe("Query parameters for a project's API keys."))
|
|
200
239
|
|
|
201
240
|
/** Non-paginated list of a project's keys. */
|
|
202
|
-
export const Response =
|
|
203
|
-
z.object({
|
|
204
|
-
data: z.array(Key).check(z.describe("The project's keys, newest first.")),
|
|
205
|
-
}),
|
|
206
|
-
"A non-paginated list of a project's API keys (metadata only).",
|
|
207
|
-
)
|
|
241
|
+
export const Response = ApiKeyList
|
|
208
242
|
}
|
|
209
243
|
|
|
210
244
|
/** Schemas for the listOrgApiKeys operation. */
|
|
@@ -215,44 +249,62 @@ export namespace schema {
|
|
|
215
249
|
.check(z.describe("Query parameters for an organization's API keys."))
|
|
216
250
|
|
|
217
251
|
/** Non-paginated list of every key in the organization. */
|
|
218
|
-
export const Response =
|
|
219
|
-
z.object({
|
|
220
|
-
data: z
|
|
221
|
-
.array(Key)
|
|
222
|
-
.check(z.describe("The organization's keys across all projects, newest first.")),
|
|
223
|
-
}),
|
|
224
|
-
"A non-paginated list of an organization's API keys (metadata only).",
|
|
225
|
-
)
|
|
252
|
+
export const Response = ApiKeyList
|
|
226
253
|
}
|
|
227
254
|
|
|
228
255
|
/** Schemas for the revokeApiKey operation. */
|
|
229
256
|
export namespace revokeApiKey {
|
|
230
257
|
/** Confirmation that the key was revoked. */
|
|
231
|
-
export const Response =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
258
|
+
export const Response = OpenApi.component(
|
|
259
|
+
z
|
|
260
|
+
.object({
|
|
261
|
+
id: z
|
|
262
|
+
.string()
|
|
263
|
+
.check(
|
|
264
|
+
z.describe('ID of the key that was revoked.'),
|
|
265
|
+
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
266
|
+
),
|
|
267
|
+
})
|
|
268
|
+
.check(z.describe('Confirmation that the key was revoked.')),
|
|
269
|
+
'RevokeApiKeyResponse',
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** Schemas for the rotateApiKey operation. */
|
|
274
|
+
export namespace rotateApiKey {
|
|
275
|
+
/** The replacement key plus its one-time token. */
|
|
276
|
+
export const Response = OpenApi.component(
|
|
277
|
+
Schema.describe(
|
|
278
|
+
z.extend(Key, {
|
|
279
|
+
token: z
|
|
280
|
+
.string()
|
|
281
|
+
.check(
|
|
282
|
+
z.describe('The plaintext token — shown once, unrecoverable afterward.'),
|
|
283
|
+
z.meta({ examples: ['tempo_sandbox:sk:…'] }),
|
|
284
|
+
),
|
|
285
|
+
}),
|
|
286
|
+
'The replacement key, including its one-time token.',
|
|
287
|
+
),
|
|
288
|
+
'RotateApiKeyResponse',
|
|
289
|
+
)
|
|
241
290
|
}
|
|
242
291
|
|
|
243
292
|
/** Schemas for the updateApiKey operation. */
|
|
244
293
|
export namespace updateApiKey {
|
|
245
294
|
/** Request body replacing or clearing a key's IP allowlist. */
|
|
246
|
-
export const Body =
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
295
|
+
export const Body = OpenApi.component(
|
|
296
|
+
z
|
|
297
|
+
.object({
|
|
298
|
+
allowedIps: ApiKey.schema.AllowedIps.check(
|
|
299
|
+
z.describe(
|
|
300
|
+
'Replacement client IP/CIDR allowlist. Use an empty list for unrestricted access.',
|
|
301
|
+
),
|
|
302
|
+
z.meta({ examples: [['203.0.113.0/24']] }),
|
|
251
303
|
),
|
|
252
|
-
|
|
253
|
-
),
|
|
254
|
-
|
|
255
|
-
|
|
304
|
+
})
|
|
305
|
+
.check(z.describe("Fields for updating an API key's network access.")),
|
|
306
|
+
'UpdateApiKeyRequest',
|
|
307
|
+
)
|
|
256
308
|
}
|
|
257
309
|
}
|
|
258
310
|
|
|
@@ -271,7 +323,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
271
323
|
code: 'param_invalid',
|
|
272
324
|
message: 'Check the path parameters and try again.',
|
|
273
325
|
}),
|
|
274
|
-
OpenApi.validate('json', schema.
|
|
326
|
+
OpenApi.validate('json', schema.CreateApiKeyRequest, {
|
|
275
327
|
code: 'body_invalid',
|
|
276
328
|
message: 'Check the request body and try again.',
|
|
277
329
|
}),
|
|
@@ -281,11 +333,18 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
281
333
|
operationId: 'createApiKey',
|
|
282
334
|
responses: OpenApi.responses({
|
|
283
335
|
errors: {
|
|
336
|
+
400: {
|
|
337
|
+
codes: ['body_invalid', 'param_invalid'],
|
|
338
|
+
description: 'Malformed API key, invalid path, or invalid body.',
|
|
339
|
+
},
|
|
284
340
|
403: {
|
|
285
341
|
codes: ['scope_not_issuable'],
|
|
286
342
|
description: 'The requested scopes are not issuable.',
|
|
287
343
|
},
|
|
288
|
-
404:
|
|
344
|
+
404: {
|
|
345
|
+
codes: ['api_keys_not_enabled', 'organization_not_found', 'project_not_found'],
|
|
346
|
+
description: 'No accessible project or API key surface was found.',
|
|
347
|
+
},
|
|
289
348
|
},
|
|
290
349
|
success: {
|
|
291
350
|
description: 'The minted key, including its one-time token.',
|
|
@@ -298,6 +357,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
298
357
|
async (c) => {
|
|
299
358
|
if (Auth.narrowAccess) return Auth.superAdminAccessError(c)
|
|
300
359
|
if (Auth.narrowScope) return Auth.ensureProjectError(c)
|
|
360
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
301
361
|
if (OpenApi.narrowValidation)
|
|
302
362
|
return OpenApi.validationError(c, {
|
|
303
363
|
code: 'param_invalid',
|
|
@@ -379,8 +439,14 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
379
439
|
operationId: 'listApiKeys',
|
|
380
440
|
responses: OpenApi.responses({
|
|
381
441
|
errors: {
|
|
382
|
-
400: {
|
|
383
|
-
|
|
442
|
+
400: {
|
|
443
|
+
codes: ['param_invalid', 'query_invalid'],
|
|
444
|
+
description: 'Malformed API key, invalid path, or invalid query.',
|
|
445
|
+
},
|
|
446
|
+
404: {
|
|
447
|
+
codes: ['api_keys_not_enabled', 'organization_not_found', 'project_not_found'],
|
|
448
|
+
description: 'No accessible project or API key surface was found.',
|
|
449
|
+
},
|
|
384
450
|
},
|
|
385
451
|
success: {
|
|
386
452
|
description: "The project's keys, newest first (metadata only).",
|
|
@@ -441,8 +507,14 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
441
507
|
operationId: 'listOrgApiKeys',
|
|
442
508
|
responses: OpenApi.responses({
|
|
443
509
|
errors: {
|
|
444
|
-
400: {
|
|
445
|
-
|
|
510
|
+
400: {
|
|
511
|
+
codes: ['param_invalid', 'query_invalid'],
|
|
512
|
+
description: 'Malformed API key, invalid path, or invalid query.',
|
|
513
|
+
},
|
|
514
|
+
404: {
|
|
515
|
+
codes: ['api_keys_not_enabled', 'organization_not_found'],
|
|
516
|
+
description: 'No accessible organization or API key surface was found.',
|
|
517
|
+
},
|
|
446
518
|
},
|
|
447
519
|
success: {
|
|
448
520
|
description: "The organization's keys across all projects, newest first (metadata only).", // prettier-ignore
|
|
@@ -484,6 +556,124 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
484
556
|
}
|
|
485
557
|
},
|
|
486
558
|
)
|
|
559
|
+
.post(
|
|
560
|
+
'/v1/orgs/:orgId{org_[A-Za-z0-9_-]+}/api-keys/:keyId{key_[A-Za-z0-9_-]+}/rotate',
|
|
561
|
+
Auth.policy({ session: true }),
|
|
562
|
+
Auth.ensureOrg({ role: 'admin' }),
|
|
563
|
+
OpenApi.validate('param', schema.OrgKeyParams, {
|
|
564
|
+
code: 'param_invalid',
|
|
565
|
+
message: 'Check the path parameters and try again.',
|
|
566
|
+
}),
|
|
567
|
+
OpenApi.describeRoute({
|
|
568
|
+
description:
|
|
569
|
+
'Create a replacement organization-level API key with the same access as an existing key. The existing key remains active until revoked.',
|
|
570
|
+
hide: hidden,
|
|
571
|
+
operationId: 'rotateOrgApiKey',
|
|
572
|
+
responses: OpenApi.responses({
|
|
573
|
+
errors: {
|
|
574
|
+
400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
|
|
575
|
+
403: {
|
|
576
|
+
codes: ['scope_not_issuable'],
|
|
577
|
+
description: 'The source key contains scopes the caller cannot rotate.',
|
|
578
|
+
},
|
|
579
|
+
404: {
|
|
580
|
+
codes: ['api_key_not_found', 'api_keys_not_enabled', 'organization_not_found'],
|
|
581
|
+
description: 'No accessible API key or API key surface was found.',
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
success: {
|
|
585
|
+
description: 'The replacement key, including its one-time token.',
|
|
586
|
+
schema: schema.rotateApiKey.Response,
|
|
587
|
+
},
|
|
588
|
+
}),
|
|
589
|
+
summary: 'Rotate organization API key',
|
|
590
|
+
tags: ['API Keys'],
|
|
591
|
+
}),
|
|
592
|
+
async (c) => {
|
|
593
|
+
if (Auth.narrowAccess) return Auth.superAdminAccessError(c)
|
|
594
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
595
|
+
if (OpenApi.narrowValidation)
|
|
596
|
+
return OpenApi.validationError(c, {
|
|
597
|
+
code: 'param_invalid',
|
|
598
|
+
message: 'Check the path parameters and try again.',
|
|
599
|
+
})
|
|
600
|
+
|
|
601
|
+
const kv = c.get('kv')
|
|
602
|
+
if (!kv) return notEnabled(c)
|
|
603
|
+
const createdBy = mintedBy(c)
|
|
604
|
+
if (!createdBy) return ManagementError.sessionRequired(c)
|
|
605
|
+
const { keyId } = c.req.valid('param')
|
|
606
|
+
try {
|
|
607
|
+
const source = await ApiKeys.get(kv.store, keyId, {
|
|
608
|
+
scopeCatalog: c.get('scopeCatalog'),
|
|
609
|
+
})
|
|
610
|
+
if (!source || source.orgId !== Auth.org(c).id || source.projectId !== undefined)
|
|
611
|
+
return keyNotFound(c)
|
|
612
|
+
if (!canRotate(c, source.scopes))
|
|
613
|
+
return Response.error(c, {
|
|
614
|
+
code: 'scope_not_issuable',
|
|
615
|
+
message: 'The source key contains scopes the caller cannot rotate.',
|
|
616
|
+
status: 403,
|
|
617
|
+
})
|
|
618
|
+
return rotate(c, kv.store, source, createdBy)
|
|
619
|
+
} catch (cause) {
|
|
620
|
+
return Response.upstream(c, cause)
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
)
|
|
624
|
+
.delete(
|
|
625
|
+
'/v1/orgs/:orgId{org_[A-Za-z0-9_-]+}/api-keys/:keyId{key_[A-Za-z0-9_-]+}',
|
|
626
|
+
Auth.policy({ apiKey: { scopes: ['management:write'] }, session: true }),
|
|
627
|
+
Auth.ensureOrg({ role: 'admin' }),
|
|
628
|
+
OpenApi.validate('param', schema.OrgKeyParams, {
|
|
629
|
+
code: 'param_invalid',
|
|
630
|
+
message: 'Check the path parameters and try again.',
|
|
631
|
+
}),
|
|
632
|
+
OpenApi.describeRoute({
|
|
633
|
+
description:
|
|
634
|
+
'Revoke an organization-level API key. Requests presenting its token stop resolving.',
|
|
635
|
+
hide: hidden,
|
|
636
|
+
operationId: 'revokeOrgApiKey',
|
|
637
|
+
responses: OpenApi.responses({
|
|
638
|
+
errors: {
|
|
639
|
+
400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
|
|
640
|
+
404: {
|
|
641
|
+
codes: ['api_key_not_found', 'api_keys_not_enabled', 'organization_not_found'],
|
|
642
|
+
description: 'No accessible API key or API key surface was found.',
|
|
643
|
+
},
|
|
644
|
+
},
|
|
645
|
+
success: {
|
|
646
|
+
description: 'Confirmation that the key was revoked.',
|
|
647
|
+
schema: schema.revokeApiKey.Response,
|
|
648
|
+
},
|
|
649
|
+
}),
|
|
650
|
+
summary: 'Revoke organization API key',
|
|
651
|
+
tags: ['API Keys'],
|
|
652
|
+
}),
|
|
653
|
+
async (c) => {
|
|
654
|
+
if (Auth.narrowAccess) return Auth.accessError(c)
|
|
655
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
656
|
+
if (OpenApi.narrowValidation)
|
|
657
|
+
return OpenApi.validationError(c, {
|
|
658
|
+
code: 'param_invalid',
|
|
659
|
+
message: 'Check the path parameters and try again.',
|
|
660
|
+
})
|
|
661
|
+
|
|
662
|
+
const kv = c.get('kv')
|
|
663
|
+
if (!kv) return notEnabled(c)
|
|
664
|
+
const { keyId } = c.req.valid('param')
|
|
665
|
+
try {
|
|
666
|
+
const record = await ApiKeys.get(kv.store, keyId, {
|
|
667
|
+
scopeCatalog: c.get('scopeCatalog'),
|
|
668
|
+
})
|
|
669
|
+
if (!record || record.orgId !== Auth.org(c).id || record.projectId !== undefined)
|
|
670
|
+
return keyNotFound(c)
|
|
671
|
+
return revoke(c, kv.store, keyId)
|
|
672
|
+
} catch (cause) {
|
|
673
|
+
return Response.upstream(c, cause)
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
)
|
|
487
677
|
.patch(
|
|
488
678
|
'/v1/orgs/:orgId{org_[A-Za-z0-9_-]+}/projects/:projectId{prj_[A-Za-z0-9_-]+}/api-keys/:keyId{key_[A-Za-z0-9_-]+}',
|
|
489
679
|
Auth.policy({ apiKey: { scopes: ['management:write'] }, session: true }),
|
|
@@ -504,7 +694,19 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
504
694
|
operationId: 'updateApiKey',
|
|
505
695
|
responses: OpenApi.responses({
|
|
506
696
|
errors: {
|
|
507
|
-
|
|
697
|
+
400: {
|
|
698
|
+
codes: ['body_invalid', 'param_invalid'],
|
|
699
|
+
description: 'Malformed API key, invalid path, or invalid body.',
|
|
700
|
+
},
|
|
701
|
+
404: {
|
|
702
|
+
codes: [
|
|
703
|
+
'api_key_not_found',
|
|
704
|
+
'api_keys_not_enabled',
|
|
705
|
+
'organization_not_found',
|
|
706
|
+
'project_not_found',
|
|
707
|
+
],
|
|
708
|
+
description: 'No accessible API key or API key surface was found.',
|
|
709
|
+
},
|
|
508
710
|
},
|
|
509
711
|
success: {
|
|
510
712
|
description: 'The updated API key metadata.',
|
|
@@ -517,6 +719,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
517
719
|
async (c) => {
|
|
518
720
|
if (Auth.narrowAccess) return Auth.accessError(c)
|
|
519
721
|
if (Auth.narrowScope) return Auth.ensureProjectError(c)
|
|
722
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
520
723
|
if (OpenApi.narrowValidation)
|
|
521
724
|
return OpenApi.validationError(c, {
|
|
522
725
|
code: 'param_invalid',
|
|
@@ -547,6 +750,78 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
547
750
|
}
|
|
548
751
|
},
|
|
549
752
|
)
|
|
753
|
+
.post(
|
|
754
|
+
'/v1/orgs/:orgId{org_[A-Za-z0-9_-]+}/projects/:projectId{prj_[A-Za-z0-9_-]+}/api-keys/:keyId{key_[A-Za-z0-9_-]+}/rotate',
|
|
755
|
+
Auth.policy({ session: true }),
|
|
756
|
+
Auth.ensureOrg({ role: 'admin' }),
|
|
757
|
+
Auth.ensureProject(),
|
|
758
|
+
OpenApi.validate('param', schema.KeyParams, {
|
|
759
|
+
code: 'param_invalid',
|
|
760
|
+
message: 'Check the path parameters and try again.',
|
|
761
|
+
}),
|
|
762
|
+
OpenApi.describeRoute({
|
|
763
|
+
description:
|
|
764
|
+
'Create a replacement API key with the same access as an existing key. The existing key remains active until revoked.',
|
|
765
|
+
hide: hidden,
|
|
766
|
+
operationId: 'rotateApiKey',
|
|
767
|
+
responses: OpenApi.responses({
|
|
768
|
+
errors: {
|
|
769
|
+
400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
|
|
770
|
+
403: {
|
|
771
|
+
codes: ['scope_not_issuable'],
|
|
772
|
+
description: 'The source key contains scopes the caller cannot rotate.',
|
|
773
|
+
},
|
|
774
|
+
404: {
|
|
775
|
+
codes: [
|
|
776
|
+
'api_key_not_found',
|
|
777
|
+
'api_keys_not_enabled',
|
|
778
|
+
'organization_not_found',
|
|
779
|
+
'project_not_found',
|
|
780
|
+
],
|
|
781
|
+
description: 'No accessible API key or API key surface was found.',
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
success: {
|
|
785
|
+
description: 'The replacement key, including its one-time token.',
|
|
786
|
+
schema: schema.rotateApiKey.Response,
|
|
787
|
+
},
|
|
788
|
+
}),
|
|
789
|
+
summary: 'Rotate API key',
|
|
790
|
+
tags: ['API Keys'],
|
|
791
|
+
}),
|
|
792
|
+
async (c) => {
|
|
793
|
+
if (Auth.narrowAccess) return Auth.superAdminAccessError(c)
|
|
794
|
+
if (Auth.narrowScope) return Auth.ensureProjectError(c)
|
|
795
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
796
|
+
if (OpenApi.narrowValidation)
|
|
797
|
+
return OpenApi.validationError(c, {
|
|
798
|
+
code: 'param_invalid',
|
|
799
|
+
message: 'Check the path parameters and try again.',
|
|
800
|
+
})
|
|
801
|
+
|
|
802
|
+
const kv = c.get('kv')
|
|
803
|
+
if (!kv) return notEnabled(c)
|
|
804
|
+
const createdBy = mintedBy(c)
|
|
805
|
+
if (!createdBy) return ManagementError.sessionRequired(c)
|
|
806
|
+
const { keyId } = c.req.valid('param')
|
|
807
|
+
try {
|
|
808
|
+
const source = await ApiKeys.get(kv.store, keyId, {
|
|
809
|
+
scopeCatalog: c.get('scopeCatalog'),
|
|
810
|
+
})
|
|
811
|
+
if (!source || source.orgId !== Auth.org(c).id || source.projectId !== Auth.project(c).id)
|
|
812
|
+
return keyNotFound(c)
|
|
813
|
+
if (!canRotate(c, source.scopes))
|
|
814
|
+
return Response.error(c, {
|
|
815
|
+
code: 'scope_not_issuable',
|
|
816
|
+
message: 'The source key contains scopes the caller cannot rotate.',
|
|
817
|
+
status: 403,
|
|
818
|
+
})
|
|
819
|
+
return rotate(c, kv.store, source, createdBy)
|
|
820
|
+
} catch (cause) {
|
|
821
|
+
return Response.upstream(c, cause)
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
)
|
|
550
825
|
.delete(
|
|
551
826
|
'/v1/orgs/:orgId{org_[A-Za-z0-9_-]+}/projects/:projectId{prj_[A-Za-z0-9_-]+}/api-keys/:keyId{key_[A-Za-z0-9_-]+}',
|
|
552
827
|
Auth.policy({ apiKey: { scopes: ['management:write'] }, session: true }),
|
|
@@ -561,7 +836,18 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
561
836
|
hide: hidden,
|
|
562
837
|
operationId: 'revokeApiKey',
|
|
563
838
|
responses: OpenApi.responses({
|
|
564
|
-
errors: {
|
|
839
|
+
errors: {
|
|
840
|
+
400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
|
|
841
|
+
404: {
|
|
842
|
+
codes: [
|
|
843
|
+
'api_key_not_found',
|
|
844
|
+
'api_keys_not_enabled',
|
|
845
|
+
'organization_not_found',
|
|
846
|
+
'project_not_found',
|
|
847
|
+
],
|
|
848
|
+
description: 'No accessible API key or API key surface was found.',
|
|
849
|
+
},
|
|
850
|
+
},
|
|
565
851
|
success: {
|
|
566
852
|
description: 'Confirmation that the key was revoked.',
|
|
567
853
|
schema: schema.revokeApiKey.Response,
|
|
@@ -573,6 +859,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
573
859
|
async (c) => {
|
|
574
860
|
if (Auth.narrowAccess) return Auth.accessError(c)
|
|
575
861
|
if (Auth.narrowScope) return Auth.ensureProjectError(c)
|
|
862
|
+
if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
|
|
576
863
|
if (OpenApi.narrowValidation)
|
|
577
864
|
return OpenApi.validationError(c, {
|
|
578
865
|
code: 'param_invalid',
|
|
@@ -590,9 +877,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
590
877
|
})
|
|
591
878
|
if (!record || record.orgId !== Auth.org(c).id || record.projectId !== Auth.project(c).id)
|
|
592
879
|
return keyNotFound(c)
|
|
593
|
-
|
|
594
|
-
if (!revoked) return keyNotFound(c)
|
|
595
|
-
return c.json(Response.validated(schema.revokeApiKey.Response, { id: keyId }), 200)
|
|
880
|
+
return revoke(c, kv.store, keyId)
|
|
596
881
|
} catch (cause) {
|
|
597
882
|
return Response.upstream(c, cause)
|
|
598
883
|
}
|
|
@@ -663,6 +948,57 @@ function canIssue(c: Context<App.Environment>, scopes: readonly Scope.Id[]) {
|
|
|
663
948
|
return false
|
|
664
949
|
}
|
|
665
950
|
|
|
951
|
+
/** Checks caller-specific restrictions that still apply when copying existing grants. */
|
|
952
|
+
function canRotate(c: Context<App.Environment>, scopes: readonly Scope.Id[]) {
|
|
953
|
+
const principal = Auth.getPrincipal(c)
|
|
954
|
+
if (principal?.type === 'super_admin') return true
|
|
955
|
+
if (principal?.type !== 'session') return false
|
|
956
|
+
return (
|
|
957
|
+
(!scopes.includes('management:write') && !scopes.includes(Scope.wildcard)) ||
|
|
958
|
+
Auth.membership(c)?.role === 'owner'
|
|
959
|
+
)
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/** Mints a replacement that preserves the source key's access and attribution. */
|
|
963
|
+
async function rotate(
|
|
964
|
+
c: Context<App.Environment>,
|
|
965
|
+
store: Store.State,
|
|
966
|
+
source: ApiKeys.Record,
|
|
967
|
+
createdBy: string,
|
|
968
|
+
) {
|
|
969
|
+
const billingActive =
|
|
970
|
+
source.environment === 'sandbox'
|
|
971
|
+
? await Billing.active(Db.get(c.get('db')), source.orgId, 'sandbox')
|
|
972
|
+
: undefined
|
|
973
|
+
const { record, token } = await ApiKeys.mint(
|
|
974
|
+
store,
|
|
975
|
+
{
|
|
976
|
+
allowedIps: source.allowedIps,
|
|
977
|
+
createdBy,
|
|
978
|
+
environment: source.environment,
|
|
979
|
+
orgId: source.orgId,
|
|
980
|
+
...(source.projectId === undefined ? {} : { projectId: source.projectId }),
|
|
981
|
+
scopes: source.scopes,
|
|
982
|
+
...(billingActive === undefined ? {} : { billingActive }),
|
|
983
|
+
...(source.expiresAt === undefined ? {} : { expiresAt: source.expiresAt }),
|
|
984
|
+
...(source.name === undefined ? {} : { name: source.name }),
|
|
985
|
+
...(source.rateLimits === undefined ? {} : { rateLimits: source.rateLimits }),
|
|
986
|
+
},
|
|
987
|
+
{ scopeCatalog: c.get('scopeCatalog') },
|
|
988
|
+
)
|
|
989
|
+
return c.json(
|
|
990
|
+
Response.validated(schema.rotateApiKey.Response, { ...serializeKey(record), token }),
|
|
991
|
+
200,
|
|
992
|
+
)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/** Revokes an API key after its route has verified ownership. */
|
|
996
|
+
async function revoke(c: Context<App.Environment>, store: Store.State, keyId: string) {
|
|
997
|
+
const revoked = await ApiKeys.revoke(store, keyId)
|
|
998
|
+
if (!revoked) return keyNotFound(c)
|
|
999
|
+
return c.json(Response.validated(schema.revokeApiKey.Response, { id: keyId }), 200)
|
|
1000
|
+
}
|
|
1001
|
+
|
|
666
1002
|
function keyNotFound(c: Context<App.Environment>) {
|
|
667
1003
|
return Response.error(c, {
|
|
668
1004
|
code: 'api_key_not_found',
|