tapimo 0.7.1 → 0.7.2
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/ApiKeys.d.ts +24 -7
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +17 -5
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12104 -7861
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +191 -128
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +10 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +17 -4
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +19 -8
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +25 -9
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +1 -1
- package/dist/admin/App.d.ts +601 -20
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +12 -2
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +94 -11
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +141 -32
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +1069 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
- package/dist/admin/apps/earn-vaults.js +409 -0
- package/dist/admin/apps/earn-vaults.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +166 -166
- 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 +99 -43
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +2 -0
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +18 -2
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +22 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +59 -39
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/Zones.d.ts +8335 -0
- package/dist/apps/Zones.d.ts.map +1 -0
- package/dist/apps/Zones.js +38 -0
- package/dist/apps/Zones.js.map +1 -0
- package/dist/apps/data/App.d.ts +12125 -7913
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +91 -19
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +1 -1
- package/dist/apps/data/FxOracle.d.ts.map +1 -1
- package/dist/apps/data/index.d.ts +0 -1
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +0 -1
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +32 -32
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +130 -65
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +312 -312
- package/dist/apps/data/routes/balances.d.ts +18 -18
- package/dist/apps/data/routes/balances.js +5 -5
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +176 -176
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
- package/dist/apps/data/routes/coingecko.js +62 -35
- package/dist/apps/data/routes/coingecko.js.map +1 -1
- package/dist/apps/data/routes/earn.d.ts +2144 -0
- package/dist/apps/data/routes/earn.d.ts.map +1 -0
- package/dist/apps/data/routes/earn.js +947 -0
- package/dist/apps/data/routes/earn.js.map +1 -0
- package/dist/apps/data/routes/exchanges.d.ts +1625 -718
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +656 -193
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +108 -108
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +59 -8
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/funding.d.ts +4092 -387
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +1403 -256
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +30 -30
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +19 -2
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +263 -263
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +11 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +5 -5
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +211 -22
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +36 -36
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +39 -8
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +114 -86
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +194 -91
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +53 -53
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +78 -39
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +76 -27
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +165 -67
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +42 -42
- package/dist/apps/data/routes/valuation.js +2 -2
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +369 -367
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +161 -59
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +281 -0
- package/dist/apps/data/routes/zones.d.ts.map +1 -0
- package/dist/apps/data/routes/zones.js +252 -0
- package/dist/apps/data/routes/zones.js.map +1 -0
- package/dist/apps/docs/reference.js +6 -5
- package/dist/apps/docs/reference.js.map +1 -1
- package/dist/apps/index.d.ts +2 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +2 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +670 -670
- package/dist/apps/management/Billing.d.ts +8 -0
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +12 -0
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/Error.d.ts +12 -0
- package/dist/apps/management/Error.d.ts.map +1 -0
- package/dist/apps/management/Error.js +10 -0
- package/dist/apps/management/Error.js.map +1 -0
- package/dist/apps/management/routes/api-keys.d.ts +5 -5
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +2 -8
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +119 -119
- package/dist/apps/management/routes/faucet.d.ts +2 -2
- package/dist/apps/management/routes/invitations.d.ts +62 -62
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +4 -10
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +30 -30
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +2 -2
- package/dist/apps/management/routes/orgs.d.ts +48 -48
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +2 -8
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +9 -9
- package/dist/apps/management/routes/scopes.js +2 -2
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +36 -36
- package/dist/apps/management/routes/webhooks.d.ts +50 -50
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +15 -3
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/App.d.ts +55 -56
- package/dist/apps/mpp/App.d.ts.map +1 -1
- package/dist/apps/mpp/App.js +192 -27
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/Mpp.d.ts +0 -20
- package/dist/apps/mpp/Mpp.d.ts.map +1 -1
- package/dist/apps/mpp/Mpp.js +0 -24
- package/dist/apps/mpp/Mpp.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Adapter.js +66 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -0
- package/dist/apps/mpp/internal/Error.d.ts +4 -0
- package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Error.js +41 -0
- package/dist/apps/mpp/internal/Error.js.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.js +28 -0
- package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
- package/dist/apps/mpp/internal/Policy.d.ts +46 -0
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Policy.js +57 -0
- package/dist/apps/mpp/internal/Policy.js.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.js +18 -0
- package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
- package/dist/apps/mpp/internal/Screening.d.ts +35 -0
- package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Screening.js +20 -0
- package/dist/apps/mpp/internal/Screening.js.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.js +103 -0
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
- package/dist/apps/mpp/internal/Utils.d.ts +7 -0
- package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Utils.js +24 -0
- package/dist/apps/mpp/internal/Utils.js.map +1 -0
- package/dist/apps/relay/App.js +183 -23
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +4 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +15 -6
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/db/Db.d.ts +20 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +342 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +921 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +269 -1
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +68 -0
- package/dist/db/tables/earnVaults.d.ts.map +1 -0
- package/dist/db/tables/earnVaults.js +72 -0
- package/dist/db/tables/earnVaults.js.map +1 -0
- package/dist/db/tables/fundingCatalog.d.ts +56 -0
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
- package/dist/db/tables/fundingCatalog.js +85 -0
- package/dist/db/tables/fundingCatalog.js.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts +159 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.js +206 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
- package/dist/db/tables/fundingDeposits.d.ts +115 -0
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
- package/dist/db/tables/fundingDeposits.js +100 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -0
- package/dist/db/tables/fundingIdempotency.d.ts +91 -0
- package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
- package/dist/db/tables/fundingIdempotency.js +103 -0
- package/dist/db/tables/fundingIdempotency.js.map +1 -0
- package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
- package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferEvents.js +18 -0
- package/dist/db/tables/fundingTransferEvents.js.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.js +27 -0
- package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
- package/dist/db/tables/fundingTransfers.d.ts +82 -0
- package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
- package/dist/db/tables/fundingTransfers.js +89 -0
- package/dist/db/tables/fundingTransfers.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +8 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +16 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +8 -0
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +16 -0
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +13 -0
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js +16 -0
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +2 -2
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +1 -1
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/users.d.ts +8 -0
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +16 -0
- package/dist/db/tables/users.js.map +1 -1
- package/dist/db/tables/verifiedTokens.d.ts +14 -7
- package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
- package/dist/db/tables/verifiedTokens.js +9 -7
- package/dist/db/tables/verifiedTokens.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +24 -3
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/relay.js +108 -108
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +26 -0
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +35 -2
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +16 -10
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/Cursor.js +1 -1
- package/dist/internal/Cursor.js.map +1 -1
- package/dist/internal/EarnRates.d.ts +89 -0
- package/dist/internal/EarnRates.d.ts.map +1 -0
- package/dist/internal/EarnRates.js +266 -0
- package/dist/internal/EarnRates.js.map +1 -0
- package/dist/internal/EarnVaults.d.ts +171 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -0
- package/dist/internal/EarnVaults.js +547 -0
- package/dist/internal/EarnVaults.js.map +1 -0
- package/dist/internal/EdgeCache.d.ts +8 -1
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +33 -7
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/Id.d.ts +11 -0
- package/dist/internal/Id.d.ts.map +1 -1
- package/dist/internal/Id.js +13 -0
- package/dist/internal/Id.js.map +1 -1
- package/dist/internal/Idempotency.d.ts +83 -0
- package/dist/internal/Idempotency.d.ts.map +1 -0
- package/dist/internal/Idempotency.js +113 -0
- package/dist/internal/Idempotency.js.map +1 -0
- package/dist/internal/Log.d.ts +64 -9
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +29 -7
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +47 -1
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +1 -1
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Provider.d.ts +14 -0
- package/dist/internal/Provider.d.ts.map +1 -0
- package/dist/internal/Provider.js +5 -0
- package/dist/internal/Provider.js.map +1 -0
- package/dist/internal/Schema.d.ts +6 -1
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +20 -11
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +6 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +35 -0
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +43 -24
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +79 -11
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Viem.d.ts +82 -65
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +83 -12
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +34 -28
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +9 -0
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +15 -10
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/exchange/Provider.d.ts +219 -0
- package/dist/internal/exchange/Provider.d.ts.map +1 -0
- package/dist/internal/exchange/Provider.js +117 -0
- package/dist/internal/exchange/Provider.js.map +1 -0
- package/dist/internal/exchange/index.d.ts +2 -0
- package/dist/internal/exchange/index.d.ts.map +1 -0
- package/dist/internal/exchange/index.js +2 -0
- package/dist/internal/exchange/index.js.map +1 -0
- package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
- package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
- package/dist/internal/exchange/providers/uniswap.js +553 -0
- package/dist/internal/exchange/providers/uniswap.js.map +1 -0
- package/dist/internal/funding/Action.d.ts +55 -0
- package/dist/internal/funding/Action.d.ts.map +1 -0
- package/dist/internal/funding/Action.js +74 -0
- package/dist/internal/funding/Action.js.map +1 -0
- package/dist/internal/funding/Catalog.d.ts +107 -0
- package/dist/internal/funding/Catalog.d.ts.map +1 -0
- package/dist/internal/funding/Catalog.js +270 -0
- package/dist/internal/funding/Catalog.js.map +1 -0
- package/dist/internal/funding/Chain.d.ts +76 -0
- package/dist/internal/funding/Chain.d.ts.map +1 -0
- package/dist/internal/funding/Chain.js +38 -0
- package/dist/internal/funding/Chain.js.map +1 -0
- package/dist/internal/funding/Deposit.d.ts +366 -0
- package/dist/internal/funding/Deposit.d.ts.map +1 -0
- package/dist/internal/funding/Deposit.js +286 -0
- package/dist/internal/funding/Deposit.js.map +1 -0
- package/dist/internal/funding/DepositAddress.d.ts +345 -0
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
- package/dist/internal/funding/DepositAddress.js +189 -0
- package/dist/internal/funding/DepositAddress.js.map +1 -0
- package/dist/internal/funding/Evidence.d.ts +52 -0
- package/dist/internal/funding/Evidence.d.ts.map +1 -0
- package/dist/internal/funding/Evidence.js +314 -0
- package/dist/internal/funding/Evidence.js.map +1 -0
- package/dist/internal/funding/Provider.d.ts +1186 -0
- package/dist/internal/funding/Provider.d.ts.map +1 -0
- package/dist/internal/funding/Provider.js +1081 -0
- package/dist/internal/funding/Provider.js.map +1 -0
- package/dist/internal/funding/Reconciliation.d.ts +113 -0
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
- package/dist/internal/funding/Reconciliation.js +676 -0
- package/dist/internal/funding/Reconciliation.js.map +1 -0
- package/dist/internal/funding/Route.d.ts +21 -0
- package/dist/internal/funding/Route.d.ts.map +1 -0
- package/dist/internal/funding/Route.js +5 -0
- package/dist/internal/funding/Route.js.map +1 -0
- package/dist/internal/funding/Subsidy.d.ts +113 -0
- package/dist/internal/funding/Subsidy.d.ts.map +1 -0
- package/dist/internal/funding/Subsidy.js +138 -0
- package/dist/internal/funding/Subsidy.js.map +1 -0
- package/dist/internal/funding/Token.d.ts +41 -0
- package/dist/internal/funding/Token.d.ts.map +1 -0
- package/dist/internal/funding/Token.js +22 -0
- package/dist/internal/funding/Token.js.map +1 -0
- package/dist/internal/funding/Transfer.d.ts +643 -0
- package/dist/internal/funding/Transfer.d.ts.map +1 -0
- package/dist/internal/funding/Transfer.js +332 -0
- package/dist/internal/funding/Transfer.js.map +1 -0
- package/dist/internal/funding/index.d.ts +13 -0
- package/dist/internal/funding/index.d.ts.map +1 -0
- package/dist/internal/funding/index.js +13 -0
- package/dist/internal/funding/index.js.map +1 -0
- package/dist/internal/funding/providers/across.d.ts +21 -0
- package/dist/internal/funding/providers/across.d.ts.map +1 -0
- package/dist/internal/funding/providers/across.js +117 -0
- package/dist/internal/funding/providers/across.js.map +1 -0
- package/dist/internal/funding/providers/relay.d.ts +46 -0
- package/dist/internal/funding/providers/relay.d.ts.map +1 -0
- package/dist/internal/funding/providers/relay.js +464 -0
- package/dist/internal/funding/providers/relay.js.map +1 -0
- package/dist/internal/funding/providers/rhino.d.ts +15 -0
- package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
- package/dist/internal/funding/providers/rhino.js +116 -0
- package/dist/internal/funding/providers/rhino.js.map +1 -0
- package/dist/internal/funding/providers/squid.d.ts +19 -0
- package/dist/internal/funding/providers/squid.d.ts.map +1 -0
- package/dist/internal/funding/providers/squid.js +120 -0
- package/dist/internal/funding/providers/squid.js.map +1 -0
- package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
- package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
- package/dist/internal/funding/providers/symbiosis.js +176 -0
- package/dist/internal/funding/providers/symbiosis.js.map +1 -0
- package/dist/internal/index.d.ts +5 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +5 -1
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/url.js +61 -57
- package/dist/internal/webhookDestinations/url.js.map +1 -1
- package/dist/providers/index.d.ts +43 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +19 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +9 -4
- package/src/ApiKeys.test.ts +11 -7
- package/src/ApiKeys.ts +37 -9
- package/src/App.test.ts +85 -10
- package/src/App.ts +224 -137
- package/src/Assets.ts +29 -4
- package/src/Client.test-d.ts +650 -30
- package/src/Scope.test.ts +19 -0
- package/src/Scope.ts +28 -11
- package/src/Webhooks.test.ts +25 -0
- package/src/Webhooks.ts +1 -1
- package/src/admin/App.test.ts +9 -2
- package/src/admin/App.ts +32 -9
- package/src/admin/apps/api-keys.test.ts +167 -23
- package/src/admin/apps/api-keys.ts +166 -28
- package/src/admin/apps/earn-vaults.test.ts +338 -0
- package/src/admin/apps/earn-vaults.ts +572 -0
- package/src/admin/apps/scopes.test.ts +16 -1
- package/src/admin/ui/plugin.ts +2 -2
- package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
- package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
- package/src/admin/ui/src/components/Page.tsx +1 -1
- package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
- package/src/admin/ui/src/lib/api-keys.ts +37 -7
- package/src/admin/ui/src/lib/client.ts +1 -1
- package/src/admin/ui/src/lib/config.ts +1 -1
- package/src/admin/ui/src/lib/early-access.ts +8 -9
- package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
- package/src/admin/ui/src/lib/format.ts +13 -0
- package/src/admin/ui/src/lib/organizations.test.ts +14 -4
- package/src/admin/ui/src/lib/organizations.ts +7 -1
- package/src/admin/ui/src/lib/response.ts +22 -0
- package/src/admin/ui/src/lib/scopes.test.ts +19 -11
- package/src/admin/ui/src/lib/scopes.ts +28 -7
- package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
- package/src/admin/ui/src/routeTree.gen.ts +70 -7
- package/src/admin/ui/src/router.tsx +2 -2
- package/src/admin/ui/src/routes/__root.tsx +9 -8
- package/src/admin/ui/src/routes/api-keys.tsx +475 -64
- package/src/admin/ui/src/routes/early-access.tsx +5 -12
- package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
- package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
- package/src/admin/ui/src/routes/organizations.tsx +4 -7
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
- package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
- package/src/admin/ui/vite.config.ts +4 -1
- package/src/admin/ui.generated.ts +113 -43
- package/src/analytics/Analytics.test.ts +69 -10
- package/src/analytics/Analytics.ts +20 -1
- package/src/analytics/tables/requestEvents.ts +79 -37
- package/src/apps/Zones.test.ts +33 -0
- package/src/apps/Zones.ts +40 -0
- package/src/apps/composition.test.ts +84 -1
- package/src/apps/data/App.test.ts +28 -11
- package/src/apps/data/App.ts +96 -33
- package/src/apps/data/FxOracle.ts +1 -1
- package/src/apps/data/index.ts +0 -1
- package/src/apps/data/routes/activities.test.ts +82 -6
- package/src/apps/data/routes/activities.ts +131 -71
- package/src/apps/data/routes/balances.test.ts +50 -37
- package/src/apps/data/routes/balances.ts +5 -5
- package/src/apps/data/routes/blocks.test.ts +2 -0
- package/src/apps/data/routes/coingecko.test.ts +22 -0
- package/src/apps/data/routes/coingecko.ts +84 -48
- package/src/apps/data/routes/earn.test.ts +1108 -0
- package/src/apps/data/routes/earn.ts +1391 -0
- package/src/apps/data/routes/exchanges.test.ts +82 -33
- package/src/apps/data/routes/exchanges.ts +842 -227
- package/src/apps/data/routes/fee-amm.test.ts +4 -6
- package/src/apps/data/routes/fee-amm.ts +69 -12
- package/src/apps/data/routes/funding.test.ts +2712 -221
- package/src/apps/data/routes/funding.ts +1604 -387
- package/src/apps/data/routes/indexer.test.ts +43 -34
- package/src/apps/data/routes/indexer.ts +19 -2
- package/src/apps/data/routes/receipts.test.ts +5 -3
- package/src/apps/data/routes/receipts.ts +13 -11
- package/src/apps/data/routes/rpc.test.ts +446 -28
- package/src/apps/data/routes/rpc.ts +243 -25
- package/src/apps/data/routes/tokenlist.ts +72 -19
- package/src/apps/data/routes/tokens.ts +258 -86
- package/src/apps/data/routes/transactions.test.ts +2 -0
- package/src/apps/data/routes/transactions.ts +77 -42
- package/src/apps/data/routes/transfers.test.ts +166 -4
- package/src/apps/data/routes/transfers.ts +216 -78
- package/src/apps/data/routes/valuation.test.ts +62 -9
- package/src/apps/data/routes/valuation.ts +2 -2
- package/src/apps/data/routes/webhooks.test.ts +386 -43
- package/src/apps/data/routes/webhooks.ts +172 -71
- package/src/apps/data/routes/zones.test.ts +473 -0
- package/src/apps/data/routes/zones.ts +338 -0
- package/src/apps/docs/reference.ts +8 -6
- package/src/apps/index.ts +2 -1
- package/src/apps/management/Billing.test.ts +29 -0
- package/src/apps/management/Billing.ts +23 -0
- package/src/apps/management/Error.ts +12 -0
- package/src/apps/management/routes/api-keys.test.ts +5 -3
- package/src/apps/management/routes/api-keys.ts +2 -9
- package/src/apps/management/routes/invitations.ts +4 -11
- package/src/apps/management/routes/orgs.ts +2 -9
- package/src/apps/management/routes/scopes.test.ts +7 -2
- package/src/apps/management/routes/scopes.ts +2 -2
- package/src/apps/management/routes/webhooks.test.ts +6 -1
- package/src/apps/management/routes/webhooks.ts +15 -3
- package/src/apps/mpp/App.ts +276 -29
- package/src/apps/mpp/Mpp.test.ts +631 -26
- package/src/apps/mpp/Mpp.ts +0 -42
- package/src/apps/mpp/internal/Adapter.ts +108 -3
- package/src/apps/mpp/internal/Error.test.ts +33 -0
- package/src/apps/mpp/internal/Error.ts +44 -6
- package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
- package/src/apps/mpp/internal/Idempotency.ts +59 -5
- package/src/apps/mpp/internal/Policy.test.ts +122 -0
- package/src/apps/mpp/internal/Policy.ts +98 -0
- package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
- package/src/apps/mpp/internal/ScreenManager.ts +41 -0
- package/src/apps/mpp/internal/Screening.ts +40 -3
- package/src/apps/mpp/internal/Sponsorship.ts +144 -0
- package/src/apps/mpp/internal/Utils.ts +30 -0
- package/src/apps/relay/App.test.ts +493 -62
- package/src/apps/relay/App.ts +233 -23
- package/src/apps/relay/Sponsorships.test.ts +49 -0
- package/src/apps/relay/Sponsorships.ts +18 -6
- package/src/db/Db.ts +439 -0
- package/src/db/Schema.ts +325 -2
- package/src/db/tables/earnVaults.test.ts +185 -0
- package/src/db/tables/earnVaults.ts +151 -0
- package/src/db/tables/fundingCatalog.test.ts +108 -0
- package/src/db/tables/fundingCatalog.ts +157 -0
- package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
- package/src/db/tables/fundingDepositAddresses.ts +376 -0
- package/src/db/tables/fundingDeposits.test.ts +261 -0
- package/src/db/tables/fundingDeposits.ts +229 -0
- package/src/db/tables/fundingIdempotency.test.ts +182 -0
- package/src/db/tables/fundingIdempotency.ts +180 -0
- package/src/db/tables/fundingTransferEvents.ts +28 -0
- package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
- package/src/db/tables/fundingTransferTransactions.ts +37 -0
- package/src/db/tables/fundingTransfers.test.ts +89 -0
- package/src/db/tables/fundingTransfers.ts +153 -0
- package/src/db/tables/organizations.ts +16 -0
- package/src/db/tables/projects.ts +16 -0
- package/src/db/tables/requestUsage.ts +23 -0
- package/src/db/tables/sponsoredTransactions.test.ts +11 -0
- package/src/db/tables/sponsoredTransactions.ts +3 -3
- package/src/db/tables/users.ts +16 -0
- package/src/db/tables/verifiedTokens.ts +19 -14
- package/src/db/tables/webhookSubscriptions.ts +58 -3
- package/src/handlers/relay.test.ts +2 -0
- package/src/handlers/relay.ts +95 -99
- package/src/internal/Auth.test.ts +48 -0
- package/src/internal/Auth.ts +61 -2
- package/src/internal/Cache.ts +13 -9
- package/src/internal/Cursor.test.ts +2 -2
- package/src/internal/Cursor.ts +1 -1
- package/src/internal/EarnRates.test.ts +125 -0
- package/src/internal/EarnRates.ts +409 -0
- package/src/internal/EarnVaults.test.ts +195 -0
- package/src/internal/EarnVaults.ts +876 -0
- package/src/internal/EdgeCache.test.ts +19 -0
- package/src/internal/EdgeCache.ts +35 -5
- package/src/internal/Id.ts +14 -0
- package/src/internal/Idempotency.test.ts +109 -0
- package/src/internal/Idempotency.ts +237 -0
- package/src/internal/Log.test-d.ts +41 -8
- package/src/internal/Log.test.ts +189 -8
- package/src/internal/Log.ts +124 -17
- package/src/internal/MetricSink.test.ts +244 -4
- package/src/internal/MetricSink.ts +51 -1
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Provider.test.ts +17 -0
- package/src/internal/Provider.ts +17 -0
- package/src/internal/Schema.ts +27 -17
- package/src/internal/Store.test.ts +25 -0
- package/src/internal/Store.ts +46 -0
- package/src/internal/Tidx.local.test.ts +78 -3
- package/src/internal/Tidx.test.ts +212 -18
- package/src/internal/Tidx.ts +112 -32
- package/src/internal/VerifiedTokens.test.ts +15 -0
- package/src/internal/Viem.test.ts +170 -17
- package/src/internal/Viem.ts +111 -28
- package/src/internal/WebhookDestination.ts +25 -23
- package/src/internal/Webhooks.test.ts +59 -0
- package/src/internal/Webhooks.ts +34 -10
- package/src/internal/exchange/Provider.test.ts +216 -0
- package/src/internal/exchange/Provider.ts +326 -0
- package/src/internal/exchange/index.test.ts +6 -0
- package/src/internal/exchange/index.ts +1 -0
- package/src/internal/exchange/providers/uniswap.test.ts +122 -0
- package/src/internal/exchange/providers/uniswap.ts +682 -0
- package/src/internal/funding/Action.test.ts +138 -0
- package/src/internal/funding/Action.ts +117 -0
- package/src/internal/funding/Catalog.test.ts +311 -0
- package/src/internal/funding/Catalog.ts +347 -0
- package/src/internal/funding/Chain.test.ts +79 -0
- package/src/internal/funding/Chain.ts +120 -0
- package/src/internal/funding/Deposit.test.ts +26 -0
- package/src/internal/funding/Deposit.ts +453 -0
- package/src/internal/funding/DepositAddress.test.ts +18 -0
- package/src/internal/funding/DepositAddress.ts +312 -0
- package/src/internal/funding/Evidence.test.ts +297 -0
- package/src/internal/funding/Evidence.ts +430 -0
- package/src/internal/funding/Provider.test.ts +1328 -0
- package/src/internal/funding/Provider.ts +1796 -0
- package/src/internal/funding/Reconciliation.local.test.ts +504 -0
- package/src/internal/funding/Reconciliation.test.ts +2020 -0
- package/src/internal/funding/Reconciliation.ts +930 -0
- package/src/internal/funding/Route.test.ts +66 -0
- package/src/internal/funding/Route.ts +29 -0
- package/src/internal/funding/Subsidy.local.test.ts +152 -0
- package/src/internal/funding/Subsidy.test.ts +75 -0
- package/src/internal/funding/Subsidy.ts +260 -0
- package/src/internal/funding/Token.test.ts +47 -0
- package/src/internal/funding/Token.ts +59 -0
- package/src/internal/funding/Transfer.test.ts +369 -0
- package/src/internal/funding/Transfer.ts +522 -0
- package/src/internal/funding/index.test.ts +20 -0
- package/src/internal/funding/index.ts +12 -0
- package/src/internal/funding/providers/across.ts +149 -0
- package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
- package/src/internal/funding/providers/relay.test.ts +474 -0
- package/src/internal/funding/providers/relay.ts +559 -0
- package/src/internal/funding/providers/rhino.ts +139 -0
- package/src/internal/funding/providers/squid.ts +151 -0
- package/src/internal/funding/providers/symbiosis.ts +221 -0
- package/src/internal/index.test.ts +5 -1
- package/src/internal/index.ts +5 -1
- package/src/internal/webhookDestinations/url.ts +49 -45
- package/src/providers/index.test.ts +14 -0
- package/src/providers/index.ts +54 -0
- package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
- package/dist/apps/data/FundingQuoteProviders.js +0 -775
- package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
- package/dist/internal/FundingQuotes.d.ts +0 -864
- package/dist/internal/FundingQuotes.d.ts.map +0 -1
- package/dist/internal/FundingQuotes.js +0 -672
- package/dist/internal/FundingQuotes.js.map +0 -1
- package/src/apps/data/FundingQuoteProviders.ts +0 -1043
- package/src/internal/FundingQuotes.test.ts +0 -456
- package/src/internal/FundingQuotes.ts +0 -944
package/src/Scope.test.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import * as Scope from './Scope.js'
|
|
2
2
|
|
|
3
|
+
describe('schema.Zone', () => {
|
|
4
|
+
test('accepts concrete read and write scopes', () => {
|
|
5
|
+
expect(
|
|
6
|
+
['zone:421700005:read', 'zone:421700005:write'].map((scope) =>
|
|
7
|
+
Scope.schema.Zone.safeParse(scope),
|
|
8
|
+
),
|
|
9
|
+
).toMatchObject([{ success: true }, { success: true }])
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('rejects templates and unsupported access levels', () => {
|
|
13
|
+
expect(
|
|
14
|
+
['zone:<chainId>:read', 'zone:421700005:admin'].map((scope) =>
|
|
15
|
+
Scope.schema.Zone.safeParse(scope),
|
|
16
|
+
),
|
|
17
|
+
).toMatchObject([{ success: false }, { success: false }])
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
3
21
|
describe('extend', () => {
|
|
4
22
|
test('appends host scopes to the built-in catalog', () => {
|
|
5
23
|
expect(
|
|
@@ -13,6 +31,7 @@ describe('extend', () => {
|
|
|
13
31
|
).toEqual([
|
|
14
32
|
...Scope.catalog,
|
|
15
33
|
Scope.zoneEntry,
|
|
34
|
+
Scope.zoneWriteEntry,
|
|
16
35
|
{
|
|
17
36
|
description: 'Read project accounts.',
|
|
18
37
|
scope: 'accounts:read',
|
package/src/Scope.ts
CHANGED
|
@@ -33,6 +33,16 @@ export const catalog = [
|
|
|
33
33
|
scope: 'data:read',
|
|
34
34
|
selfServe: true,
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
description: 'Read organization funding transfers, deposit addresses, and deposits.',
|
|
38
|
+
scope: 'funding:read',
|
|
39
|
+
selfServe: false,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
description: 'Create funding transfers and register their source transactions.',
|
|
43
|
+
scope: 'funding:write',
|
|
44
|
+
selfServe: false,
|
|
45
|
+
},
|
|
36
46
|
{
|
|
37
47
|
description: 'Run ad-hoc queries against the raw indexer passthrough.',
|
|
38
48
|
scope: 'indexer:query',
|
|
@@ -50,7 +60,7 @@ export const catalog = [
|
|
|
50
60
|
selfServe: true,
|
|
51
61
|
},
|
|
52
62
|
{
|
|
53
|
-
description: 'Validate and broadcast MPP
|
|
63
|
+
description: 'Validate and broadcast MPP credentials through Tempo.',
|
|
54
64
|
scope: 'mpp:write',
|
|
55
65
|
selfServe: true,
|
|
56
66
|
},
|
|
@@ -76,28 +86,35 @@ export const catalog = [
|
|
|
76
86
|
},
|
|
77
87
|
] as const satisfies readonly Entry[]
|
|
78
88
|
|
|
79
|
-
/**
|
|
80
|
-
* Templated `/v1/scopes` entry for per-zone read scopes. Concrete grants use
|
|
81
|
-
* `zone:<chainId>:read` and are never self-serve.
|
|
82
|
-
*/
|
|
89
|
+
/** Templated `/v1/scopes` entry for per-zone read scopes. */
|
|
83
90
|
export const zoneEntry = {
|
|
84
91
|
description: 'Read RPC and indexed data for one zone chain id.',
|
|
85
92
|
scope: 'zone:<chainId>:read',
|
|
86
93
|
selfServe: false,
|
|
87
94
|
} as const satisfies Entry
|
|
88
95
|
|
|
96
|
+
/** Templated `/v1/scopes` entry for per-zone transaction broadcast scopes. */
|
|
97
|
+
export const zoneWriteEntry = {
|
|
98
|
+
description: 'Broadcast signed transactions to one zone chain id.',
|
|
99
|
+
scope: 'zone:<chainId>:write',
|
|
100
|
+
selfServe: false,
|
|
101
|
+
} as const satisfies Entry
|
|
102
|
+
|
|
89
103
|
/** Zod schemas owned by the scope vocabulary. */
|
|
90
104
|
export namespace schema {
|
|
91
|
-
/** A concrete per-zone read scope
|
|
105
|
+
/** A concrete per-zone read or write scope. */
|
|
92
106
|
export const Zone = z
|
|
93
|
-
.
|
|
107
|
+
.union([
|
|
108
|
+
z.templateLiteral(['zone:', z.int(), ':read']),
|
|
109
|
+
z.templateLiteral(['zone:', z.int(), ':write']),
|
|
110
|
+
])
|
|
94
111
|
.check(
|
|
95
|
-
z.regex(/^zone:[1-9]\d*:read$/),
|
|
96
|
-
z.describe('Per-zone read scope (`zone:<chainId>:read`).'),
|
|
112
|
+
z.regex(/^zone:[1-9]\d*:(read|write)$/),
|
|
113
|
+
z.describe('Per-zone read or write scope (`zone:<chainId>:read|write`).'),
|
|
97
114
|
)
|
|
98
115
|
}
|
|
99
116
|
|
|
100
|
-
/** Per-zone read scope, granting access to one zone chain id. */
|
|
117
|
+
/** Per-zone read or write scope, granting access to one zone chain id. */
|
|
101
118
|
export type Zone = z.output<typeof schema.Zone>
|
|
102
119
|
|
|
103
120
|
/** Issuable API-key scope identifier, including host-defined scopes. */
|
|
@@ -123,7 +140,7 @@ export const selfServe: readonly Id[] = catalog
|
|
|
123
140
|
*/
|
|
124
141
|
export function extend(entries: readonly Entry[] = []): Catalog {
|
|
125
142
|
const identifiers = new Set<string>()
|
|
126
|
-
const result = [...catalog, zoneEntry, ...entries]
|
|
143
|
+
const result = [...catalog, zoneEntry, zoneWriteEntry, ...entries]
|
|
127
144
|
for (const entry of result) {
|
|
128
145
|
if (!entry.scope.trim()) throw new Error('Scope identifier must not be empty.')
|
|
129
146
|
if (identifiers.has(entry.scope)) throw new Error(`Duplicate scope \`${entry.scope}\`.`)
|
package/src/Webhooks.test.ts
CHANGED
|
@@ -47,4 +47,29 @@ describe('createPoller', () => {
|
|
|
47
47
|
]
|
|
48
48
|
`)
|
|
49
49
|
})
|
|
50
|
+
|
|
51
|
+
test('clamps a creation checkpoint to genesis', async () => {
|
|
52
|
+
const db = TestApp.database()
|
|
53
|
+
const subscription = await Webhooks.createSubscription(
|
|
54
|
+
db,
|
|
55
|
+
{
|
|
56
|
+
chainId: 42431,
|
|
57
|
+
destination: { type: 'url', url: 'https://hooks.example.com/x' },
|
|
58
|
+
eventType: 'block:created',
|
|
59
|
+
owner: { orgId: 'org_test', type: 'api_key' },
|
|
60
|
+
},
|
|
61
|
+
{ startBlockNumber: 1 },
|
|
62
|
+
)
|
|
63
|
+
const poller = Webhooks.createPoller({
|
|
64
|
+
db,
|
|
65
|
+
defaultChainId: 42431,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
await poller.tick({
|
|
69
|
+
eventTypes: ['block:created'],
|
|
70
|
+
headBlockNumber: 1,
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
expect(decodeCursor(await Webhooks.getCursor(db, subscription.id))).toEqual([0, 2_147_483_647])
|
|
74
|
+
})
|
|
50
75
|
})
|
package/src/Webhooks.ts
CHANGED
|
@@ -126,7 +126,7 @@ export declare namespace createPoller {
|
|
|
126
126
|
|
|
127
127
|
/** Knobs shared by every {@link Poller.tick}; each is overridable per tick. */
|
|
128
128
|
type Defaults = {
|
|
129
|
-
/** Max matching rows scanned per subscription per tick (default
|
|
129
|
+
/** Max matching rows scanned per subscription per tick (default 200). */
|
|
130
130
|
batchSize?: number | undefined
|
|
131
131
|
/** Reorg-safety window: only emit blocks this far behind head (default 2). */
|
|
132
132
|
confirmations?: number | undefined
|
package/src/admin/App.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Hono } from 'hono'
|
|
2
|
+
import * as Organizations from '../db/tables/organizations.js'
|
|
2
3
|
import * as TestAdmin from '../../test/Admin.js'
|
|
3
4
|
|
|
4
5
|
// Route behavior (mint/list/revoke, the scope catalog) is covered in
|
|
@@ -18,6 +19,11 @@ describe('create', () => {
|
|
|
18
19
|
method: 'POST',
|
|
19
20
|
}),
|
|
20
21
|
new Request('http://admin/api-keys/key_x', { method: 'DELETE' }),
|
|
22
|
+
new Request('http://admin/earn/verified-vaults', {
|
|
23
|
+
body: JSON.stringify({}),
|
|
24
|
+
headers: { 'content-type': 'application/json' },
|
|
25
|
+
method: 'PUT',
|
|
26
|
+
}),
|
|
21
27
|
new Request('http://admin/organizations'),
|
|
22
28
|
new Request('http://admin/organizations/org_x'),
|
|
23
29
|
new Request('http://admin/organizations/org_x/billing-sources/stripe', { method: 'PUT' }),
|
|
@@ -61,9 +67,10 @@ describe('create', () => {
|
|
|
61
67
|
})
|
|
62
68
|
|
|
63
69
|
test('verified identity is recorded as createdBy on minted keys', async () => {
|
|
64
|
-
const { app } = TestAdmin.setup({ identify: () => ({ email: 'ops@tempo.xyz' }) })
|
|
70
|
+
const { app, db } = TestAdmin.setup({ identify: () => ({ email: 'ops@tempo.xyz' }) })
|
|
71
|
+
await Organizations.create(db, { id: 'org', name: 'Operations' })
|
|
65
72
|
const response = await app.request('http://admin/api-keys', {
|
|
66
|
-
body: JSON.stringify({ orgId: 'org', scopes: ['data:read'] }),
|
|
73
|
+
body: JSON.stringify({ name: 'Operations', orgId: 'org', scopes: ['data:read'] }),
|
|
67
74
|
headers: { 'content-type': 'application/json' },
|
|
68
75
|
method: 'POST',
|
|
69
76
|
})
|
package/src/admin/App.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Context, Hono, type Next } from 'hono'
|
|
2
2
|
import { HTTPException } from 'hono/http-exception'
|
|
3
3
|
import { requestId, type RequestIdVariables } from 'hono/request-id'
|
|
4
|
+
import type { Chain } from 'viem'
|
|
4
5
|
|
|
5
6
|
import * as ApiKey from '../ApiKey.js'
|
|
6
7
|
import type * as Assets from '../Assets.js'
|
|
@@ -9,9 +10,12 @@ import * as Db from '../db/Db.js'
|
|
|
9
10
|
import * as AdminAuditLogs from '../db/tables/adminAuditLogs.js'
|
|
10
11
|
import type * as Store from '../internal/Store.js'
|
|
11
12
|
import * as Response from '../internal/Response.js'
|
|
13
|
+
import * as Viem from '../internal/Viem.js'
|
|
14
|
+
import * as Zones from '../apps/Zones.js'
|
|
12
15
|
|
|
13
16
|
import { apiKeys } from './apps/api-keys.js'
|
|
14
17
|
import { earlyAccess } from './apps/early-access.js'
|
|
18
|
+
import { earnVaults } from './apps/earn-vaults.js'
|
|
15
19
|
import { organizations } from './apps/organizations.js'
|
|
16
20
|
import { scopes } from './apps/scopes.js'
|
|
17
21
|
import { verifiedTokens } from './apps/verified-tokens.js'
|
|
@@ -30,12 +34,18 @@ export type Environment = {
|
|
|
30
34
|
analytics: Analytics.Source
|
|
31
35
|
/** Static-asset writer (e.g. the R2 icon bucket), when configured. */
|
|
32
36
|
assets: create.Assets | undefined
|
|
37
|
+
/** Path where the admin app is mounted. */
|
|
38
|
+
basePath: string
|
|
33
39
|
/** Authoritative Postgres store, or a per-request factory. Resolve at the leaf with `Db.get`. */
|
|
34
40
|
db: Db.Source
|
|
35
|
-
/**
|
|
36
|
-
|
|
41
|
+
/** Gets a Tempo RPC client for a chain id. */
|
|
42
|
+
getClient: Viem.GetClient
|
|
37
43
|
/** The admin identity, or `null` when unauthenticated (gated routes reject). */
|
|
38
44
|
identity: Identity | null
|
|
45
|
+
/** KV state store backing API-key records (mint/list/revoke). */
|
|
46
|
+
kv: { store: Store.State }
|
|
47
|
+
/** Zone chains available to admin routes. */
|
|
48
|
+
zones: readonly Chain[]
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
51
|
|
|
@@ -45,6 +55,10 @@ export type App = ReturnType<typeof create>
|
|
|
45
55
|
/** Creates the admin portal Hono app. */
|
|
46
56
|
export function create(options: create.Options) {
|
|
47
57
|
const { identify } = options
|
|
58
|
+
|
|
59
|
+
const zones = options.zones === true ? Zones.chains : (options.zones ?? [])
|
|
60
|
+
const getClient = Viem.createGetClient({ rpc: options.rpc, zones })
|
|
61
|
+
|
|
48
62
|
// `false` (disabled) collapses to `undefined` so only a real config surfaces
|
|
49
63
|
// `loginUrl`/`logoutUrl` in `/config.json`.
|
|
50
64
|
const ui = options.ui || undefined
|
|
@@ -62,8 +76,11 @@ export function create(options: create.Options) {
|
|
|
62
76
|
c.header('Cache-Control', 'no-store')
|
|
63
77
|
c.set('analytics', options.analytics)
|
|
64
78
|
c.set('assets', options.assets)
|
|
79
|
+
c.set('basePath', c.req.routePath.replace(/\*$/, '').replace(/\/$/, ''))
|
|
65
80
|
c.set('db', options.db)
|
|
81
|
+
c.set('getClient', getClient)
|
|
66
82
|
c.set('kv', options.kv)
|
|
83
|
+
c.set('zones', zones)
|
|
67
84
|
c.set('identity', await identify(c.req.raw))
|
|
68
85
|
return next()
|
|
69
86
|
})
|
|
@@ -83,13 +100,12 @@ export function create(options: create.Options) {
|
|
|
83
100
|
// Renders the public SPA shell: stamps its hydration-safe base and auth
|
|
84
101
|
// placeholders with request values. `<` is escaped to keep the config script.
|
|
85
102
|
const serveShell = (c: Context<Environment>) => {
|
|
86
|
-
const mount = c.req.routePath.replace(/\*$/, '').replace(/\/$/, '')
|
|
87
103
|
const config = JSON.stringify(authConfig(c.get('identity'))).replaceAll('<', '\\u003c')
|
|
88
104
|
return c.html(
|
|
89
105
|
Ui.shell
|
|
90
106
|
.replace(
|
|
91
107
|
'<base data-tempo-base="true" href="/"/>',
|
|
92
|
-
`<base data-tempo-base="true" href="${
|
|
108
|
+
`<base data-tempo-base="true" href="${c.get('basePath')}/"/>`,
|
|
93
109
|
)
|
|
94
110
|
.replace('window.__TEMPO_API_CONFIG__=undefined', `window.__TEMPO_API_CONFIG__=${config}`),
|
|
95
111
|
)
|
|
@@ -120,6 +136,8 @@ export function create(options: create.Options) {
|
|
|
120
136
|
'/api-keys/*',
|
|
121
137
|
'/early-access',
|
|
122
138
|
'/early-access/*',
|
|
139
|
+
'/earn/verified-vaults',
|
|
140
|
+
'/earn/verified-vaults/*',
|
|
123
141
|
'/organizations',
|
|
124
142
|
'/organizations/*',
|
|
125
143
|
'/scopes',
|
|
@@ -156,6 +174,7 @@ export function create(options: create.Options) {
|
|
|
156
174
|
.get('/config.json', (c) => c.json(authConfig(c.get('identity')), 200))
|
|
157
175
|
.route('/api-keys', apiKeys())
|
|
158
176
|
.route('/early-access', earlyAccess())
|
|
177
|
+
.route('/earn/verified-vaults', earnVaults())
|
|
159
178
|
.route('/organizations', organizations())
|
|
160
179
|
.route('/scopes', scopes())
|
|
161
180
|
.route('/verified-tokens', verifiedTokens())
|
|
@@ -222,22 +241,26 @@ export declare namespace create {
|
|
|
222
241
|
* (`() => Db.postgres(...)`) on Workers.
|
|
223
242
|
*/
|
|
224
243
|
db: Db.Source
|
|
225
|
-
/**
|
|
226
|
-
* KV state store backing API-key records (shared with the main API's
|
|
227
|
-
* `kv` option), provisioned against by the `/api-keys` routes.
|
|
228
|
-
*/
|
|
229
|
-
kv: { store: Store.State }
|
|
230
244
|
/**
|
|
231
245
|
* Extracts the verified admin identity from a request, or `null` to deny.
|
|
232
246
|
* Must only return an identity for an already-authenticated request (a
|
|
233
247
|
* verified Access JWT, or a header set by a trusted proxy).
|
|
234
248
|
*/
|
|
235
249
|
identify: (request: Request) => Identity | null | Promise<Identity | null>
|
|
250
|
+
/**
|
|
251
|
+
* KV state store backing API-key records (shared with the main API's
|
|
252
|
+
* `kv` option), provisioned against by the `/api-keys` routes.
|
|
253
|
+
*/
|
|
254
|
+
kv: { store: Store.State }
|
|
255
|
+
/** Tempo RPC options used by onchain verification. */
|
|
256
|
+
rpc?: Viem.getClient.Rpc | undefined
|
|
236
257
|
/**
|
|
237
258
|
* Admin UI options, or `false` to disable the bundled UI (JSON API only).
|
|
238
259
|
* `loginUrl`/`logoutUrl` are surfaced in `GET /config.json`.
|
|
239
260
|
*/
|
|
240
261
|
ui?: Ui | false | undefined
|
|
262
|
+
/** Zone chains available to admin routes. Pass true to use the hosted Zone list. */
|
|
263
|
+
zones?: true | readonly Chain[] | undefined
|
|
241
264
|
}
|
|
242
265
|
|
|
243
266
|
/** Admin UI options surfaced to the SPA via `GET /config.json`. */
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import * as ApiKey from '../../ApiKey.js'
|
|
2
2
|
import * as core_ApiKeys from '../../ApiKeys.js'
|
|
3
|
+
import * as Organizations from '../../db/tables/organizations.js'
|
|
4
|
+
import * as Projects from '../../db/tables/projects.js'
|
|
5
|
+
import * as Users from '../../db/tables/users.js'
|
|
3
6
|
|
|
4
7
|
import * as TestAdmin from '../../../test/Admin.js'
|
|
5
8
|
import * as TestApp from '../../../test/App.js'
|
|
6
9
|
import * as ApiKeys from './api-keys.js'
|
|
7
10
|
|
|
8
11
|
/** Minimal valid mint payload. */
|
|
9
|
-
const validBody = { orgId: 'org_test', scopes: ['data:read'] } as const
|
|
12
|
+
const validBody = { name: 'CI', orgId: 'org_test', scopes: ['data:read'] } as const
|
|
10
13
|
|
|
11
14
|
describe('POST /api-keys', () => {
|
|
12
15
|
test('mints a key, returns the token once, persists a hashed record', async () => {
|
|
13
|
-
const { client, store } =
|
|
16
|
+
const { client, store } = await setup()
|
|
14
17
|
const response = await client['api-keys'].$post({ json: { ...validBody, name: 'CI' } })
|
|
15
18
|
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
16
19
|
|
|
@@ -44,7 +47,7 @@ describe('POST /api-keys', () => {
|
|
|
44
47
|
})
|
|
45
48
|
|
|
46
49
|
test('defaults to the production environment', async () => {
|
|
47
|
-
const { client, store } =
|
|
50
|
+
const { client, store } = await setup()
|
|
48
51
|
const response = await client['api-keys'].$post({ json: validBody })
|
|
49
52
|
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
50
53
|
|
|
@@ -53,8 +56,17 @@ describe('POST /api-keys', () => {
|
|
|
53
56
|
expect((await core_ApiKeys.list(store))[0]?.environment).toBe('production')
|
|
54
57
|
})
|
|
55
58
|
|
|
59
|
+
test('requires a human-readable name', async () => {
|
|
60
|
+
const { client } = await setup()
|
|
61
|
+
const response = await client['api-keys'].$post({
|
|
62
|
+
json: { orgId: 'org_test', scopes: ['data:read'] } as never,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
expect(response.status).toBe(400)
|
|
66
|
+
})
|
|
67
|
+
|
|
56
68
|
test('persists a sandbox environment when provided', async () => {
|
|
57
|
-
const { client, store } =
|
|
69
|
+
const { client, store } = await setup()
|
|
58
70
|
const response = await client['api-keys'].$post({
|
|
59
71
|
json: { ...validBody, environment: 'sandbox' },
|
|
60
72
|
})
|
|
@@ -68,21 +80,21 @@ describe('POST /api-keys', () => {
|
|
|
68
80
|
expect(resolved?.environment).toBe('sandbox')
|
|
69
81
|
})
|
|
70
82
|
|
|
71
|
-
test('mints a key with
|
|
72
|
-
const { client, store } =
|
|
73
|
-
const
|
|
83
|
+
test('mints a key with concrete Zone read and write scopes', async () => {
|
|
84
|
+
const { client, store } = await setup()
|
|
85
|
+
const scopes = ['zone:421700001:read', 'zone:421700001:write'] as const
|
|
74
86
|
const response = await client['api-keys'].$post({
|
|
75
|
-
json: { ...validBody, scopes
|
|
87
|
+
json: { ...validBody, scopes },
|
|
76
88
|
})
|
|
77
89
|
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
78
90
|
|
|
79
91
|
expect(response.status).toBe(200)
|
|
80
|
-
expect(body.scopes).toEqual(
|
|
81
|
-
expect((await core_ApiKeys.resolve(store, body.token))?.scopes).toEqual(
|
|
92
|
+
expect(body.scopes).toEqual(scopes)
|
|
93
|
+
expect((await core_ApiKeys.resolve(store, body.token))?.scopes).toEqual(scopes)
|
|
82
94
|
})
|
|
83
95
|
|
|
84
96
|
test('records the expiry when provided', async () => {
|
|
85
|
-
const { client, store } =
|
|
97
|
+
const { client, store } = await setup()
|
|
86
98
|
const expiresAt = '2100-01-01T00:00:00.000Z'
|
|
87
99
|
const response = await client['api-keys'].$post({ json: { ...validBody, expiresAt } })
|
|
88
100
|
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
@@ -93,7 +105,7 @@ describe('POST /api-keys', () => {
|
|
|
93
105
|
})
|
|
94
106
|
|
|
95
107
|
test('rejects an unknown scope with 400', async () => {
|
|
96
|
-
const { client } =
|
|
108
|
+
const { client } = await setup()
|
|
97
109
|
const response = await client['api-keys'].$post({
|
|
98
110
|
// Cast past the typed client to exercise runtime validation.
|
|
99
111
|
json: { ...validBody, scopes: ['nope:read'] } as never,
|
|
@@ -105,8 +117,13 @@ describe('POST /api-keys', () => {
|
|
|
105
117
|
})
|
|
106
118
|
|
|
107
119
|
test('rejects non-concrete or non-canonical Zone scopes with 400', async () => {
|
|
108
|
-
for (const scope of [
|
|
109
|
-
|
|
120
|
+
for (const scope of [
|
|
121
|
+
'zone:<chainId>:read',
|
|
122
|
+
'zone:0:read',
|
|
123
|
+
'zone:0:write',
|
|
124
|
+
'zone:000421700001:read',
|
|
125
|
+
]) {
|
|
126
|
+
const { client } = await setup()
|
|
110
127
|
const response = await client['api-keys'].$post({
|
|
111
128
|
// Cast past the typed client to exercise runtime validation.
|
|
112
129
|
json: { ...validBody, scopes: [scope] } as never,
|
|
@@ -119,7 +136,7 @@ describe('POST /api-keys', () => {
|
|
|
119
136
|
})
|
|
120
137
|
|
|
121
138
|
test('ignores a client-supplied createdBy (audit trail is server-set)', async () => {
|
|
122
|
-
const { client } =
|
|
139
|
+
const { client } = await setup()
|
|
123
140
|
const response = await client['api-keys'].$post({
|
|
124
141
|
// Cast past the typed client: the body schema omits createdBy, so an
|
|
125
142
|
// unknown key is stripped and the server records the verified identity.
|
|
@@ -130,8 +147,68 @@ describe('POST /api-keys', () => {
|
|
|
130
147
|
expect(response.status).toBe(200)
|
|
131
148
|
expect(body.createdBy).toBe(TestAdmin.identity.email)
|
|
132
149
|
})
|
|
150
|
+
|
|
151
|
+
test('allows a one-off key without organization attribution', async () => {
|
|
152
|
+
const { client, store } = TestAdmin.setup()
|
|
153
|
+
const response = await client['api-keys'].$post({
|
|
154
|
+
json: { name: 'Trial', scopes: ['data:read'] },
|
|
155
|
+
})
|
|
156
|
+
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
157
|
+
|
|
158
|
+
expect(response.status).toBe(200)
|
|
159
|
+
expect(body.orgId).toBe(body.id)
|
|
160
|
+
expect((await core_ApiKeys.resolve(store, body.token))?.orgId).toBe(body.id)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test('rejects an unknown organization', async () => {
|
|
164
|
+
const { client } = TestAdmin.setup()
|
|
165
|
+
const response = await client['api-keys'].$post({ json: validBody })
|
|
166
|
+
|
|
167
|
+
expect(response.status).toBe(404)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
test('infers organization attribution from a project', async () => {
|
|
171
|
+
const { client, db, store } = TestAdmin.setup()
|
|
172
|
+
const organization = await Organizations.create(db, { name: 'Project owner' })
|
|
173
|
+
const project = await Projects.create(db, { name: 'Project', orgId: organization.id })
|
|
174
|
+
const response = await client['api-keys'].$post({
|
|
175
|
+
json: { name: 'Project key', projectId: project.id, scopes: ['data:read'] },
|
|
176
|
+
})
|
|
177
|
+
const body = await TestApp.json(response, ApiKeys.schema.createApiKey.Response)
|
|
178
|
+
|
|
179
|
+
expect(response.status).toBe(200)
|
|
180
|
+
expect(body.orgId).toBe(organization.id)
|
|
181
|
+
expect(body.projectId).toBe(project.id)
|
|
182
|
+
expect((await core_ApiKeys.resolve(store, body.token))?.orgId).toBe(organization.id)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
test('rejects an unknown project', async () => {
|
|
186
|
+
const { client } = await setup()
|
|
187
|
+
const response = await client['api-keys'].$post({
|
|
188
|
+
json: { ...validBody, projectId: 'prj_missing' },
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
expect(response.status).toBe(404)
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
test('rejects a project owned by another organization', async () => {
|
|
195
|
+
const { client, db } = await setup()
|
|
196
|
+
const other = await Organizations.create(db, { name: 'Other' })
|
|
197
|
+
const project = await Projects.create(db, { name: 'Other project', orgId: other.id })
|
|
198
|
+
const response = await client['api-keys'].$post({
|
|
199
|
+
json: { ...validBody, projectId: project.id },
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
expect(response.status).toBe(404)
|
|
203
|
+
})
|
|
133
204
|
})
|
|
134
205
|
|
|
206
|
+
async function setup() {
|
|
207
|
+
const context = TestAdmin.setup()
|
|
208
|
+
await Organizations.create(context.db, { id: validBody.orgId, name: 'Test' })
|
|
209
|
+
return context
|
|
210
|
+
}
|
|
211
|
+
|
|
135
212
|
describe('GET /api-keys', () => {
|
|
136
213
|
test('lists records as metadata only (never the token)', async () => {
|
|
137
214
|
const { client, store } = TestAdmin.setup()
|
|
@@ -142,6 +219,11 @@ describe('GET /api-keys', () => {
|
|
|
142
219
|
|
|
143
220
|
expect(response.status).toBe(200)
|
|
144
221
|
expect(body.data).toHaveLength(1)
|
|
222
|
+
expect(body.data[0]).toMatchObject({
|
|
223
|
+
createdByLabel: null,
|
|
224
|
+
organizationName: null,
|
|
225
|
+
projectName: null,
|
|
226
|
+
})
|
|
145
227
|
// No record (and no serialized response) may carry the plaintext token.
|
|
146
228
|
expect(body.data[0]).not.toHaveProperty('token')
|
|
147
229
|
expect(JSON.stringify(body)).not.toContain(token)
|
|
@@ -157,6 +239,30 @@ describe('GET /api-keys', () => {
|
|
|
157
239
|
|
|
158
240
|
expect(body.data.map((record) => record.orgId)).toEqual(['org_a'])
|
|
159
241
|
})
|
|
242
|
+
|
|
243
|
+
test('resolves organization, project, and creator display labels', async () => {
|
|
244
|
+
const { client, db, store } = TestAdmin.setup()
|
|
245
|
+
const user = await Users.upsertByAddress(db, { address: `0x${'aa'.repeat(20)}` })
|
|
246
|
+
await Users.setEmail(db, user.id, 'alex@tempo.xyz')
|
|
247
|
+
const organization = await Organizations.create(db, { name: 'Tempo' })
|
|
248
|
+
const project = await Projects.create(db, { name: 'Explorer', orgId: organization.id })
|
|
249
|
+
await core_ApiKeys.mint(store, {
|
|
250
|
+
createdBy: user.id,
|
|
251
|
+
name: 'Explorer testnet',
|
|
252
|
+
orgId: organization.id,
|
|
253
|
+
projectId: project.id,
|
|
254
|
+
scopes: ['data:read'],
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
const response = await client['api-keys'].$get({ query: {} })
|
|
258
|
+
const body = await TestApp.json(response, ApiKeys.schema.listApiKeys.Response)
|
|
259
|
+
|
|
260
|
+
expect(body.data[0]).toMatchObject({
|
|
261
|
+
createdByLabel: 'alex@tempo.xyz',
|
|
262
|
+
organizationName: 'Tempo',
|
|
263
|
+
projectName: 'Explorer',
|
|
264
|
+
})
|
|
265
|
+
})
|
|
160
266
|
})
|
|
161
267
|
|
|
162
268
|
describe('DELETE /api-keys/:id', () => {
|
|
@@ -184,22 +290,60 @@ describe('DELETE /api-keys/:id', () => {
|
|
|
184
290
|
})
|
|
185
291
|
|
|
186
292
|
describe('PATCH /api-keys/:id', () => {
|
|
187
|
-
test('
|
|
188
|
-
const { client, store } = TestAdmin.setup()
|
|
189
|
-
const
|
|
293
|
+
test('renames and associates a one-off key without changing its token', async () => {
|
|
294
|
+
const { client, db, store } = TestAdmin.setup()
|
|
295
|
+
const organization = await Organizations.create(db, { name: 'Tempo' })
|
|
296
|
+
const { record, token } = await core_ApiKeys.mint(store, {
|
|
297
|
+
name: 'Trial',
|
|
298
|
+
scopes: ['data:read'],
|
|
299
|
+
})
|
|
190
300
|
|
|
191
301
|
const response = await client['api-keys'][':id'].$patch({
|
|
192
|
-
json: {
|
|
302
|
+
json: { name: 'Explorer', orgId: organization.id, projectId: 'prj_real' },
|
|
193
303
|
param: { id: record.id },
|
|
194
304
|
})
|
|
195
305
|
expect(response.status).toBe(200)
|
|
196
306
|
const body = await TestApp.json(response, core_ApiKeys.schema.Record)
|
|
197
|
-
expect(body.
|
|
307
|
+
expect(body.name).toBe('Explorer')
|
|
308
|
+
expect(body.orgId).toBe(organization.id)
|
|
198
309
|
expect(body.projectId).toBe('prj_real')
|
|
199
310
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
expect(
|
|
311
|
+
expect((await core_ApiKeys.resolve(store, token))?.orgId).toBe(organization.id)
|
|
312
|
+
expect(await core_ApiKeys.listByOrg(store, record.id)).toEqual([])
|
|
313
|
+
expect((await core_ApiKeys.listByOrg(store, organization.id)).map(({ id }) => id)).toEqual([
|
|
314
|
+
record.id,
|
|
315
|
+
])
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
test('rejects an unknown organization without changing the key', async () => {
|
|
319
|
+
const { client, store } = TestAdmin.setup()
|
|
320
|
+
const { record } = await core_ApiKeys.mint(store, { scopes: ['data:read'] })
|
|
321
|
+
const response = await client['api-keys'][':id'].$patch({
|
|
322
|
+
json: { orgId: 'org_missing' },
|
|
323
|
+
param: { id: record.id },
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
expect(response.status).toBe(404)
|
|
327
|
+
expect((await core_ApiKeys.get(store, record.id))?.orgId).toBe(record.id)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
test('rejects changing an assigned organization', async () => {
|
|
331
|
+
const { client, db, store } = TestAdmin.setup()
|
|
332
|
+
const organization = await Organizations.create(db, { name: 'Tempo' })
|
|
333
|
+
const other = await Organizations.create(db, { name: 'Other' })
|
|
334
|
+
const { record, token } = await core_ApiKeys.mint(store, {
|
|
335
|
+
orgId: organization.id,
|
|
336
|
+
scopes: ['data:read'],
|
|
337
|
+
})
|
|
338
|
+
const response = await client['api-keys'][':id'].$patch({
|
|
339
|
+
json: { orgId: other.id },
|
|
340
|
+
param: { id: record.id },
|
|
341
|
+
})
|
|
342
|
+
const body = (await response.json()) as { error?: { code?: string } }
|
|
343
|
+
|
|
344
|
+
expect(response.status).toBe(409)
|
|
345
|
+
expect(body.error?.code).toBe('organization_already_assigned')
|
|
346
|
+
expect((await core_ApiKeys.resolve(store, token))?.orgId).toBe(organization.id)
|
|
203
347
|
})
|
|
204
348
|
|
|
205
349
|
test('unknown id → 404', async () => {
|