tapimo 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/ApiKey.js +1 -1
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +95 -14
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +360 -49
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12457 -10365
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +300 -22
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +2 -1
- package/dist/Assets.js.map +1 -1
- package/dist/Handler.d.ts +0 -1
- package/dist/Handler.d.ts.map +1 -1
- package/dist/Handler.js +0 -1
- package/dist/Handler.js.map +1 -1
- package/dist/Scope.d.ts +13 -5
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +16 -5
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.js +1 -1
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +3057 -549
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +26 -5
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +159 -7
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +95 -43
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +1398 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +463 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +267 -15
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +241 -25
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/routes-support.d.ts +95 -0
- package/dist/admin/apps/routes-support.d.ts.map +1 -0
- package/dist/admin/apps/routes-support.js +151 -0
- package/dist/admin/apps/routes-support.js.map +1 -0
- package/dist/admin/apps/routes.d.ts +2764 -0
- package/dist/admin/apps/routes.d.ts.map +1 -0
- package/dist/admin/apps/routes.js +728 -0
- package/dist/admin/apps/routes.js.map +1 -0
- package/dist/admin/apps/subsidies.d.ts +501 -0
- package/dist/admin/apps/subsidies.d.ts.map +1 -0
- package/dist/admin/apps/subsidies.js +384 -0
- package/dist/admin/apps/subsidies.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +88 -88
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +3 -3
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +129 -69
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +5 -2
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +31 -1
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +2 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +10 -1
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/analytics/tables/routesLifecycleIntervals.d.ts +72 -0
- package/dist/analytics/tables/routesLifecycleIntervals.d.ts.map +1 -0
- package/dist/analytics/tables/routesLifecycleIntervals.js +56 -0
- package/dist/analytics/tables/routesLifecycleIntervals.js.map +1 -0
- package/dist/apps/Zones.d.ts +21 -12526
- package/dist/apps/Zones.d.ts.map +1 -1
- package/dist/apps/Zones.js +37 -5
- package/dist/apps/Zones.js.map +1 -1
- package/dist/apps/data/App.d.ts +3971 -2595
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +76 -21
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +364 -34
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +495 -190
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +72 -0
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +37 -37
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
- package/dist/apps/data/routes/coingecko.js +47 -21
- package/dist/apps/data/routes/coingecko.js.map +1 -1
- package/dist/apps/data/routes/earn.d.ts +1450 -337
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +1226 -144
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +5 -0
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +31 -19
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +125 -0
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +83 -27
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +507 -33
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +266 -156
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +47 -15
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +68 -11
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +2 -0
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +26 -14
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +28 -12
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +9 -7
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +30 -30
- package/dist/apps/data/routes/verified-tokens.d.ts +9 -9
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +64 -20
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +613 -176
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +291 -195
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts.map +1 -1
- package/dist/apps/data/routes/zones.js +20 -12
- package/dist/apps/data/routes/zones.js.map +1 -1
- package/dist/apps/docs/reference.js +2 -2
- package/dist/apps/docs/reference.js.map +1 -1
- package/dist/apps/index.d.ts +1 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +1 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +3763 -3385
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +5 -14
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/Billing.d.ts +48 -7
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +204 -25
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +106 -4
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +43 -15
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +290 -4
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +274 -49
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/faucet.js +1 -1
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +77 -2
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +117 -13
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +4 -4
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +6 -2
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +30 -30
- package/dist/apps/management/routes/orgs.d.ts +18 -2
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +52 -12
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +4 -4
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +6 -1
- 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 +4 -1
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +24 -24
- package/dist/apps/management/routes/usage.js +21 -4
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +2 -2
- package/dist/apps/management/routes/webhooks.d.ts +280 -214
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +58 -12
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mcp.d.ts +1 -1
- package/dist/apps/mcp.js +7 -7
- package/dist/apps/mcp.js.map +1 -1
- package/dist/apps/mpp/App.d.ts.map +1 -1
- package/dist/apps/mpp/App.js +35 -7
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +2 -0
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +30 -1
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/apps/mpp/internal/Policy.d.ts +22 -4
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Policy.js +24 -6
- package/dist/apps/mpp/internal/Policy.js.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.d.ts +3 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.js +6 -3
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
- package/dist/apps/relay/App.d.ts +2 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +134 -75
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +5 -3
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +209 -28
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/apps/{funding → routes}/Access.d.ts +4 -4
- package/dist/apps/routes/Access.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/Access.js +4 -4
- package/dist/apps/routes/Access.js.map +1 -0
- package/dist/apps/{funding → routes}/App.d.ts +418 -124
- package/dist/apps/{funding → routes}/App.d.ts.map +1 -1
- package/dist/apps/{funding → routes}/App.js +16 -16
- package/dist/apps/routes/App.js.map +1 -0
- package/dist/apps/routes/Inventory.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/Inventory.js +2 -2
- package/dist/apps/routes/Inventory.js.map +1 -0
- package/dist/apps/routes/index.d.ts +2 -0
- package/dist/apps/routes/index.d.ts.map +1 -0
- package/dist/apps/routes/index.js +2 -0
- package/dist/apps/routes/index.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/chains.d.ts +7 -7
- package/dist/apps/routes/routes/chains.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/chains.js +25 -25
- package/dist/apps/routes/routes/chains.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/deposit-addresses.d.ts +107 -43
- package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/deposit-addresses.js +497 -222
- package/dist/apps/routes/routes/deposit-addresses.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/providers.d.ts +8 -8
- package/dist/apps/routes/routes/providers.d.ts.map +1 -0
- package/dist/apps/routes/routes/providers.js +57 -0
- package/dist/apps/routes/routes/providers.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/quotes.d.ts +19 -16
- package/dist/apps/routes/routes/quotes.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/quotes.js +55 -38
- package/dist/apps/routes/routes/quotes.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/transfers.d.ts +379 -74
- package/dist/apps/routes/routes/transfers.d.ts.map +1 -0
- package/dist/apps/routes/routes/transfers.js +1140 -0
- package/dist/apps/routes/routes/transfers.js.map +1 -0
- package/dist/cli/Cli.d.ts +30 -0
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/commands/admin.d.ts +36 -0
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/admin.js +273 -0
- package/dist/cli/commands/admin.js.map +1 -1
- package/dist/cloudflare.d.ts +16 -14
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +26 -21
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +63 -21
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +1030 -15
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +780 -133
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +575 -162
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts +4 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts.map +1 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.js +2 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.js.map +1 -0
- package/dist/db/tables/apiKeyAdmissions.d.ts +73 -0
- package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -0
- package/dist/db/tables/apiKeyAdmissions.js +142 -0
- package/dist/db/tables/apiKeyAdmissions.js.map +1 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.d.ts +4 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.d.ts.map +1 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.js +2 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.js.map +1 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts +20 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -0
- package/dist/db/tables/apiKeyOwnerTombstones.js +57 -0
- package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -0
- package/dist/db/tables/apiKeyRevocations.d.ts +21 -0
- package/dist/db/tables/apiKeyRevocations.d.ts.map +1 -0
- package/dist/db/tables/apiKeyRevocations.js +98 -0
- package/dist/db/tables/apiKeyRevocations.js.map +1 -0
- package/dist/db/tables/authAccounts.d.ts +47 -0
- package/dist/db/tables/authAccounts.d.ts.map +1 -0
- package/dist/db/tables/authAccounts.js +72 -0
- package/dist/db/tables/authAccounts.js.map +1 -0
- package/dist/db/tables/authSessions.d.ts +12 -0
- package/dist/db/tables/authSessions.d.ts.map +1 -0
- package/dist/db/tables/authSessions.js +2 -0
- package/dist/db/tables/authSessions.js.map +1 -0
- package/dist/db/tables/authVerifications.d.ts +12 -0
- package/dist/db/tables/authVerifications.d.ts.map +1 -0
- package/dist/db/tables/authVerifications.js +2 -0
- package/dist/db/tables/authVerifications.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +17 -1
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +123 -43
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/memberships.d.ts +8 -0
- package/dist/db/tables/memberships.d.ts.map +1 -1
- package/dist/db/tables/memberships.js +51 -2
- package/dist/db/tables/memberships.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +32 -10
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +110 -49
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +2 -0
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +12 -3
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/rewardAccounts.d.ts +86 -0
- package/dist/db/tables/rewardAccounts.d.ts.map +1 -0
- package/dist/db/tables/rewardAccounts.js +88 -0
- package/dist/db/tables/rewardAccounts.js.map +1 -0
- package/dist/db/tables/rewardCampaignDistributors.d.ts +36 -0
- package/dist/db/tables/rewardCampaignDistributors.d.ts.map +1 -0
- package/dist/db/tables/rewardCampaignDistributors.js +30 -0
- package/dist/db/tables/rewardCampaignDistributors.js.map +1 -0
- package/dist/db/tables/rewardCampaigns.d.ts +171 -0
- package/dist/db/tables/rewardCampaigns.d.ts.map +1 -0
- package/dist/db/tables/rewardCampaigns.js +392 -0
- package/dist/db/tables/rewardCampaigns.js.map +1 -0
- package/dist/db/tables/rewardCredits.d.ts +53 -0
- package/dist/db/tables/rewardCredits.d.ts.map +1 -0
- package/dist/db/tables/rewardCredits.js +63 -0
- package/dist/db/tables/rewardCredits.js.map +1 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts +61 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -0
- package/dist/db/tables/rewardEligibilityAssociations.js +103 -0
- package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -0
- package/dist/db/tables/rewardRuns.d.ts +188 -0
- package/dist/db/tables/rewardRuns.d.ts.map +1 -0
- package/dist/db/tables/rewardRuns.js +278 -0
- package/dist/db/tables/rewardRuns.js.map +1 -0
- package/dist/db/tables/rewardTransactionAttempts.d.ts +100 -0
- package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -0
- package/dist/db/tables/rewardTransactionAttempts.js +163 -0
- package/dist/db/tables/rewardTransactionAttempts.js.map +1 -0
- package/dist/db/tables/routesCatalog.d.ts +58 -0
- package/dist/db/tables/routesCatalog.d.ts.map +1 -0
- package/dist/db/tables/{fundingCatalog.js → routesCatalog.js} +19 -19
- package/dist/db/tables/routesCatalog.js.map +1 -0
- package/dist/db/tables/routesDepositAddresses.d.ts +476 -0
- package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -0
- package/dist/db/tables/routesDepositAddresses.js +587 -0
- package/dist/db/tables/routesDepositAddresses.js.map +1 -0
- package/dist/db/tables/{fundingDepositRequestObservations.d.ts → routesDepositRequestObservations.d.ts} +6 -6
- package/dist/db/tables/routesDepositRequestObservations.d.ts.map +1 -0
- package/dist/db/tables/{fundingDepositRequestObservations.js → routesDepositRequestObservations.js} +6 -6
- package/dist/db/tables/routesDepositRequestObservations.js.map +1 -0
- package/dist/db/tables/{fundingDeposits.d.ts → routesDeposits.d.ts} +210 -22
- package/dist/db/tables/routesDeposits.d.ts.map +1 -0
- package/dist/db/tables/routesDeposits.js +576 -0
- package/dist/db/tables/routesDeposits.js.map +1 -0
- package/dist/db/tables/routesIdempotency.d.ts +166 -0
- package/dist/db/tables/routesIdempotency.d.ts.map +1 -0
- package/dist/db/tables/routesIdempotency.js +330 -0
- package/dist/db/tables/routesIdempotency.js.map +1 -0
- package/dist/db/tables/routesSubsidies.d.ts +27 -0
- package/dist/db/tables/routesSubsidies.d.ts.map +1 -0
- package/dist/db/tables/routesSubsidies.js +45 -0
- package/dist/db/tables/routesSubsidies.js.map +1 -0
- package/dist/db/tables/{fundingTransferEvents.d.ts → routesTransferEvents.d.ts} +3 -3
- package/dist/db/tables/routesTransferEvents.d.ts.map +1 -0
- package/dist/db/tables/{fundingTransferEvents.js → routesTransferEvents.js} +3 -3
- package/dist/db/tables/routesTransferEvents.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts +19 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.js +17 -0
- package/dist/db/tables/routesTransferSubsidies.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts +51 -0
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -0
- package/dist/db/tables/routesTransferSubsidyNonces.js +82 -0
- package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -0
- package/dist/db/tables/routesTransferTransactions.d.ts +77 -0
- package/dist/db/tables/routesTransferTransactions.d.ts.map +1 -0
- package/dist/db/tables/{fundingTransferTransactions.js → routesTransferTransactions.js} +31 -13
- package/dist/db/tables/routesTransferTransactions.js.map +1 -0
- package/dist/db/tables/routesTransfers.d.ts +319 -0
- package/dist/db/tables/routesTransfers.d.ts.map +1 -0
- package/dist/db/tables/routesTransfers.js +372 -0
- package/dist/db/tables/routesTransfers.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +75 -20
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +124 -54
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/sponsorshipAttributions.d.ts +69 -0
- package/dist/db/tables/sponsorshipAttributions.d.ts.map +1 -0
- package/dist/db/tables/sponsorshipAttributions.js +77 -0
- package/dist/db/tables/sponsorshipAttributions.js.map +1 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.d.ts +22 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.d.ts.map +1 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.js +45 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.js.map +1 -0
- package/dist/db/tables/stripeCustomers.d.ts +11 -0
- package/dist/db/tables/stripeCustomers.d.ts.map +1 -1
- package/dist/db/tables/stripeCustomers.js +13 -0
- package/dist/db/tables/stripeCustomers.js.map +1 -1
- package/dist/db/tables/users.d.ts +17 -1
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +47 -2
- package/dist/db/tables/users.js.map +1 -1
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +5 -1
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +19 -11
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +45 -13
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/executionError.d.ts +2 -2
- package/dist/handlers/internal/executionError.d.ts.map +1 -1
- package/dist/handlers/internal/executionError.js +1 -2
- package/dist/handlers/internal/executionError.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +4 -232
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +11 -537
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/internal/sponsorship.d.ts +19 -8
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
- package/dist/handlers/internal/sponsorship.js +13 -9
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/relay.d.ts +9 -12
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +81 -85
- package/dist/handlers/relay.js.map +1 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +1 -1
- package/dist/internal/AssetResponse.d.ts +12 -0
- package/dist/internal/AssetResponse.d.ts.map +1 -0
- package/dist/internal/AssetResponse.js +21 -0
- package/dist/internal/AssetResponse.js.map +1 -0
- package/dist/internal/Auth.d.ts +48 -12
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +603 -175
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/BetterAuth.d.ts +1488 -0
- package/dist/internal/BetterAuth.d.ts.map +1 -0
- package/dist/internal/BetterAuth.js +253 -0
- package/dist/internal/BetterAuth.js.map +1 -0
- package/dist/internal/Cache.d.ts +2 -0
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +2 -0
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnRates.d.ts +26 -3
- package/dist/internal/EarnRates.d.ts.map +1 -1
- package/dist/internal/EarnRates.js +84 -19
- package/dist/internal/EarnRates.js.map +1 -1
- package/dist/internal/EarnSharePrices.d.ts +120 -0
- package/dist/internal/EarnSharePrices.d.ts.map +1 -0
- package/dist/internal/EarnSharePrices.js +179 -0
- package/dist/internal/EarnSharePrices.js.map +1 -0
- package/dist/internal/EarnVaults.d.ts +4 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +27 -10
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Email.d.ts +37 -0
- package/dist/internal/Email.d.ts.map +1 -0
- package/dist/internal/Email.js +16 -0
- package/dist/internal/Email.js.map +1 -0
- package/dist/internal/Log.d.ts +32 -28
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +18 -11
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts +3 -0
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +67 -8
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/Mpp.d.ts.map +1 -1
- package/dist/internal/Mpp.js +20 -25
- package/dist/internal/Mpp.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +26 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +25 -10
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Provider.d.ts +1 -1
- package/dist/internal/Provider.d.ts.map +1 -1
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +13 -1
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +59 -8
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +9 -2
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +78 -11
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timing.d.ts +26 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +63 -5
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/VercelOidc.d.ts +94 -0
- package/dist/internal/VercelOidc.d.ts.map +1 -0
- package/dist/internal/VercelOidc.js +128 -0
- package/dist/internal/VercelOidc.js.map +1 -0
- package/dist/internal/VerifiedTokens.d.ts +2 -8
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +24 -24
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Viem.d.ts +30 -2067
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +167 -17
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +12 -4
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +9 -3
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/ZoneRpc.d.ts +7 -0
- package/dist/internal/ZoneRpc.d.ts.map +1 -0
- package/dist/internal/ZoneRpc.js +49 -0
- package/dist/internal/ZoneRpc.js.map +1 -0
- package/dist/internal/index.d.ts +3 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +3 -1
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/rewards/Audit.d.ts +88 -0
- package/dist/internal/rewards/Audit.d.ts.map +1 -0
- package/dist/internal/rewards/Audit.js +134 -0
- package/dist/internal/rewards/Audit.js.map +1 -0
- package/dist/internal/rewards/Campaigns.d.ts +572 -0
- package/dist/internal/rewards/Campaigns.d.ts.map +1 -0
- package/dist/internal/rewards/Campaigns.js +531 -0
- package/dist/internal/rewards/Campaigns.js.map +1 -0
- package/dist/internal/rewards/Credits.d.ts +76 -0
- package/dist/internal/rewards/Credits.d.ts.map +1 -0
- package/dist/internal/rewards/Credits.js +95 -0
- package/dist/internal/rewards/Credits.js.map +1 -0
- package/dist/internal/rewards/Events.d.ts +100 -0
- package/dist/internal/rewards/Events.d.ts.map +1 -0
- package/dist/internal/rewards/Events.js +340 -0
- package/dist/internal/rewards/Events.js.map +1 -0
- package/dist/internal/rewards/Projection.d.ts +237 -0
- package/dist/internal/rewards/Projection.d.ts.map +1 -0
- package/dist/internal/rewards/Projection.js +616 -0
- package/dist/internal/rewards/Projection.js.map +1 -0
- package/dist/internal/rewards/Rates.d.ts +44 -0
- package/dist/internal/rewards/Rates.d.ts.map +1 -0
- package/dist/internal/rewards/Rates.js +60 -0
- package/dist/internal/rewards/Rates.js.map +1 -0
- package/dist/internal/rewards/Read.d.ts +158 -0
- package/dist/internal/rewards/Read.d.ts.map +1 -0
- package/dist/internal/rewards/Read.js +292 -0
- package/dist/internal/rewards/Read.js.map +1 -0
- package/dist/internal/rewards/Runner.d.ts +164 -0
- package/dist/internal/rewards/Runner.d.ts.map +1 -0
- package/dist/internal/rewards/Runner.js +1778 -0
- package/dist/internal/rewards/Runner.js.map +1 -0
- package/dist/internal/rewards/Signer.d.ts +224 -0
- package/dist/internal/rewards/Signer.d.ts.map +1 -0
- package/dist/internal/rewards/Signer.js +135 -0
- package/dist/internal/rewards/Signer.js.map +1 -0
- package/dist/internal/rewards/index.d.ts +15 -0
- package/dist/internal/rewards/index.d.ts.map +1 -0
- package/dist/internal/rewards/index.js +15 -0
- package/dist/internal/rewards/index.js.map +1 -0
- package/dist/internal/{funding → routes}/Action.d.ts +12 -1
- package/dist/internal/routes/Action.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Action.js +17 -9
- package/dist/internal/routes/Action.js.map +1 -0
- package/dist/internal/{funding → routes}/Catalog.d.ts +20 -20
- package/dist/internal/routes/Catalog.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Catalog.js +29 -29
- package/dist/internal/routes/Catalog.js.map +1 -0
- package/dist/internal/{funding → routes}/Chain.d.ts +10 -10
- package/dist/internal/routes/Chain.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Chain.js +3 -3
- package/dist/internal/routes/Chain.js.map +1 -0
- package/dist/internal/{funding → routes}/Deposit.d.ts +45 -23
- package/dist/internal/routes/Deposit.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Deposit.js +60 -27
- package/dist/internal/routes/Deposit.js.map +1 -0
- package/dist/internal/{funding → routes}/DepositAddress.d.ts +56 -27
- package/dist/internal/routes/DepositAddress.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/DepositAddress.js +95 -33
- package/dist/internal/routes/DepositAddress.js.map +1 -0
- package/dist/internal/{funding → routes}/DepositWebhook.d.ts +4 -4
- package/dist/internal/routes/DepositWebhook.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/DepositWebhook.js +4 -4
- package/dist/internal/routes/DepositWebhook.js.map +1 -0
- package/dist/internal/routes/Economics.d.ts +25 -0
- package/dist/internal/routes/Economics.d.ts.map +1 -0
- package/dist/internal/routes/Economics.js +28 -0
- package/dist/internal/routes/Economics.js.map +1 -0
- package/dist/internal/{funding → routes}/Evidence.d.ts +3 -3
- package/dist/internal/routes/Evidence.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Evidence.js +7 -7
- package/dist/internal/routes/Evidence.js.map +1 -0
- package/dist/internal/routes/Observability.d.ts +154 -0
- package/dist/internal/routes/Observability.d.ts.map +1 -0
- package/dist/internal/routes/Observability.js +389 -0
- package/dist/internal/routes/Observability.js.map +1 -0
- package/dist/internal/{funding → routes}/Provider.d.ts +311 -105
- package/dist/internal/routes/Provider.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Provider.js +229 -98
- package/dist/internal/routes/Provider.js.map +1 -0
- package/dist/internal/{funding → routes}/Reconciliation.d.ts +11 -6
- package/dist/internal/routes/Reconciliation.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Reconciliation.js +408 -158
- package/dist/internal/routes/Reconciliation.js.map +1 -0
- package/dist/internal/routes/Route.d.ts +21 -0
- package/dist/internal/routes/Route.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Route.js +1 -1
- package/dist/internal/routes/Route.js.map +1 -0
- package/dist/internal/{funding → routes}/SourceObservation.d.ts +6 -6
- package/dist/internal/routes/SourceObservation.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/SourceObservation.js +8 -8
- package/dist/internal/routes/SourceObservation.js.map +1 -0
- package/dist/internal/{funding → routes}/Subsidy.d.ts +48 -3
- package/dist/internal/routes/Subsidy.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Subsidy.js +43 -3
- package/dist/internal/routes/Subsidy.js.map +1 -0
- package/dist/internal/{funding → routes}/Token.d.ts +4 -4
- package/dist/internal/routes/Token.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Token.js +3 -3
- package/dist/internal/routes/Token.js.map +1 -0
- package/dist/internal/{funding → routes}/Transfer.d.ts +241 -46
- package/dist/internal/routes/Transfer.d.ts.map +1 -0
- package/dist/internal/routes/Transfer.js +728 -0
- package/dist/internal/routes/Transfer.js.map +1 -0
- package/dist/internal/{funding → routes}/TransferReconciliation.d.ts +13 -10
- package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -0
- package/dist/internal/routes/TransferReconciliation.js +422 -0
- package/dist/internal/routes/TransferReconciliation.js.map +1 -0
- package/dist/internal/routes/TransferSubsidy.d.ts +201 -0
- package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/TransferSubsidy.js +256 -0
- package/dist/internal/routes/TransferSubsidy.js.map +1 -0
- package/dist/internal/{funding → routes}/TransferWebhook.d.ts +5 -5
- package/dist/internal/routes/TransferWebhook.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/TransferWebhook.js +3 -3
- package/dist/internal/routes/TransferWebhook.js.map +1 -0
- package/dist/internal/{funding → routes}/index.d.ts +2 -0
- package/dist/internal/routes/index.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/index.js +2 -0
- package/dist/internal/routes/index.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/across.d.ts +4 -4
- package/dist/internal/routes/providers/across.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/across.js +13 -13
- package/dist/internal/routes/providers/across.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/relay.d.ts +21 -12
- package/dist/internal/routes/providers/relay.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/relay.js +194 -110
- package/dist/internal/routes/providers/relay.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/rhino.d.ts +4 -4
- package/dist/internal/routes/providers/rhino.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/rhino.js +10 -10
- package/dist/internal/routes/providers/rhino.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/squid.d.ts +4 -4
- package/dist/internal/routes/providers/squid.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/squid.js +14 -14
- package/dist/internal/routes/providers/squid.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/stargate.d.ts +46 -18
- package/dist/internal/routes/providers/stargate.d.ts.map +1 -0
- package/dist/internal/routes/providers/stargate.js +898 -0
- package/dist/internal/routes/providers/stargate.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/symbiosis.d.ts +4 -4
- package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/symbiosis.js +30 -20
- package/dist/internal/routes/providers/symbiosis.js.map +1 -0
- package/dist/internal/webhookDestinations/slack.js +12 -12
- package/dist/internal/webhookDestinations/slack.js.map +1 -1
- package/dist/providers/index.d.ts +12 -12
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +12 -12
- package/dist/providers/index.js.map +1 -1
- package/dist/server.d.ts +19 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +19 -0
- package/dist/server.js.map +1 -0
- package/package.json +15 -4
- package/src/ApiKey.ts +1 -1
- package/src/ApiKeys.test.ts +1033 -3
- package/src/ApiKeys.ts +489 -48
- package/src/App.test-d.ts +1 -1
- package/src/App.test.ts +216 -25
- package/src/App.ts +334 -31
- package/src/Assets.test.ts +2 -2
- package/src/Assets.ts +3 -1
- package/src/Auth.test-d.ts +1 -1
- package/src/Client.test-d.ts +539 -110
- package/src/Handler.ts +0 -1
- package/src/OpenApi.contract.test.ts +195 -0
- package/src/Scope.ts +17 -5
- package/src/Webhooks.ts +1 -1
- package/src/admin/App.test.ts +30 -2
- package/src/admin/App.ts +42 -6
- package/src/admin/apps/api-keys.test.ts +267 -5
- package/src/admin/apps/api-keys.ts +100 -50
- package/src/admin/apps/earn-vaults.test.ts +158 -0
- package/src/admin/apps/earn-vaults.ts +679 -6
- package/src/admin/apps/organizations.test.ts +306 -17
- package/src/admin/apps/organizations.ts +299 -24
- package/src/admin/apps/routes-support.test.ts +200 -0
- package/src/admin/apps/routes-support.ts +201 -0
- package/src/admin/apps/routes.test.ts +450 -0
- package/src/admin/apps/routes.ts +896 -0
- package/src/admin/apps/scopes.test.ts +15 -5
- package/src/admin/apps/subsidies.test.ts +306 -0
- package/src/admin/apps/subsidies.ts +457 -0
- package/src/admin/apps/verified-tokens.test.ts +8 -3
- package/src/admin/apps/verified-tokens.ts +3 -3
- package/src/admin/ui/plugin.ts +1 -2
- package/src/admin/ui/src/components/RewardCampaignForm.tsx +1009 -0
- package/src/admin/ui/src/lib/config.ts +11 -2
- package/src/admin/ui/src/lib/earn-vaults.ts +2 -2
- package/src/admin/ui/src/lib/organizations.test.ts +83 -50
- package/src/admin/ui/src/lib/organizations.ts +106 -25
- package/src/admin/ui/src/lib/query-client.ts +1 -1
- package/src/admin/ui/src/lib/reward-campaigns.ts +136 -0
- package/src/admin/ui/src/lib/routes.test.ts +88 -0
- package/src/admin/ui/src/lib/routes.ts +304 -0
- package/src/admin/ui/src/lib/subsidies.ts +75 -0
- package/src/admin/ui/src/routeTree.gen.ts +63 -0
- package/src/admin/ui/src/routes/__root.tsx +12 -1
- package/src/admin/ui/src/routes/api-keys.tsx +196 -84
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +105 -70
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +239 -23
- package/src/admin/ui/src/routes/routes.tsx +1615 -0
- package/src/admin/ui/src/routes/routes_.support.tsx +248 -0
- package/src/admin/ui/src/routes/subsidies.tsx +799 -0
- package/src/admin/ui.generated.ts +144 -69
- package/src/analytics/Analytics.test.ts +108 -18
- package/src/analytics/Analytics.ts +38 -6
- package/src/analytics/tables/requestEvents.test.ts +100 -0
- package/src/analytics/tables/requestEvents.ts +10 -1
- package/src/analytics/tables/routesLifecycleIntervals.ts +140 -0
- package/src/apps/Zones.test.ts +15 -0
- package/src/apps/Zones.ts +52 -5
- package/src/apps/composition.test.ts +68 -60
- package/src/apps/data/App.test.ts +154 -2
- package/src/apps/data/App.ts +88 -28
- package/src/apps/data/routes/activities.test.ts +419 -7
- package/src/apps/data/routes/activities.ts +683 -216
- package/src/apps/data/routes/balances.test.ts +2 -2
- package/src/apps/data/routes/blocks.test.ts +46 -1
- package/src/apps/data/routes/coingecko.test.ts +419 -1
- package/src/apps/data/routes/coingecko.ts +309 -253
- package/src/apps/data/routes/earn.discovery.test.ts +274 -0
- package/src/apps/data/routes/earn.test.ts +1294 -17
- package/src/apps/data/routes/earn.ts +1838 -321
- package/src/apps/data/routes/exchanges.test.ts +12 -15
- package/src/apps/data/routes/fee-amm.test.ts +224 -0
- package/src/apps/data/routes/fee-amm.ts +191 -160
- package/src/apps/data/routes/indexer.test.ts +389 -0
- package/src/apps/data/routes/indexer.ts +165 -69
- package/src/apps/data/routes/receipts.test.ts +1 -1
- package/src/apps/data/routes/rpc.test.ts +352 -8
- package/src/apps/data/routes/rpc.ts +407 -219
- package/src/apps/data/routes/rpc.zone.test.ts +340 -0
- package/src/apps/data/routes/tokenlist.test.ts +285 -0
- package/src/apps/data/routes/tokenlist.ts +173 -88
- package/src/apps/data/routes/tokens.test.ts +93 -3
- package/src/apps/data/routes/tokens.ts +39 -23
- package/src/apps/data/routes/transactions.test.ts +1 -1
- package/src/apps/data/routes/transfers.test.ts +56 -24
- package/src/apps/data/routes/transfers.ts +19 -8
- package/src/apps/data/routes/valuation.test.ts +1 -1
- package/src/apps/data/routes/verified-tokens.test.ts +345 -0
- package/src/apps/data/routes/verified-tokens.ts +99 -29
- package/src/apps/data/routes/webhooks.test.ts +645 -83
- package/src/apps/data/routes/webhooks.ts +1089 -857
- package/src/apps/data/routes/zones.test.ts +148 -71
- package/src/apps/data/routes/zones.ts +71 -55
- package/src/apps/docs/reference.ts +2 -2
- package/src/apps/index.ts +1 -1
- package/src/apps/management/App.ts +9 -51
- package/src/apps/management/Billing.test.ts +375 -14
- package/src/apps/management/Billing.ts +265 -29
- package/src/apps/management/routes/api-keys.test.ts +269 -7
- package/src/apps/management/routes/api-keys.ts +61 -20
- package/src/apps/management/routes/billing.test.ts +477 -15
- package/src/apps/management/routes/billing.ts +377 -50
- package/src/apps/management/routes/faucet.test.ts +1 -1
- package/src/apps/management/routes/faucet.ts +1 -1
- package/src/apps/management/routes/invitations.test.ts +270 -3
- package/src/apps/management/routes/invitations.ts +185 -15
- package/src/apps/management/routes/invoicePreview.test.ts +549 -0
- package/src/apps/management/routes/me.test.ts +246 -5
- package/src/apps/management/routes/me.ts +7 -2
- package/src/apps/management/routes/members.test.ts +108 -0
- package/src/apps/management/routes/orgs.test.ts +191 -3
- package/src/apps/management/routes/orgs.ts +58 -11
- package/src/apps/management/routes/projects.test.ts +33 -3
- package/src/apps/management/routes/projects.ts +6 -1
- package/src/apps/management/routes/scopes.test.ts +30 -2
- package/src/apps/management/routes/scopes.ts +4 -1
- package/src/apps/management/routes/usage.test.ts +32 -0
- package/src/apps/management/routes/usage.ts +22 -4
- package/src/apps/management/routes/webhooks.test.ts +49 -26
- package/src/apps/management/routes/webhooks.ts +78 -22
- package/src/apps/mcp.test.ts +6 -6
- package/src/apps/mcp.ts +7 -7
- package/src/apps/mpp/App.ts +37 -7
- package/src/apps/mpp/Mpp.test.ts +49 -8
- package/src/apps/mpp/Mpp.zone.test.ts +219 -0
- package/src/apps/mpp/internal/Adapter.ts +34 -0
- package/src/apps/mpp/internal/Policy.test.ts +86 -31
- package/src/apps/mpp/internal/Policy.ts +49 -7
- package/src/apps/mpp/internal/Sponsorship.test.ts +207 -0
- package/src/apps/mpp/internal/Sponsorship.ts +9 -3
- package/src/apps/relay/App.test.ts +839 -64
- package/src/apps/relay/App.ts +148 -81
- package/src/apps/relay/App.zone-billing.test.ts +257 -0
- package/src/apps/relay/Sponsorships.test.ts +67 -4
- package/src/apps/relay/Sponsorships.ts +233 -32
- package/src/apps/relay/Sponsorships.zone.test.ts +102 -0
- package/src/apps/{funding → routes}/Access.ts +6 -6
- package/src/apps/routes/App.test.ts +165 -0
- package/src/apps/routes/App.ts +96 -0
- package/src/apps/{funding → routes}/Inventory.ts +2 -2
- package/src/apps/routes/index.ts +1 -0
- package/src/apps/{funding → routes}/routes/chains.test.ts +66 -66
- package/src/apps/{funding → routes}/routes/chains.ts +23 -23
- package/src/apps/{funding → routes}/routes/deposit-addresses.test.ts +1358 -458
- package/src/apps/{funding → routes}/routes/deposit-addresses.ts +566 -246
- package/src/apps/{funding → routes}/routes/providers.test.ts +27 -33
- package/src/apps/{funding → routes}/routes/providers.ts +23 -23
- package/src/apps/{funding → routes}/routes/quotes.test.ts +298 -41
- package/src/apps/{funding → routes}/routes/quotes.ts +57 -40
- package/src/apps/{funding → routes}/routes/transfers.test.ts +1100 -353
- package/src/apps/routes/routes/transfers.ts +1332 -0
- package/src/cli/Cli.test.ts +1 -1
- package/src/cli/commands/admin.test.ts +748 -1
- package/src/cli/commands/admin.ts +278 -0
- package/src/cloudflare.ts +52 -47
- package/src/db/Db.test.ts +245 -2
- package/src/db/Db.ts +1476 -34
- package/src/db/Schema.ts +729 -228
- package/src/db/tables/apiKeyAdmissionBootstraps.ts +4 -0
- package/src/db/tables/apiKeyAdmissions.ts +218 -0
- package/src/db/tables/apiKeyOwnerAdmissions.ts +4 -0
- package/src/db/tables/apiKeyOwnerTombstones.ts +81 -0
- package/src/db/tables/apiKeyRevocations.test.ts +74 -0
- package/src/db/tables/apiKeyRevocations.ts +121 -0
- package/src/db/tables/authAccounts.ts +105 -0
- package/src/db/tables/authSessions.ts +13 -0
- package/src/db/tables/authVerifications.ts +13 -0
- package/src/db/tables/invitations.ts +142 -45
- package/src/db/tables/memberships.ts +79 -3
- package/src/db/tables/organizations.test.ts +690 -13
- package/src/db/tables/organizations.ts +139 -55
- package/src/db/tables/projects.test.ts +16 -0
- package/src/db/tables/projects.ts +13 -3
- package/src/db/tables/requestUsage.ts +4 -1
- package/src/db/tables/rewardAccounts.ts +178 -0
- package/src/db/tables/rewardCampaignDistributors.ts +68 -0
- package/src/db/tables/rewardCampaigns.test.ts +1388 -0
- package/src/db/tables/rewardCampaigns.ts +647 -0
- package/src/db/tables/rewardCredits.ts +110 -0
- package/src/db/tables/rewardEligibilityAssociations.test.ts +271 -0
- package/src/db/tables/rewardEligibilityAssociations.ts +184 -0
- package/src/db/tables/rewardRuns.ts +514 -0
- package/src/db/tables/rewardTransactionAttempts.ts +272 -0
- package/src/db/tables/routesCatalog.test.ts +185 -0
- package/src/db/tables/routesCatalog.ts +163 -0
- package/src/db/tables/routesDepositAddresses.test.ts +1048 -0
- package/src/db/tables/routesDepositAddresses.ts +1008 -0
- package/src/db/tables/{fundingDepositRequestObservations.test.ts → routesDepositRequestObservations.test.ts} +13 -14
- package/src/db/tables/{fundingDepositRequestObservations.ts → routesDepositRequestObservations.ts} +10 -10
- package/src/db/tables/{fundingDeposits.test.ts → routesDeposits.test.ts} +316 -46
- package/src/db/tables/routesDeposits.ts +1062 -0
- package/src/db/tables/routesIdempotency.test.ts +796 -0
- package/src/db/tables/routesIdempotency.ts +496 -0
- package/src/db/tables/routesSubsidies.test.ts +120 -0
- package/src/db/tables/routesSubsidies.ts +71 -0
- package/src/db/tables/{fundingTransferEvents.ts → routesTransferEvents.ts} +4 -4
- package/src/db/tables/routesTransferSubsidies.ts +38 -0
- package/src/db/tables/routesTransferSubsidyNonces.ts +124 -0
- package/src/db/tables/routesTransferTransactions.test.ts +195 -0
- package/src/db/tables/{fundingTransferTransactions.ts → routesTransferTransactions.ts} +63 -18
- package/src/db/tables/routesTransfers.test.ts +338 -0
- package/src/db/tables/routesTransfers.ts +662 -0
- package/src/db/tables/sponsoredTransactions.test.ts +269 -45
- package/src/db/tables/sponsoredTransactions.ts +225 -65
- package/src/db/tables/sponsorshipAttributions.test.ts +160 -0
- package/src/db/tables/sponsorshipAttributions.ts +168 -0
- package/src/db/tables/sponsorshipReconciliationCursors.test.ts +115 -0
- package/src/db/tables/sponsorshipReconciliationCursors.ts +67 -0
- package/src/db/tables/stripeCustomers.test.ts +85 -0
- package/src/db/tables/stripeCustomers.ts +24 -0
- package/src/db/tables/users.test.ts +129 -0
- package/src/db/tables/users.ts +49 -3
- package/src/db/tables/webhookQueueEvents.ts +8 -1
- package/src/db/tables/webhookSubscriptions.ts +95 -20
- package/src/handlers/internal/executionError.ts +3 -4
- package/src/handlers/internal/multisig.ts +13 -816
- package/src/handlers/internal/sponsorship.ts +26 -10
- package/src/handlers/relay.test-d.ts +9 -1
- package/src/handlers/relay.test.ts +823 -3
- package/src/handlers/relay.ts +127 -107
- package/src/index.test-d.ts +7 -0
- package/src/index.ts +0 -17
- package/src/internal/AssetResponse.ts +26 -0
- package/src/internal/Auth.test.ts +1564 -9
- package/src/internal/Auth.ts +833 -239
- package/src/internal/BetterAuth.test.ts +242 -0
- package/src/internal/BetterAuth.ts +349 -0
- package/src/internal/Cache.ts +2 -0
- package/src/internal/EarnRates.test.ts +17 -0
- package/src/internal/EarnRates.ts +124 -31
- package/src/internal/EarnSharePrices.test.ts +182 -0
- package/src/internal/EarnSharePrices.ts +313 -0
- package/src/internal/EarnVaults.test.ts +21 -0
- package/src/internal/EarnVaults.ts +33 -11
- package/src/internal/Email.ts +54 -0
- package/src/internal/Idempotency.test.ts +2 -2
- package/src/internal/Log.test-d.ts +8 -7
- package/src/internal/Log.test.ts +114 -16
- package/src/internal/Log.ts +53 -40
- package/src/internal/MetricSink.test.ts +313 -26
- package/src/internal/MetricSink.ts +73 -8
- package/src/internal/Mpp.test.ts +31 -0
- package/src/internal/Mpp.ts +21 -24
- package/src/internal/OpenApi.ts +45 -12
- package/src/internal/Provider.test.ts +1 -1
- package/src/internal/Provider.ts +1 -1
- package/src/internal/RateLimit.test.ts +21 -3
- package/src/internal/RateLimit.ts +12 -1
- package/src/internal/Store.test-d.ts +1 -1
- package/src/internal/Store.test.ts +151 -8
- package/src/internal/Store.ts +76 -9
- package/src/internal/Tidx.test.ts +59 -8
- package/src/internal/Tidx.ts +86 -14
- package/src/internal/Timing.test.ts +77 -0
- package/src/internal/Timing.ts +83 -6
- package/src/internal/VercelOidc.test.ts +188 -0
- package/src/internal/VercelOidc.ts +193 -0
- package/src/internal/VerifiedTokens.test.ts +60 -6
- package/src/internal/VerifiedTokens.ts +21 -24
- package/src/internal/Viem.batch.test.ts +80 -0
- package/src/internal/Viem.test.ts +201 -2
- package/src/internal/Viem.ts +221 -25
- package/src/internal/Webhooks.test.ts +85 -6
- package/src/internal/Webhooks.ts +22 -4
- package/src/internal/ZoneRpc.ts +50 -0
- package/src/internal/exchange/Provider.test.ts +2 -2
- package/src/internal/index.test.ts +3 -1
- package/src/internal/index.ts +3 -1
- package/src/internal/rewards/Audit.ts +231 -0
- package/src/internal/rewards/Campaigns.test.ts +1234 -0
- package/src/internal/rewards/Campaigns.ts +1205 -0
- package/src/internal/rewards/Credits.ts +165 -0
- package/src/internal/rewards/Events.local.test.ts +113 -0
- package/src/internal/rewards/Events.test.ts +152 -0
- package/src/internal/rewards/Events.ts +468 -0
- package/src/internal/rewards/Projection.test.ts +681 -0
- package/src/internal/rewards/Projection.ts +987 -0
- package/src/internal/rewards/Rates.test.ts +171 -0
- package/src/internal/rewards/Rates.ts +110 -0
- package/src/internal/rewards/Read.test.ts +501 -0
- package/src/internal/rewards/Read.ts +476 -0
- package/src/internal/rewards/Runner.checkpoint.test.ts +80 -0
- package/src/internal/rewards/Runner.states.test.ts +188 -0
- package/src/internal/rewards/Runner.test.ts +90 -0
- package/src/internal/rewards/Runner.ts +2229 -0
- package/src/internal/rewards/Signer.test.ts +79 -0
- package/src/internal/rewards/Signer.ts +180 -0
- package/src/internal/rewards/index.ts +14 -0
- package/src/internal/{funding → routes}/Action.test.ts +63 -14
- package/src/internal/{funding → routes}/Action.ts +35 -8
- package/src/internal/{funding → routes}/Catalog.test.ts +3 -3
- package/src/internal/{funding → routes}/Catalog.ts +39 -39
- package/src/internal/{funding → routes}/Chain.test.ts +1 -1
- package/src/internal/{funding → routes}/Chain.ts +11 -11
- package/src/internal/{funding → routes}/Deposit.test.ts +1 -1
- package/src/internal/{funding → routes}/Deposit.ts +93 -45
- package/src/internal/{funding → routes}/DepositAddress.test.ts +11 -3
- package/src/internal/{funding → routes}/DepositAddress.ts +132 -53
- package/src/internal/{funding → routes}/DepositWebhook.test.ts +61 -18
- package/src/internal/{funding → routes}/DepositWebhook.ts +9 -9
- package/src/internal/routes/Economics.test.ts +42 -0
- package/src/internal/routes/Economics.ts +47 -0
- package/src/internal/{funding → routes}/Evidence.test.ts +6 -6
- package/src/internal/{funding → routes}/Evidence.ts +9 -9
- package/src/internal/routes/Observability.test.ts +636 -0
- package/src/internal/routes/Observability.ts +668 -0
- package/src/internal/{funding → routes}/Provider.test.ts +489 -153
- package/src/internal/{funding → routes}/Provider.ts +489 -186
- package/src/internal/{funding → routes}/Reconciliation.local.test.ts +84 -12
- package/src/internal/{funding → routes}/Reconciliation.test.ts +1213 -279
- package/src/internal/{funding → routes}/Reconciliation.ts +501 -203
- package/src/internal/routes/Reconciliation.unattributed.test.ts +250 -0
- package/src/internal/{funding → routes}/Route.ts +7 -7
- package/src/internal/{funding → routes}/SourceObservation.test.ts +13 -14
- package/src/internal/{funding → routes}/SourceObservation.ts +13 -13
- package/src/internal/{funding → routes}/Subsidy.local.test.ts +7 -7
- package/src/internal/routes/Subsidy.test.ts +169 -0
- package/src/internal/{funding → routes}/Subsidy.ts +86 -6
- package/src/internal/{funding → routes}/Token.test.ts +1 -1
- package/src/internal/{funding → routes}/Token.ts +5 -5
- package/src/internal/routes/Transfer.test.ts +1199 -0
- package/src/internal/routes/Transfer.ts +1206 -0
- package/src/internal/routes/TransferReconciliation.test.ts +731 -0
- package/src/internal/routes/TransferReconciliation.ts +527 -0
- package/src/internal/routes/TransferSubsidy.test.ts +172 -0
- package/src/internal/routes/TransferSubsidy.ts +447 -0
- package/src/internal/{funding → routes}/TransferWebhook.test.ts +13 -13
- package/src/internal/{funding → routes}/TransferWebhook.ts +7 -7
- package/src/internal/{funding → routes}/index.test.ts +5 -3
- package/src/internal/{funding → routes}/index.ts +2 -0
- package/src/internal/{funding → routes}/providers/across.ts +16 -16
- package/src/internal/{funding → routes}/providers/index.test.ts +157 -44
- package/src/internal/{funding → routes}/providers/relay.test.ts +165 -32
- package/src/internal/{funding → routes}/providers/relay.ts +228 -121
- package/src/internal/{funding → routes}/providers/rhino.ts +16 -16
- package/src/internal/{funding → routes}/providers/squid.ts +17 -17
- package/src/internal/routes/providers/stargate.test.ts +728 -0
- package/src/internal/routes/providers/stargate.ts +1276 -0
- package/src/internal/{funding → routes}/providers/symbiosis.ts +64 -24
- package/src/internal/webhookDestinations/slack.ts +10 -10
- package/src/providers/index.ts +13 -13
- package/src/server.ts +18 -0
- package/dist/apps/funding/Access.d.ts.map +0 -1
- package/dist/apps/funding/Access.js.map +0 -1
- package/dist/apps/funding/App.js.map +0 -1
- package/dist/apps/funding/Inventory.d.ts.map +0 -1
- package/dist/apps/funding/Inventory.js.map +0 -1
- package/dist/apps/funding/ProviderAttempts.d.ts +0 -5
- package/dist/apps/funding/ProviderAttempts.d.ts.map +0 -1
- package/dist/apps/funding/ProviderAttempts.js +0 -24
- package/dist/apps/funding/ProviderAttempts.js.map +0 -1
- package/dist/apps/funding/index.d.ts +0 -2
- package/dist/apps/funding/index.d.ts.map +0 -1
- package/dist/apps/funding/index.js +0 -2
- package/dist/apps/funding/index.js.map +0 -1
- package/dist/apps/funding/routes/chains.d.ts.map +0 -1
- package/dist/apps/funding/routes/chains.js.map +0 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +0 -1
- package/dist/apps/funding/routes/deposit-addresses.js.map +0 -1
- package/dist/apps/funding/routes/providers.d.ts.map +0 -1
- package/dist/apps/funding/routes/providers.js +0 -57
- package/dist/apps/funding/routes/providers.js.map +0 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +0 -1
- package/dist/apps/funding/routes/quotes.js.map +0 -1
- package/dist/apps/funding/routes/transfers.d.ts.map +0 -1
- package/dist/apps/funding/routes/transfers.js +0 -828
- package/dist/apps/funding/routes/transfers.js.map +0 -1
- package/dist/db/tables/fundingCatalog.d.ts +0 -58
- package/dist/db/tables/fundingCatalog.d.ts.map +0 -1
- package/dist/db/tables/fundingCatalog.js.map +0 -1
- package/dist/db/tables/fundingDepositAddresses.d.ts +0 -192
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +0 -1
- package/dist/db/tables/fundingDepositAddresses.js +0 -235
- package/dist/db/tables/fundingDepositAddresses.js.map +0 -1
- package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +0 -1
- package/dist/db/tables/fundingDepositRequestObservations.js.map +0 -1
- package/dist/db/tables/fundingDeposits.d.ts.map +0 -1
- package/dist/db/tables/fundingDeposits.js +0 -295
- package/dist/db/tables/fundingDeposits.js.map +0 -1
- package/dist/db/tables/fundingIdempotency.d.ts +0 -91
- package/dist/db/tables/fundingIdempotency.d.ts.map +0 -1
- package/dist/db/tables/fundingIdempotency.js +0 -103
- package/dist/db/tables/fundingIdempotency.js.map +0 -1
- package/dist/db/tables/fundingTransferEvents.d.ts.map +0 -1
- package/dist/db/tables/fundingTransferEvents.js.map +0 -1
- package/dist/db/tables/fundingTransferTransactions.d.ts +0 -53
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +0 -1
- package/dist/db/tables/fundingTransferTransactions.js.map +0 -1
- package/dist/db/tables/fundingTransfers.d.ts +0 -99
- package/dist/db/tables/fundingTransfers.d.ts.map +0 -1
- package/dist/db/tables/fundingTransfers.js +0 -110
- package/dist/db/tables/fundingTransfers.js.map +0 -1
- package/dist/internal/funding/Action.d.ts.map +0 -1
- package/dist/internal/funding/Action.js.map +0 -1
- package/dist/internal/funding/Catalog.d.ts.map +0 -1
- package/dist/internal/funding/Catalog.js.map +0 -1
- package/dist/internal/funding/Chain.d.ts.map +0 -1
- package/dist/internal/funding/Chain.js.map +0 -1
- package/dist/internal/funding/Deposit.d.ts.map +0 -1
- package/dist/internal/funding/Deposit.js.map +0 -1
- package/dist/internal/funding/DepositAddress.d.ts.map +0 -1
- package/dist/internal/funding/DepositAddress.js.map +0 -1
- package/dist/internal/funding/DepositWebhook.d.ts.map +0 -1
- package/dist/internal/funding/DepositWebhook.js.map +0 -1
- package/dist/internal/funding/Evidence.d.ts.map +0 -1
- package/dist/internal/funding/Evidence.js.map +0 -1
- package/dist/internal/funding/Provider.d.ts.map +0 -1
- package/dist/internal/funding/Provider.js.map +0 -1
- package/dist/internal/funding/Reconciliation.d.ts.map +0 -1
- package/dist/internal/funding/Reconciliation.js.map +0 -1
- package/dist/internal/funding/Route.d.ts +0 -21
- package/dist/internal/funding/Route.d.ts.map +0 -1
- package/dist/internal/funding/Route.js.map +0 -1
- package/dist/internal/funding/SourceObservation.d.ts.map +0 -1
- package/dist/internal/funding/SourceObservation.js.map +0 -1
- package/dist/internal/funding/Subsidy.d.ts.map +0 -1
- package/dist/internal/funding/Subsidy.js.map +0 -1
- package/dist/internal/funding/Token.d.ts.map +0 -1
- package/dist/internal/funding/Token.js.map +0 -1
- package/dist/internal/funding/Transfer.d.ts.map +0 -1
- package/dist/internal/funding/Transfer.js +0 -462
- package/dist/internal/funding/Transfer.js.map +0 -1
- package/dist/internal/funding/TransferReconciliation.d.ts.map +0 -1
- package/dist/internal/funding/TransferReconciliation.js +0 -192
- package/dist/internal/funding/TransferReconciliation.js.map +0 -1
- package/dist/internal/funding/TransferWebhook.d.ts.map +0 -1
- package/dist/internal/funding/TransferWebhook.js.map +0 -1
- package/dist/internal/funding/index.d.ts.map +0 -1
- package/dist/internal/funding/index.js.map +0 -1
- package/dist/internal/funding/providers/across.d.ts.map +0 -1
- package/dist/internal/funding/providers/across.js.map +0 -1
- package/dist/internal/funding/providers/relay.d.ts.map +0 -1
- package/dist/internal/funding/providers/relay.js.map +0 -1
- package/dist/internal/funding/providers/rhino.d.ts.map +0 -1
- package/dist/internal/funding/providers/rhino.js.map +0 -1
- package/dist/internal/funding/providers/squid.d.ts.map +0 -1
- package/dist/internal/funding/providers/squid.js.map +0 -1
- package/dist/internal/funding/providers/stargate.d.ts.map +0 -1
- package/dist/internal/funding/providers/stargate.js +0 -579
- package/dist/internal/funding/providers/stargate.js.map +0 -1
- package/dist/internal/funding/providers/symbiosis.d.ts.map +0 -1
- package/dist/internal/funding/providers/symbiosis.js.map +0 -1
- package/src/apps/funding/App.test.ts +0 -78
- package/src/apps/funding/App.ts +0 -88
- package/src/apps/funding/ProviderAttempts.ts +0 -26
- package/src/apps/funding/index.ts +0 -1
- package/src/apps/funding/routes/transfers.ts +0 -987
- package/src/db/tables/fundingCatalog.test.ts +0 -122
- package/src/db/tables/fundingCatalog.ts +0 -163
- package/src/db/tables/fundingDepositAddresses.test.ts +0 -608
- package/src/db/tables/fundingDepositAddresses.ts +0 -443
- package/src/db/tables/fundingDeposits.ts +0 -572
- package/src/db/tables/fundingIdempotency.test.ts +0 -182
- package/src/db/tables/fundingIdempotency.ts +0 -180
- package/src/db/tables/fundingTransferTransactions.test.ts +0 -112
- package/src/db/tables/fundingTransfers.test.ts +0 -115
- package/src/db/tables/fundingTransfers.ts +0 -189
- package/src/handlers/internal/multisig.test.ts +0 -818
- package/src/internal/funding/Subsidy.test.ts +0 -75
- package/src/internal/funding/Transfer.test.ts +0 -524
- package/src/internal/funding/Transfer.ts +0 -762
- package/src/internal/funding/TransferReconciliation.test.ts +0 -147
- package/src/internal/funding/TransferReconciliation.ts +0 -264
- package/src/internal/funding/providers/stargate.test.ts +0 -328
- package/src/internal/funding/providers/stargate.ts +0 -856
- /package/dist/apps/{funding → routes}/Inventory.d.ts +0 -0
- /package/src/internal/{funding → routes}/Route.test.ts +0 -0
package/src/internal/Auth.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import * as Accounts from 'accounts/server'
|
|
2
|
+
import { splitSetCookieHeader } from 'better-auth/cookies'
|
|
2
3
|
import { Hono } from 'hono'
|
|
3
4
|
import type { Context as hono_Context, MiddlewareHandler } from 'hono'
|
|
5
|
+
import { deleteCookie, getCookie, setCookie } from 'hono/cookie'
|
|
4
6
|
import type { HonoBase } from 'hono/hono-base'
|
|
5
7
|
import { createMiddleware } from 'hono/factory'
|
|
6
8
|
import { matchedRoutes } from 'hono/route'
|
|
7
9
|
import type { MergePath, RouterRoute, Schema as core_Schema } from 'hono/types'
|
|
8
10
|
import { findTargetHandler } from 'hono/utils/handler'
|
|
11
|
+
import * as jose from 'jose'
|
|
12
|
+
import { sql } from 'kysely'
|
|
9
13
|
import { Challenge, Credential, type Method } from 'mppx'
|
|
10
14
|
import { Mppx, tempo } from 'mppx/hono'
|
|
15
|
+
import { Address, Hex } from 'ox'
|
|
11
16
|
import { Addresses } from 'viem/tempo'
|
|
12
17
|
import { tempoMainnet } from 'viem/tempo/chains'
|
|
13
18
|
import * as z from 'zod/mini'
|
|
@@ -15,25 +20,68 @@ import * as z from 'zod/mini'
|
|
|
15
20
|
import type * as App from '../App.js'
|
|
16
21
|
import * as ApiKey from '../ApiKey.js'
|
|
17
22
|
import * as ApiKeys from '../ApiKeys.js'
|
|
23
|
+
import * as ApiKeyAdmissions from '../db/tables/apiKeyAdmissions.js'
|
|
24
|
+
import * as ApiKeyOwnerTombstones from '../db/tables/apiKeyOwnerTombstones.js'
|
|
25
|
+
import * as AuthAccounts from '../db/tables/authAccounts.js'
|
|
26
|
+
import * as BetterAuth from './BetterAuth.js'
|
|
18
27
|
import * as Db from '../db/Db.js'
|
|
19
|
-
import type * as
|
|
28
|
+
import type * as Email from './Email.js'
|
|
20
29
|
import * as Memberships from '../db/tables/memberships.js'
|
|
21
30
|
import * as IpAllowlist from './IpAllowlist.js'
|
|
22
31
|
import * as Metadata from '../apps/metadata.js'
|
|
23
32
|
import * as OpenApi from './OpenApi.js'
|
|
24
33
|
import * as Organizations from '../db/tables/organizations.js'
|
|
34
|
+
import * as Path from './Path.js'
|
|
25
35
|
import * as Projects from '../db/tables/projects.js'
|
|
26
36
|
import * as RateLimit from './RateLimit.js'
|
|
27
37
|
import * as Response from './Response.js'
|
|
28
38
|
import * as Schema from './Schema.js'
|
|
29
39
|
import * as Scope from '../Scope.js'
|
|
40
|
+
import type * as Store from './Store.js'
|
|
41
|
+
import * as Timing from './Timing.js'
|
|
30
42
|
import * as Users from '../db/tables/users.js'
|
|
31
43
|
import type * as Viem from './Viem.js'
|
|
32
44
|
|
|
33
45
|
const policySymbol = Symbol('tempo-api.auth.policy')
|
|
34
46
|
const mppManagementSymbol = Symbol('tempo-api.auth.mpp-management')
|
|
35
47
|
const defaultApiKeyRateLimit = { limit: 10_000, period: 'minute' } satisfies RateLimit.Limit
|
|
48
|
+
const defaultIdentitySessionTtl = 24 * 60 * 60
|
|
36
49
|
const defaultMppRateLimit = { limit: 100, period: 'minute' } satisfies RateLimit.Limit
|
|
50
|
+
const defaultPublicRateLimit = { limit: 60, period: 'minute' } satisfies RateLimit.Limit
|
|
51
|
+
const identityCookieName = 'tempo_identity'
|
|
52
|
+
const walletIdentityIssuer = 'https://wallet.tempo.xyz/api/oidc'
|
|
53
|
+
|
|
54
|
+
type IdentitySession = {
|
|
55
|
+
/** Wallet address asserted by the identity token. */
|
|
56
|
+
address: string
|
|
57
|
+
/** Verified email asserted by the identity token. */
|
|
58
|
+
email?: string | undefined
|
|
59
|
+
/** Unix timestamp when the session expires. */
|
|
60
|
+
expiresAt: number
|
|
61
|
+
/** Unix timestamp when the session was issued. */
|
|
62
|
+
issuedAt: number
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type WalletSession = {
|
|
66
|
+
/** Wallet address used to resolve the canonical user. */
|
|
67
|
+
address: string
|
|
68
|
+
/** Verified email used to reconcile the canonical user. */
|
|
69
|
+
email?: string | undefined
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isIdentityTokenError(error: unknown) {
|
|
73
|
+
return (
|
|
74
|
+
error instanceof jose.errors.JOSEAlgNotAllowed ||
|
|
75
|
+
error instanceof jose.errors.JOSENotSupported ||
|
|
76
|
+
error instanceof jose.errors.JWSInvalid ||
|
|
77
|
+
error instanceof jose.errors.JWKSNoMatchingKey ||
|
|
78
|
+
error instanceof jose.errors.JWSSignatureVerificationFailed ||
|
|
79
|
+
error instanceof jose.errors.JWTClaimValidationFailed ||
|
|
80
|
+
error instanceof jose.errors.JWTExpired ||
|
|
81
|
+
error instanceof jose.errors.JWTInvalid ||
|
|
82
|
+
(error instanceof Error && error.message === 'email not verified')
|
|
83
|
+
)
|
|
84
|
+
}
|
|
37
85
|
|
|
38
86
|
/** Auth context consumed by Tempo API handlers. */
|
|
39
87
|
export type Context = {
|
|
@@ -95,7 +143,10 @@ export type Payment = {
|
|
|
95
143
|
type: 'mpp'
|
|
96
144
|
}
|
|
97
145
|
|
|
98
|
-
/**
|
|
146
|
+
/** Host-provided request backstop that returns a rejection response when over quota. */
|
|
147
|
+
export type EdgeRateLimit = (request: Request) => Promise<Response | undefined>
|
|
148
|
+
|
|
149
|
+
/** MPP route-policy types. Distinct from the authentication {@link Session} capability. */
|
|
99
150
|
export declare namespace Mpp {
|
|
100
151
|
/** MPP Session request options used by route access policies. */
|
|
101
152
|
type Session = Method.RequestDefaults<ReturnType<typeof tempo.session>> & {
|
|
@@ -160,7 +211,7 @@ export type PolicyOverride = {
|
|
|
160
211
|
}
|
|
161
212
|
| boolean
|
|
162
213
|
| undefined
|
|
163
|
-
/** Session lane: `true` allows signed-in
|
|
214
|
+
/** Session lane: `true` allows signed-in sessions, `false` disables. */
|
|
164
215
|
session?: boolean | undefined
|
|
165
216
|
}
|
|
166
217
|
|
|
@@ -197,7 +248,7 @@ export type Principal =
|
|
|
197
248
|
id: string
|
|
198
249
|
/** Identity that established the session, as a provider/subject pair (OIDC `iss`/`sub` semantics). */
|
|
199
250
|
identity: {
|
|
200
|
-
/** Identity provider: `wallet
|
|
251
|
+
/** Identity provider: `email`, `wallet`, or an OIDC issuer. */
|
|
201
252
|
provider: string
|
|
202
253
|
/** Provider-scoped subject — the wallet address for `wallet`. */
|
|
203
254
|
subject: string
|
|
@@ -504,6 +555,20 @@ export function middleware<
|
|
|
504
555
|
endpoint extends string = string,
|
|
505
556
|
environment extends Environment = Environment,
|
|
506
557
|
>(options: middleware.Options<endpoint>): MiddlewareHandler<environment> {
|
|
558
|
+
const resolve = createApiKeyResolver({
|
|
559
|
+
apiKey: options.apiKey,
|
|
560
|
+
scopeCatalog: options.scopeCatalog,
|
|
561
|
+
})
|
|
562
|
+
return createAuthMiddleware(options, resolve)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function createAuthMiddleware<
|
|
566
|
+
endpoint extends string = string,
|
|
567
|
+
environment extends Environment = Environment,
|
|
568
|
+
>(
|
|
569
|
+
options: middleware.Options<endpoint>,
|
|
570
|
+
resolve: ReturnType<typeof createApiKeyResolver>,
|
|
571
|
+
): MiddlewareHandler<environment> {
|
|
507
572
|
const {
|
|
508
573
|
rateLimit: mppRateLimit = defaultMppRateLimit,
|
|
509
574
|
session: session_ = {},
|
|
@@ -522,23 +587,13 @@ export function middleware<
|
|
|
522
587
|
// keyed by token sha256) so hot keys skip the backend read on the auth path
|
|
523
588
|
// of every request. Pass `apiKey.cache: false` when immediate key updates
|
|
524
589
|
// matter more than the per-request read.
|
|
525
|
-
const resolve = (() => {
|
|
526
|
-
const uncached = (c: hono_Context, token: string) => {
|
|
527
|
-
const kv = contextKv(c)
|
|
528
|
-
return kv
|
|
529
|
-
? ApiKeys.resolve(kv.store, token, { scopeCatalog: options.scopeCatalog })
|
|
530
|
-
: Promise.resolve(null)
|
|
531
|
-
}
|
|
532
|
-
if (options.apiKey === false || options.apiKey?.cache === false) return uncached
|
|
533
|
-
return cachedResolve(uncached, options.apiKey?.cache ?? {})
|
|
534
|
-
})()
|
|
535
590
|
const auth: Context = {
|
|
536
591
|
...(options.apiKey === false
|
|
537
592
|
? {}
|
|
538
593
|
: {
|
|
539
594
|
apiKey: {
|
|
540
595
|
...(options.apiKey?.rateLimits ? { rateLimits: options.apiKey.rateLimits } : {}),
|
|
541
|
-
resolve,
|
|
596
|
+
resolve: resolve.resolve,
|
|
542
597
|
},
|
|
543
598
|
}),
|
|
544
599
|
// The throttle ceiling for sandbox keys without active billing, so
|
|
@@ -580,38 +635,124 @@ export function middleware<
|
|
|
580
635
|
}
|
|
581
636
|
|
|
582
637
|
return createMiddleware<environment>((c, next) => {
|
|
583
|
-
const
|
|
584
|
-
if (!
|
|
585
|
-
|
|
586
|
-
const { key, description, management, scope } = route
|
|
587
|
-
const overrides = options.overrides as
|
|
588
|
-
| Record<string, PolicyOverride | false | undefined>
|
|
589
|
-
| undefined
|
|
590
|
-
const routePolicies = policies(c)
|
|
591
|
-
const configuredOverride = (() => {
|
|
592
|
-
const configured = overrides?.[key]
|
|
593
|
-
if (configured !== undefined) return configured
|
|
594
|
-
const inheritedMethod = routePolicies.find(
|
|
595
|
-
(policy) => policy.inheritOverridesFrom,
|
|
596
|
-
)?.inheritOverridesFrom
|
|
597
|
-
if (inheritedMethod === undefined) return undefined
|
|
598
|
-
const inheritedKey = `${inheritedMethod.toUpperCase()} ${key.slice(key.indexOf(' ') + 1)}`
|
|
599
|
-
return overrides?.[inheritedKey]
|
|
600
|
-
})()
|
|
601
|
-
const routeOverride =
|
|
602
|
-
management && configuredOverride ? { mpp: configuredOverride.mpp } : configuredOverride
|
|
603
|
-
const endpointPolicy = bindMppScope(
|
|
604
|
-
resolvePolicy(base, defaults, [...routePolicies, routeOverride], description),
|
|
605
|
-
scope,
|
|
606
|
-
)
|
|
607
|
-
if (!endpointPolicy) return next()
|
|
608
|
-
if (management && (!auth.mpp || !endpointPolicy.mpp)) return next()
|
|
638
|
+
const resolved = resolveRequestPolicy(c, { base, defaults, options })
|
|
639
|
+
if (!resolved) return next()
|
|
609
640
|
|
|
610
641
|
c.set('auth', auth)
|
|
611
|
-
|
|
642
|
+
if (!resolved.policy) return next()
|
|
643
|
+
if (resolved.management && (!auth.mpp || !resolved.policy.mpp)) return next()
|
|
644
|
+
|
|
645
|
+
return require<environment>(resolved.policy)(c, next)
|
|
612
646
|
})
|
|
613
647
|
}
|
|
614
648
|
|
|
649
|
+
function resolveRequestPolicy(c: hono_Context, options: resolveRequestPolicy.Options) {
|
|
650
|
+
const route = openApiRoute(c)
|
|
651
|
+
if (!route) return undefined
|
|
652
|
+
|
|
653
|
+
const { key, description, management, scope } = route
|
|
654
|
+
const overrides = options.options.overrides as
|
|
655
|
+
| Record<string, PolicyOverride | false | undefined>
|
|
656
|
+
| undefined
|
|
657
|
+
const routePolicies = policies(c)
|
|
658
|
+
const configuredOverride = (() => {
|
|
659
|
+
const configured = overrides?.[key]
|
|
660
|
+
if (configured !== undefined) return configured
|
|
661
|
+
const inheritedMethod = routePolicies.find(
|
|
662
|
+
(routePolicy): routePolicy is policy.Options =>
|
|
663
|
+
routePolicy !== false && routePolicy.inheritOverridesFrom !== undefined,
|
|
664
|
+
)?.inheritOverridesFrom
|
|
665
|
+
if (inheritedMethod === undefined) return undefined
|
|
666
|
+
const inheritedKey = `${inheritedMethod.toUpperCase()} ${key.slice(key.indexOf(' ') + 1)}`
|
|
667
|
+
return overrides?.[inheritedKey]
|
|
668
|
+
})()
|
|
669
|
+
const routeOverride =
|
|
670
|
+
management && configuredOverride ? { mpp: configuredOverride.mpp } : configuredOverride
|
|
671
|
+
return {
|
|
672
|
+
management,
|
|
673
|
+
policy: bindMppScope(
|
|
674
|
+
resolvePolicy(options.base, options.defaults, [...routePolicies, routeOverride], description),
|
|
675
|
+
scope,
|
|
676
|
+
),
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
declare namespace resolveRequestPolicy {
|
|
681
|
+
/** Inputs used to resolve the current route's authentication policy. */
|
|
682
|
+
type Options = {
|
|
683
|
+
/** Default-closed base policy. */
|
|
684
|
+
base: require.Policy
|
|
685
|
+
/** Configured lane defaults. */
|
|
686
|
+
defaults: LaneDefaults
|
|
687
|
+
/** Authentication middleware options and route overrides. */
|
|
688
|
+
options: middleware.Options
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
type ApiKeyResolverOptions = {
|
|
693
|
+
/** API-key authentication and cache configuration. */
|
|
694
|
+
apiKey: middleware.Options['apiKey']
|
|
695
|
+
/** Authoritative owner store used to reject orphaned API keys. */
|
|
696
|
+
db?: Db.Source | undefined
|
|
697
|
+
/** Scope catalog accepted while resolving records. */
|
|
698
|
+
scopeCatalog: Scope.Catalog | undefined
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
type RequestApiKeyResolution = {
|
|
702
|
+
/** Resolved API key, or null when the token is invalid. */
|
|
703
|
+
apiKey: ApiKey.ApiKey | null
|
|
704
|
+
/** Hash of the presented token associated with the resolution. */
|
|
705
|
+
tokenHash: string
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
function createApiKeyResolver(options: ApiKeyResolverOptions) {
|
|
709
|
+
const requests = new WeakMap<hono_Context, RequestApiKeyResolution>()
|
|
710
|
+
const uncached = (c: hono_Context, token: string) => {
|
|
711
|
+
const kv = contextKv(c)
|
|
712
|
+
return kv
|
|
713
|
+
? ApiKeys.resolve(kv.store, token, { scopeCatalog: options.scopeCatalog })
|
|
714
|
+
: Promise.resolve(null)
|
|
715
|
+
}
|
|
716
|
+
const cache =
|
|
717
|
+
options.apiKey === false || options.apiKey?.cache === false
|
|
718
|
+
? { invalidate: () => {}, peek: () => undefined, resolve: uncached }
|
|
719
|
+
: cachedResolve(uncached, options.apiKey?.cache ?? {})
|
|
720
|
+
|
|
721
|
+
return {
|
|
722
|
+
peek: (c: hono_Context, token: string) => {
|
|
723
|
+
const tokenHash = ApiKey.hash(token)
|
|
724
|
+
const existing = requests.get(c)
|
|
725
|
+
if (existing?.tokenHash === tokenHash) return existing.apiKey
|
|
726
|
+
return cache.peek(token)
|
|
727
|
+
},
|
|
728
|
+
resolve: async (c: hono_Context, token: string) => {
|
|
729
|
+
const tokenHash = ApiKey.hash(token)
|
|
730
|
+
const existing = requests.get(c)
|
|
731
|
+
if (existing?.tokenHash === tokenHash) return existing.apiKey
|
|
732
|
+
const cached = await cache.resolve(c, token)
|
|
733
|
+
const kv = contextKv(c)
|
|
734
|
+
const apiKey =
|
|
735
|
+
cached &&
|
|
736
|
+
((kv && (await ApiKeys.isOwnerDeleted(kv.store, cached))) ||
|
|
737
|
+
!(await apiKeyOwnerExists(cached, options.db)))
|
|
738
|
+
? null
|
|
739
|
+
: cached
|
|
740
|
+
if (cached && !apiKey) cache.invalidate(token)
|
|
741
|
+
requests.set(c, { apiKey, tokenHash })
|
|
742
|
+
return apiKey
|
|
743
|
+
},
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/** Rejects attributed keys fenced by a committed owner deletion. */
|
|
748
|
+
async function apiKeyOwnerExists(apiKey: ApiKey.ApiKey, source: Db.Source | undefined) {
|
|
749
|
+
if (!source) return true
|
|
750
|
+
const db = Db.get(source)
|
|
751
|
+
if (!(await ApiKeyAdmissions.matches(db, apiKey))) return false
|
|
752
|
+
if (await ApiKeyOwnerTombstones.isDeleted(db, apiKey)) return false
|
|
753
|
+
return true
|
|
754
|
+
}
|
|
755
|
+
|
|
615
756
|
export declare namespace middleware {
|
|
616
757
|
/** Per-route policy overrides keyed by HTTP endpoint. */
|
|
617
758
|
type Overrides<endpoint extends string = string> = Partial<
|
|
@@ -689,7 +830,7 @@ export declare namespace middleware {
|
|
|
689
830
|
}
|
|
690
831
|
}
|
|
691
832
|
|
|
692
|
-
/** Zod schemas documenting the session sign-in surface
|
|
833
|
+
/** Zod schemas documenting the session sign-in surface. */
|
|
693
834
|
namespace schema {
|
|
694
835
|
const siweMessage =
|
|
695
836
|
'api.tempo.xyz wants you to sign in with your Ethereum account:\n0x0000000000000000000000000000000000000000\n\nURI: https://api.tempo.xyz\nVersion: 1\nChain ID: 0\nNonce: 3D0sZfnHqTBmc9tKR\nIssued At: 2026-01-01T00:00:00.000Z\nExpiration Time: 2026-01-01T00:10:00.000Z'
|
|
@@ -710,64 +851,92 @@ namespace schema {
|
|
|
710
851
|
/** Schemas for `POST /v1/auth/siwe/challenge`. */
|
|
711
852
|
export namespace challenge {
|
|
712
853
|
/** Request body. Accepted fields beyond this document pass through to the SDK handler. */
|
|
713
|
-
export const Body = z.object({})
|
|
854
|
+
export const Body = OpenApi.component(z.object({}), 'SiweChallengeRequest')
|
|
714
855
|
|
|
715
856
|
/** Response body. */
|
|
716
|
-
export const Response =
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
857
|
+
export const Response = OpenApi.component(
|
|
858
|
+
z.object({
|
|
859
|
+
message: z
|
|
860
|
+
.string()
|
|
861
|
+
.check(
|
|
862
|
+
z.describe('Single-use EIP-4361 (SIWE) message to sign and submit for verification.'),
|
|
863
|
+
z.meta({ examples: [siweMessage] }),
|
|
864
|
+
),
|
|
865
|
+
}),
|
|
866
|
+
'SiweChallengeResponse',
|
|
867
|
+
)
|
|
724
868
|
}
|
|
725
869
|
|
|
726
870
|
/** Schemas for `POST /v1/auth/siwe` (verify). */
|
|
727
871
|
export namespace verify {
|
|
728
872
|
/** Request body. */
|
|
729
|
-
export const Body =
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
873
|
+
export const Body = OpenApi.component(
|
|
874
|
+
z.object({
|
|
875
|
+
address: z
|
|
876
|
+
.string()
|
|
877
|
+
.check(
|
|
878
|
+
z.describe('Wallet address that signed the message; becomes the session subject.'),
|
|
879
|
+
z.meta({ examples: ['0x0000000000000000000000000000000000000001'] }),
|
|
880
|
+
),
|
|
881
|
+
idToken: z.optional(z.string()).check(
|
|
882
|
+
z.describe('Wallet-minted OIDC identity token (JWT) asserting a verified email, folded onto the session.'), // prettier-ignore
|
|
883
|
+
z.meta({ examples: ['eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIweDAwMDAifQ.c2lnbmF0dXJl'] }),
|
|
735
884
|
),
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
),
|
|
740
|
-
keyAuthorization: z.optional(z.string()).check(
|
|
741
|
-
z.describe('RLP-serialized signed key authorization (TIP-1053) whose witness binds this message; verification recovers over its digest.'), // prettier-ignore
|
|
742
|
-
z.meta({ examples: [`0x${'aa'.repeat(60)}`] }),
|
|
743
|
-
),
|
|
744
|
-
message: z
|
|
745
|
-
.string()
|
|
746
|
-
.check(
|
|
747
|
-
z.describe('The exact challenge message issued by `POST /v1/auth/siwe/challenge`.'),
|
|
748
|
-
z.meta({ examples: [siweMessage] }),
|
|
885
|
+
keyAuthorization: z.optional(z.string()).check(
|
|
886
|
+
z.describe('RLP-serialized signed key authorization (TIP-1053) whose witness binds this message; verification recovers over its digest.'), // prettier-ignore
|
|
887
|
+
z.meta({ examples: [`0x${'aa'.repeat(60)}`] }),
|
|
749
888
|
),
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
.check(
|
|
757
|
-
z.describe('
|
|
758
|
-
z.meta({ examples: [
|
|
889
|
+
message: z
|
|
890
|
+
.string()
|
|
891
|
+
.check(
|
|
892
|
+
z.describe('The exact challenge message issued by `POST /v1/auth/siwe/challenge`.'),
|
|
893
|
+
z.meta({ examples: [siweMessage] }),
|
|
894
|
+
),
|
|
895
|
+
returnToken: z.optional(z.boolean()).check(
|
|
896
|
+
z.describe('Return the session token in the body instead of setting the session cookie.'), // prettier-ignore
|
|
897
|
+
z.meta({ examples: [true] }),
|
|
759
898
|
),
|
|
760
|
-
|
|
899
|
+
signature: z
|
|
900
|
+
.string()
|
|
901
|
+
.check(
|
|
902
|
+
z.describe('Signature over the challenge message (or the key-authorization digest).'),
|
|
903
|
+
z.meta({ examples: [`0x${'aa'.repeat(65)}`] }),
|
|
904
|
+
),
|
|
905
|
+
}),
|
|
906
|
+
'SiweVerifyRequest',
|
|
907
|
+
)
|
|
761
908
|
|
|
762
909
|
/** Response body. */
|
|
763
|
-
export const Response =
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
910
|
+
export const Response = OpenApi.component(
|
|
911
|
+
z.object({
|
|
912
|
+
token: z
|
|
913
|
+
.optional(z.string())
|
|
914
|
+
.check(
|
|
915
|
+
z.describe('Bearer session token; present only when `returnToken` is true.'),
|
|
916
|
+
z.meta({ examples: ['aa'.repeat(32)] }),
|
|
917
|
+
),
|
|
918
|
+
}),
|
|
919
|
+
'SiweVerifyResponse',
|
|
920
|
+
)
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/** Schemas for `POST /v1/auth/identity`. */
|
|
924
|
+
export namespace identity {
|
|
925
|
+
/** Request body. */
|
|
926
|
+
export const Body = OpenApi.component(
|
|
927
|
+
z.object({
|
|
928
|
+
idToken: z
|
|
929
|
+
.string()
|
|
930
|
+
.check(
|
|
931
|
+
z.describe('Wallet-issued OpenID Connect identity token.'),
|
|
932
|
+
z.meta({ examples: ['eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiIweDAwMDAifQ.c2lnbmF0dXJl'] }),
|
|
933
|
+
),
|
|
934
|
+
}),
|
|
935
|
+
'IdentitySignInRequest',
|
|
936
|
+
)
|
|
937
|
+
|
|
938
|
+
/** Response body. */
|
|
939
|
+
export const Response = OpenApi.component(z.object({}), 'IdentitySignInResponse')
|
|
771
940
|
}
|
|
772
941
|
}
|
|
773
942
|
|
|
@@ -787,19 +956,39 @@ function handlerError(description: string) {
|
|
|
787
956
|
*/
|
|
788
957
|
export function install(options: install.Options) {
|
|
789
958
|
const { db, kv, scopeCatalog } = options
|
|
790
|
-
const {
|
|
791
|
-
|
|
959
|
+
const {
|
|
960
|
+
edgeRateLimit: options_edgeRateLimit,
|
|
961
|
+
session: options_session,
|
|
962
|
+
...options_middleware
|
|
963
|
+
} = options.auth === false ? {} : (options.auth ?? {})
|
|
964
|
+
const publicClientIp =
|
|
965
|
+
typeof options_middleware.public === 'object' ? options_middleware.public.clientIp : undefined
|
|
792
966
|
if (options_session && !kv)
|
|
793
967
|
throw new Error('`auth.session` requires the `kv` state store: sessions and sign-in challenges persist there.') // prettier-ignore
|
|
968
|
+
const options_betterAuth = options_session
|
|
969
|
+
? {
|
|
970
|
+
basePath: Path.join(options.basePath, 'v1/auth'),
|
|
971
|
+
clientIp: (request: Request) => resolveTrustedClientIp(request, publicClientIp),
|
|
972
|
+
db,
|
|
973
|
+
get email() {
|
|
974
|
+
return options.email()
|
|
975
|
+
},
|
|
976
|
+
rateLimit: RateLimit.memory(options_middleware.rateLimit),
|
|
977
|
+
secret: options_session.secret,
|
|
978
|
+
...(options_session.google ? { google: options_session.google } : {}),
|
|
979
|
+
...(options_session.trustedOrigins
|
|
980
|
+
? { trustedOrigins: options_session.trustedOrigins }
|
|
981
|
+
: {}),
|
|
982
|
+
}
|
|
983
|
+
: undefined
|
|
794
984
|
|
|
795
985
|
// Session sign-in surface (challenge, verify, logout — SIWE wallet sign-in
|
|
796
986
|
// today) plus the capability the session lane resolves through. Public but
|
|
797
987
|
// policy-gated: the hidden describeRoute engages the middleware for the
|
|
798
988
|
// mounted sub-app, and the public lane rate-limits challenge-store writes.
|
|
799
989
|
const app = (() => {
|
|
800
|
-
if (!options_session || !kv) return undefined
|
|
801
|
-
const { issuer, origin, requireEmail, ttl } =
|
|
802
|
-
(typeof options_session === 'object' ? options_session.wallet : undefined) ?? {}
|
|
990
|
+
if (!options_betterAuth || !options_session || !kv) return undefined
|
|
991
|
+
const { issuer, origin, requireEmail, ttl } = options_session.wallet ?? {}
|
|
803
992
|
|
|
804
993
|
const handler = Accounts.Handler.auth({
|
|
805
994
|
getClient: options.getClient,
|
|
@@ -839,30 +1028,105 @@ export function install(options: install.Options) {
|
|
|
839
1028
|
},
|
|
840
1029
|
...(ttl ? { ttl } : {}),
|
|
841
1030
|
})
|
|
1031
|
+
const identity = options_session.identity
|
|
1032
|
+
const identitySessionTtl = identity?.ttl ?? defaultIdentitySessionTtl
|
|
1033
|
+
const identitySessionKey = (token: string) => `identity:session:${token}`
|
|
1034
|
+
|
|
1035
|
+
async function resolveWallet(payload: WalletSession) {
|
|
1036
|
+
const database = Db.get(db)
|
|
1037
|
+
const verifiedEmail = payload.email?.trim().toLowerCase()
|
|
1038
|
+
return database.kysely.transaction().execute(async (kysely) => {
|
|
1039
|
+
const tx = { ...database, kysely }
|
|
1040
|
+
// Organization creation locks the same address row before resolving
|
|
1041
|
+
// the wallet owner, serializing resource writes with reconciliation.
|
|
1042
|
+
const addressUser = await Users.getByAddressForUpdate(tx, payload.address)
|
|
1043
|
+
if (!addressUser) return null
|
|
1044
|
+
if (verifiedEmail)
|
|
1045
|
+
await sql`SELECT pg_advisory_xact_lock(hashtextextended(${verifiedEmail}, 0))`.execute(
|
|
1046
|
+
kysely,
|
|
1047
|
+
)
|
|
1048
|
+
const linkedUserId = await AuthAccounts.getWalletUserId(tx, payload.address)
|
|
1049
|
+
const linkedUser = linkedUserId ? await Users.get(tx, linkedUserId) : undefined
|
|
1050
|
+
const emailUser = verifiedEmail ? await Users.getByEmail(tx, verifiedEmail) : undefined
|
|
1051
|
+
const walletUser = linkedUser ?? addressUser
|
|
1052
|
+
const walletHasResources =
|
|
1053
|
+
emailUser && walletUser.id !== emailUser.id
|
|
1054
|
+
? await Memberships.existsForUser(tx, walletUser.id)
|
|
1055
|
+
: false
|
|
1056
|
+
// A verified email reconciles a provisional email-less wallet link.
|
|
1057
|
+
// Keep a provisional owner when changing it would orphan its access.
|
|
1058
|
+
const user = walletHasResources ? walletUser : (emailUser ?? walletUser)
|
|
1059
|
+
if (linkedUser?.id !== user.id)
|
|
1060
|
+
await AuthAccounts.setWalletUser(tx, { address: payload.address, userId: user.id })
|
|
1061
|
+
if (verifiedEmail && (user.email !== verifiedEmail || !user.emailVerified))
|
|
1062
|
+
await Users.setEmail(tx, user.id, verifiedEmail)
|
|
1063
|
+
return { email: verifiedEmail ?? user.email ?? undefined, user }
|
|
1064
|
+
})
|
|
1065
|
+
}
|
|
842
1066
|
|
|
843
1067
|
const session: Session = {
|
|
844
1068
|
resolve: async (c) => {
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1069
|
+
const [betterAuth, identitySession, wallet] = await Promise.all([
|
|
1070
|
+
(async () => {
|
|
1071
|
+
const auth = BetterAuth.fromContext(c, options_betterAuth)
|
|
1072
|
+
const request = BetterAuth.request(c, options_betterAuth)
|
|
1073
|
+
const result = await auth.api.getSession({ headers: request.headers })
|
|
1074
|
+
if (!result) return null
|
|
1075
|
+
const provider =
|
|
1076
|
+
'provider' in result.session && typeof result.session.provider === 'string'
|
|
1077
|
+
? result.session.provider
|
|
1078
|
+
: undefined
|
|
1079
|
+
if (
|
|
1080
|
+
!provider ||
|
|
1081
|
+
!result.user.email ||
|
|
1082
|
+
(provider === 'email' && !options_betterAuth.email)
|
|
1083
|
+
)
|
|
1084
|
+
return null
|
|
1085
|
+
return {
|
|
1086
|
+
email: result.user.email,
|
|
1087
|
+
id: result.user.id,
|
|
1088
|
+
identity: { provider, subject: result.user.email },
|
|
1089
|
+
type: 'session',
|
|
1090
|
+
} satisfies SessionPrincipal
|
|
1091
|
+
})(),
|
|
1092
|
+
(async () => {
|
|
1093
|
+
if (!identity) return null
|
|
1094
|
+
const token = getCookie(c, identityCookieName)
|
|
1095
|
+
if (!token) return null
|
|
1096
|
+
const value = await kv.store.get(identitySessionKey(token))
|
|
1097
|
+
if (value === null) return null
|
|
1098
|
+
const payload = JSON.parse(value) as IdentitySession
|
|
1099
|
+
if (payload.expiresAt <= Math.floor(Date.now() / 1_000)) return null
|
|
1100
|
+
const user = await resolveWallet(payload)
|
|
1101
|
+
if (!user) return null
|
|
1102
|
+
return {
|
|
1103
|
+
...(user.email ? { email: user.email } : {}),
|
|
1104
|
+
id: user.user.id,
|
|
1105
|
+
identity: { provider: 'wallet', subject: payload.address },
|
|
1106
|
+
type: 'session',
|
|
1107
|
+
} satisfies SessionPrincipal
|
|
1108
|
+
})(),
|
|
1109
|
+
(async () => {
|
|
1110
|
+
const payload = await handler.getSession(c.req.raw)
|
|
1111
|
+
if (!payload) return null
|
|
1112
|
+
const user = await resolveWallet(payload)
|
|
1113
|
+
if (!user) return null
|
|
1114
|
+
return {
|
|
1115
|
+
...(user.email ? { email: user.email } : {}),
|
|
1116
|
+
id: user.user.id,
|
|
1117
|
+
identity: { provider: 'wallet', subject: payload.address },
|
|
1118
|
+
type: 'session',
|
|
1119
|
+
} satisfies SessionPrincipal
|
|
1120
|
+
})(),
|
|
1121
|
+
])
|
|
1122
|
+
if (betterAuth && identitySession && betterAuth.id !== identitySession.id) return null
|
|
1123
|
+
if (betterAuth && wallet && betterAuth.id !== wallet.id) return null
|
|
1124
|
+
if (identitySession && wallet && identitySession.id !== wallet.id) return null
|
|
1125
|
+
return betterAuth ?? identitySession ?? wallet
|
|
861
1126
|
},
|
|
862
1127
|
}
|
|
863
1128
|
|
|
864
1129
|
const policy_public = policy({ public: true })
|
|
865
|
-
const policy_session = policy({ public: true, session: true })
|
|
866
1130
|
const describe = OpenApi.describeRoute({ hide: true })
|
|
867
1131
|
|
|
868
1132
|
const app = new Hono<App.Environment>()
|
|
@@ -874,10 +1138,8 @@ export function install(options: install.Options) {
|
|
|
874
1138
|
app.post(
|
|
875
1139
|
'/v1/auth/siwe/challenge',
|
|
876
1140
|
policy_public,
|
|
877
|
-
OpenApi.
|
|
878
|
-
|
|
879
|
-
message: 'Invalid request body',
|
|
880
|
-
}),
|
|
1141
|
+
OpenApi.documentJsonRequest(schema.challenge.Body),
|
|
1142
|
+
validateJsonRequest(schema.challenge.Body),
|
|
881
1143
|
OpenApi.describeRoute({
|
|
882
1144
|
description:
|
|
883
1145
|
'Issues a single-use SIWE challenge message to sign. The challenge expires after a short TTL.',
|
|
@@ -901,10 +1163,8 @@ export function install(options: install.Options) {
|
|
|
901
1163
|
app.post(
|
|
902
1164
|
'/v1/auth/siwe',
|
|
903
1165
|
policy_public,
|
|
904
|
-
OpenApi.
|
|
905
|
-
|
|
906
|
-
message: 'Invalid request body',
|
|
907
|
-
}),
|
|
1166
|
+
OpenApi.documentJsonRequest(schema.verify.Body),
|
|
1167
|
+
validateJsonRequest(schema.verify.Body),
|
|
908
1168
|
OpenApi.describeRoute({
|
|
909
1169
|
description:
|
|
910
1170
|
'Verifies the signed challenge and establishes a session. Sets a session cookie by default; pass `returnToken` to receive a bearer token instead.',
|
|
@@ -933,42 +1193,270 @@ export function install(options: install.Options) {
|
|
|
933
1193
|
tags: ['Authentication'],
|
|
934
1194
|
}),
|
|
935
1195
|
)
|
|
1196
|
+
if (identity)
|
|
1197
|
+
app.post(
|
|
1198
|
+
'/v1/auth/identity',
|
|
1199
|
+
policy_public,
|
|
1200
|
+
OpenApi.documentJsonRequest(schema.identity.Body),
|
|
1201
|
+
validateJsonRequest(schema.identity.Body),
|
|
1202
|
+
OpenApi.describeRoute({
|
|
1203
|
+
description:
|
|
1204
|
+
'Verifies a Wallet-issued OpenID Connect identity token and establishes a session.',
|
|
1205
|
+
hide: false,
|
|
1206
|
+
operationId: 'verifyIdentity',
|
|
1207
|
+
responses: {
|
|
1208
|
+
200: {
|
|
1209
|
+
content: {
|
|
1210
|
+
'application/json': { schema: OpenApi.resolver(schema.identity.Response) },
|
|
1211
|
+
},
|
|
1212
|
+
description: 'Session established.',
|
|
1213
|
+
headers: {
|
|
1214
|
+
...OpenApi.successHeaders,
|
|
1215
|
+
'Set-Cookie': {
|
|
1216
|
+
description: `Session cookie (${identityCookieName}).`,
|
|
1217
|
+
schema: { type: 'string' },
|
|
1218
|
+
},
|
|
1219
|
+
},
|
|
1220
|
+
},
|
|
1221
|
+
400: OpenApi.standardError(400, 'Malformed request body.', ['body_invalid']),
|
|
1222
|
+
401: OpenApi.standardError(401, 'Identity verification failed.', ['identity_invalid']),
|
|
1223
|
+
429: OpenApi.standardError(429, 'Rate limited.'),
|
|
1224
|
+
500: OpenApi.standardError(500, 'Internal server error.'),
|
|
1225
|
+
},
|
|
1226
|
+
summary: 'Authenticate identity',
|
|
1227
|
+
tags: ['Authentication'],
|
|
1228
|
+
}),
|
|
1229
|
+
async (c) => {
|
|
1230
|
+
const { idToken } = schema.identity.Body.parse(await c.req.json())
|
|
1231
|
+
const claims = await Accounts.Identity.verify(idToken, {
|
|
1232
|
+
audience: identity.audience,
|
|
1233
|
+
issuer: identity.issuer ?? walletIdentityIssuer,
|
|
1234
|
+
}).catch((error) => {
|
|
1235
|
+
// Issuer and network failures must reach the request error signal.
|
|
1236
|
+
if (isIdentityTokenError(error)) return undefined
|
|
1237
|
+
throw error
|
|
1238
|
+
})
|
|
1239
|
+
if (!claims || !Address.validate(claims.subject, { strict: false }))
|
|
1240
|
+
return Response.error(c, {
|
|
1241
|
+
code: 'identity_invalid',
|
|
1242
|
+
message: 'Invalid identity token',
|
|
1243
|
+
status: 401,
|
|
1244
|
+
})
|
|
1245
|
+
|
|
1246
|
+
const address = Address.checksum(claims.subject)
|
|
1247
|
+
await Users.upsertByAddress(Db.get(db), { address })
|
|
1248
|
+
const issuedAt = Math.floor(Date.now() / 1_000)
|
|
1249
|
+
const token = Hex.fromBytes(crypto.getRandomValues(new Uint8Array(32))).slice(2)
|
|
1250
|
+
await kv.store.put(
|
|
1251
|
+
identitySessionKey(token),
|
|
1252
|
+
JSON.stringify({
|
|
1253
|
+
address,
|
|
1254
|
+
...(claims.email ? { email: claims.email } : {}),
|
|
1255
|
+
expiresAt: issuedAt + identitySessionTtl,
|
|
1256
|
+
issuedAt,
|
|
1257
|
+
} satisfies IdentitySession),
|
|
1258
|
+
{ ttl: identitySessionTtl * 1_000 },
|
|
1259
|
+
)
|
|
1260
|
+
setCookie(c, identityCookieName, token, {
|
|
1261
|
+
httpOnly: true,
|
|
1262
|
+
maxAge: identitySessionTtl,
|
|
1263
|
+
path: '/',
|
|
1264
|
+
sameSite: 'Lax',
|
|
1265
|
+
secure: new URL(c.req.url).protocol === 'https:',
|
|
1266
|
+
})
|
|
1267
|
+
return c.json({}, 200)
|
|
1268
|
+
},
|
|
1269
|
+
)
|
|
936
1270
|
app.post(
|
|
937
|
-
'/v1/auth/
|
|
938
|
-
|
|
1271
|
+
'/v1/auth/logout',
|
|
1272
|
+
policy(false),
|
|
1273
|
+
createMiddleware<App.Environment>(async (c, next) => {
|
|
1274
|
+
const auth = c.get('auth')
|
|
1275
|
+
const principal = principalFromPublic(c, auth)
|
|
1276
|
+
const result = await consumeRateLimit(auth, {
|
|
1277
|
+
key: `public:${principal.id}`,
|
|
1278
|
+
limit: auth.publicRateLimit ?? defaultPublicRateLimit,
|
|
1279
|
+
})
|
|
1280
|
+
if (result) {
|
|
1281
|
+
setRateLimitHeaders(c, result)
|
|
1282
|
+
if (!result.allowed) return rateLimitExceeded(c, result)
|
|
1283
|
+
}
|
|
1284
|
+
c.set('principal', principal)
|
|
1285
|
+
await next()
|
|
1286
|
+
return undefined
|
|
1287
|
+
}),
|
|
939
1288
|
OpenApi.describeRoute({
|
|
940
|
-
description: 'Revokes
|
|
1289
|
+
description: 'Revokes auth sessions and clears their cookies.',
|
|
941
1290
|
hide: false,
|
|
942
|
-
operationId: '
|
|
1291
|
+
operationId: 'logout',
|
|
943
1292
|
responses: {
|
|
944
|
-
204: { description: '
|
|
1293
|
+
204: { description: 'Sessions revoked and cookies cleared.' },
|
|
945
1294
|
429: OpenApi.standardError(429, 'Rate limited.'),
|
|
946
|
-
500: OpenApi.standardError(500, '
|
|
1295
|
+
500: OpenApi.standardError(500, 'Session logout failed.', ['session_logout_failed']),
|
|
947
1296
|
},
|
|
948
1297
|
summary: 'Sign out',
|
|
949
1298
|
tags: ['Authentication'],
|
|
950
1299
|
}),
|
|
1300
|
+
async (c) => {
|
|
1301
|
+
const walletHeaders = (() => {
|
|
1302
|
+
const authorization = c.req.header('authorization')
|
|
1303
|
+
const cookie = c.req.header('cookie')
|
|
1304
|
+
if (!authorization?.match(/^Bearer\s+.+$/i) || !cookie?.match(/(?:^|;\s*)accounts_auth=/))
|
|
1305
|
+
return [c.req.raw.headers]
|
|
1306
|
+
const bearer = new Headers(c.req.raw.headers)
|
|
1307
|
+
bearer.delete('cookie')
|
|
1308
|
+
const cookie_ = new Headers(c.req.raw.headers)
|
|
1309
|
+
cookie_.delete('authorization')
|
|
1310
|
+
return [bearer, cookie_]
|
|
1311
|
+
})()
|
|
1312
|
+
const [betterAuth, identityLogout, ...accounts] = await Promise.allSettled([
|
|
1313
|
+
BetterAuth.fromContext(c, options_betterAuth).api.signOut({
|
|
1314
|
+
headers: c.req.raw.headers,
|
|
1315
|
+
returnHeaders: true,
|
|
1316
|
+
}),
|
|
1317
|
+
(async () => {
|
|
1318
|
+
const token = getCookie(c, identityCookieName)
|
|
1319
|
+
deleteCookie(c, identityCookieName, { path: '/' })
|
|
1320
|
+
if (token) await kv.store.delete(identitySessionKey(token))
|
|
1321
|
+
})(),
|
|
1322
|
+
...walletHeaders.map((headers) =>
|
|
1323
|
+
handler.request(
|
|
1324
|
+
new Request(new URL('/logout', c.req.url), {
|
|
1325
|
+
headers,
|
|
1326
|
+
method: 'POST',
|
|
1327
|
+
}),
|
|
1328
|
+
),
|
|
1329
|
+
),
|
|
1330
|
+
])
|
|
1331
|
+
|
|
1332
|
+
if (betterAuth.status === 'fulfilled')
|
|
1333
|
+
for (const cookie of splitSetCookieHeader(
|
|
1334
|
+
betterAuth.value.headers.get('Set-Cookie') ?? '',
|
|
1335
|
+
))
|
|
1336
|
+
c.header('Set-Cookie', cookie, { append: true })
|
|
1337
|
+
for (const result of accounts)
|
|
1338
|
+
if (result.status === 'fulfilled')
|
|
1339
|
+
for (const cookie of splitSetCookieHeader(result.value.headers.get('Set-Cookie') ?? ''))
|
|
1340
|
+
c.header('Set-Cookie', cookie, { append: true })
|
|
1341
|
+
|
|
1342
|
+
const error = (() => {
|
|
1343
|
+
const rejected = [betterAuth, identityLogout, ...accounts].find(
|
|
1344
|
+
(result) => result.status === 'rejected',
|
|
1345
|
+
)
|
|
1346
|
+
if (rejected?.status === 'rejected')
|
|
1347
|
+
return rejected.reason instanceof Error
|
|
1348
|
+
? rejected.reason
|
|
1349
|
+
: new Error('Session logout failed', { cause: rejected.reason })
|
|
1350
|
+
const failed = accounts.find(
|
|
1351
|
+
(result) => result.status === 'fulfilled' && !result.value.ok,
|
|
1352
|
+
)
|
|
1353
|
+
if (failed?.status === 'fulfilled')
|
|
1354
|
+
return new Error(`Accounts session logout failed with status ${failed.value.status}`)
|
|
1355
|
+
return undefined
|
|
1356
|
+
})()
|
|
1357
|
+
if (error) {
|
|
1358
|
+
c.error = error
|
|
1359
|
+
return Response.error(c, {
|
|
1360
|
+
code: 'session_logout_failed',
|
|
1361
|
+
message: 'Session logout failed',
|
|
1362
|
+
status: 500,
|
|
1363
|
+
})
|
|
1364
|
+
}
|
|
1365
|
+
return c.body(null, 204)
|
|
1366
|
+
},
|
|
951
1367
|
)
|
|
1368
|
+
app.route('/v1/auth/siwe', handler)
|
|
1369
|
+
app.on(['GET', 'POST'], '/v1/auth/*', policy_public, describe, async (c, next) => {
|
|
1370
|
+
if (
|
|
1371
|
+
c.req.method === 'POST' &&
|
|
1372
|
+
stripBasePath(c.req.path, basePath(c)) === '/v1/auth/email-otp/send-verification-otp'
|
|
1373
|
+
) {
|
|
1374
|
+
const body: unknown = await c.req.raw
|
|
1375
|
+
.clone()
|
|
1376
|
+
.json()
|
|
1377
|
+
.catch(() => undefined)
|
|
1378
|
+
if (body && typeof body === 'object' && 'type' in body && body.type !== 'sign-in')
|
|
1379
|
+
return Response.error(c, {
|
|
1380
|
+
code: 'body_invalid',
|
|
1381
|
+
message: 'Only sign-in OTPs are supported',
|
|
1382
|
+
status: 400,
|
|
1383
|
+
})
|
|
1384
|
+
}
|
|
1385
|
+
const response = await BetterAuth.fromContext(c, options_betterAuth).handler(
|
|
1386
|
+
BetterAuth.request(c, options_betterAuth),
|
|
1387
|
+
)
|
|
1388
|
+
// Leave unmatched paths available to auth providers mounted by the host app.
|
|
1389
|
+
return response.status === 404 ? next() : response
|
|
1390
|
+
})
|
|
952
1391
|
return Object.assign(
|
|
953
1392
|
// The tag joins the `Management API` group at `management()`'s chosen slot;
|
|
954
1393
|
// group listings filter to defined tags, so it drops out when unmounted.
|
|
955
|
-
Metadata.attach(app
|
|
1394
|
+
Metadata.attach(app, {
|
|
1395
|
+
securitySchemes: {
|
|
1396
|
+
session: {
|
|
1397
|
+
description: 'Session cookie established by email OTP, Wallet identity, or SIWE sign-in. Browsers send `tempo_auth.session_token`, `tempo_identity`, or `accounts_auth`; Accounts sessions may also use `Authorization: Bearer <token>`.', // prettier-ignore
|
|
1398
|
+
in: 'header',
|
|
1399
|
+
name: 'Cookie',
|
|
1400
|
+
type: 'apiKey',
|
|
1401
|
+
},
|
|
1402
|
+
},
|
|
956
1403
|
tags: [{ name: 'Authentication', description: 'Authenticate into the Tempo Platform.' }],
|
|
957
1404
|
}),
|
|
958
1405
|
{ session },
|
|
959
1406
|
)
|
|
960
1407
|
})()
|
|
961
1408
|
|
|
1409
|
+
const resolve = createApiKeyResolver({
|
|
1410
|
+
apiKey: options_middleware.apiKey,
|
|
1411
|
+
db: options.db,
|
|
1412
|
+
scopeCatalog,
|
|
1413
|
+
})
|
|
1414
|
+
const defaults = laneDefaults(options_middleware)
|
|
1415
|
+
const base: require.Policy = {}
|
|
1416
|
+
const edgeRateLimit = (() => {
|
|
1417
|
+
if (options.auth === false || !options_edgeRateLimit) return undefined
|
|
1418
|
+
const superAdminTokenHash = options_middleware.superAdmin?.secret
|
|
1419
|
+
? ApiKey.hash(options_middleware.superAdmin.secret)
|
|
1420
|
+
: undefined
|
|
1421
|
+
|
|
1422
|
+
return createMiddleware(async (c, next) => {
|
|
1423
|
+
const credential = getApiKeyCredential(c)
|
|
1424
|
+
const resolved = resolveRequestPolicy(c, { base, defaults, options: options_middleware })
|
|
1425
|
+
const isSuperAdmin =
|
|
1426
|
+
credential &&
|
|
1427
|
+
superAdminTokenHash !== undefined &&
|
|
1428
|
+
ApiKey.hash(credential.token) === superAdminTokenHash
|
|
1429
|
+
const canUseApiKeyQuota =
|
|
1430
|
+
credential &&
|
|
1431
|
+
!isSuperAdmin &&
|
|
1432
|
+
!hasPaymentCredential(c) &&
|
|
1433
|
+
options_middleware.apiKey !== false &&
|
|
1434
|
+
resolved?.policy?.apiKey &&
|
|
1435
|
+
(!resolved.management || (options_middleware.mpp !== false && resolved.policy.mpp))
|
|
1436
|
+
const cached = canUseApiKeyQuota ? resolve.peek(c, credential.token) : undefined
|
|
1437
|
+
if (cached) return next()
|
|
1438
|
+
|
|
1439
|
+
const response = await Timing.time(c, 'edge_rate_limit', () =>
|
|
1440
|
+
options_edgeRateLimit(c.req.raw),
|
|
1441
|
+
)
|
|
1442
|
+
if (response) return response
|
|
1443
|
+
if (canUseApiKeyQuota && cached === undefined) await resolve.resolve(c, credential.token)
|
|
1444
|
+
return next()
|
|
1445
|
+
})
|
|
1446
|
+
})()
|
|
962
1447
|
const middleware_ =
|
|
963
1448
|
options.auth === false
|
|
964
1449
|
? undefined
|
|
965
|
-
:
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1450
|
+
: createAuthMiddleware(
|
|
1451
|
+
{
|
|
1452
|
+
...options_middleware,
|
|
1453
|
+
...(app ? { session: app.session } : {}),
|
|
1454
|
+
scopeCatalog,
|
|
1455
|
+
},
|
|
1456
|
+
resolve,
|
|
1457
|
+
)
|
|
970
1458
|
|
|
971
|
-
return { app, middleware: middleware_ }
|
|
1459
|
+
return { app, edgeRateLimit, middleware: middleware_ }
|
|
972
1460
|
}
|
|
973
1461
|
|
|
974
1462
|
export declare namespace install {
|
|
@@ -976,13 +1464,19 @@ export declare namespace install {
|
|
|
976
1464
|
type Options = {
|
|
977
1465
|
auth:
|
|
978
1466
|
| (Omit<middleware.Options, 'scopeCatalog' | 'session'> & {
|
|
979
|
-
/**
|
|
1467
|
+
/** Request backstop skipped for cached API keys on routes with per-key quotas. */
|
|
1468
|
+
edgeRateLimit?: EdgeRateLimit | undefined
|
|
1469
|
+
/** Session sign-in surface: mounts Better Auth, Wallet identity, and SIWE routes and enables the session lane. Requires `kv`. */
|
|
980
1470
|
session?: Session | undefined
|
|
981
1471
|
})
|
|
982
1472
|
| false
|
|
983
1473
|
| undefined
|
|
1474
|
+
/** Normalized path prefix that contains the auth surface. */
|
|
1475
|
+
basePath: string
|
|
984
1476
|
/** Authoritative database holding user rows. */
|
|
985
1477
|
db: Db.Source
|
|
1478
|
+
/** Resolves the transactional email sender shared by authentication and route groups. */
|
|
1479
|
+
email: () => Email.Sender | undefined
|
|
986
1480
|
/** Resolves the configured Tempo RPC client used for SIWE signature verification. */
|
|
987
1481
|
getClient: (chainId: number) => Viem.getClient.ReturnType
|
|
988
1482
|
/** KV state store, or undefined when key auth is closed. */
|
|
@@ -991,13 +1485,36 @@ export declare namespace install {
|
|
|
991
1485
|
scopeCatalog: Scope.Catalog
|
|
992
1486
|
}
|
|
993
1487
|
|
|
994
|
-
/** Session sign-in surface configuration
|
|
995
|
-
type Session =
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1488
|
+
/** Session sign-in surface configuration. */
|
|
1489
|
+
type Session = {
|
|
1490
|
+
/** Google OpenID Connect configuration. */
|
|
1491
|
+
google?:
|
|
1492
|
+
| {
|
|
1493
|
+
/** OAuth client identifier. */
|
|
1494
|
+
clientId: string
|
|
1495
|
+
/** OAuth client secret. */
|
|
1496
|
+
clientSecret: string
|
|
1497
|
+
}
|
|
1498
|
+
| undefined
|
|
1499
|
+
/** Wallet-issued OpenID Connect identity sign-in configuration. */
|
|
1500
|
+
identity?: Identity | undefined
|
|
1501
|
+
/** High-entropy secret used to protect Better Auth credentials. */
|
|
1502
|
+
secret: string
|
|
1503
|
+
/** Additional browser origins accepted by Better Auth. */
|
|
1504
|
+
trustedOrigins?: readonly string[] | undefined
|
|
1505
|
+
/** SIWE wallet sign-in configuration. */
|
|
1506
|
+
wallet?: Wallet | undefined
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
/** Wallet-issued OpenID Connect identity sign-in configuration. */
|
|
1510
|
+
type Identity = {
|
|
1511
|
+
/** Expected token audience, usually the Console origin. */
|
|
1512
|
+
audience: string
|
|
1513
|
+
/** Identity issuer override; defaults to Tempo Wallet. */
|
|
1514
|
+
issuer?: string | undefined
|
|
1515
|
+
/** Session lifetime in seconds. Defaults to 24 hours. */
|
|
1516
|
+
ttl?: number | undefined
|
|
1517
|
+
}
|
|
1001
1518
|
|
|
1002
1519
|
/** SIWE wallet sign-in configuration. */
|
|
1003
1520
|
type Wallet = {
|
|
@@ -1005,15 +1522,44 @@ export declare namespace install {
|
|
|
1005
1522
|
issuer?: string | undefined
|
|
1006
1523
|
/** Pinned absolute origin for SIWE domain binding. Required off-Workers; on Workers the edge proxy headers are trusted by default. */
|
|
1007
1524
|
origin?: string | undefined
|
|
1008
|
-
/** Reject sign-ins
|
|
1525
|
+
/** Reject sign-ins without a valid identity token. Defaults to false. */
|
|
1009
1526
|
requireEmail?: boolean | undefined
|
|
1010
1527
|
/** Session and challenge TTL overrides, in seconds. */
|
|
1011
1528
|
ttl?: { challenge?: number | undefined; session?: number | undefined } | undefined
|
|
1012
1529
|
}
|
|
1013
1530
|
}
|
|
1014
1531
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1532
|
+
function validateJsonRequest<const schema extends z.ZodMiniType>(
|
|
1533
|
+
schema: schema,
|
|
1534
|
+
): MiddlewareHandler {
|
|
1535
|
+
return async (c, next) => {
|
|
1536
|
+
if (!c.req.header('content-type')?.toLowerCase().startsWith('application/json'))
|
|
1537
|
+
return Response.error(c, {
|
|
1538
|
+
code: 'body_invalid',
|
|
1539
|
+
message: 'Invalid request body',
|
|
1540
|
+
status: 400,
|
|
1541
|
+
})
|
|
1542
|
+
const value = await (async () => {
|
|
1543
|
+
try {
|
|
1544
|
+
return await c.req.raw.clone().json()
|
|
1545
|
+
} catch {
|
|
1546
|
+
return undefined
|
|
1547
|
+
}
|
|
1548
|
+
})()
|
|
1549
|
+
const result = schema.safeParse(value)
|
|
1550
|
+
if (!result.success)
|
|
1551
|
+
return Response.error(c, {
|
|
1552
|
+
code: 'body_invalid',
|
|
1553
|
+
details: Response.validationDetails(result.error.issues),
|
|
1554
|
+
message: 'Invalid request body',
|
|
1555
|
+
status: 400,
|
|
1556
|
+
})
|
|
1557
|
+
return next()
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
/** Creates route middleware that contributes an auth policy override, or bypasses auth when passed `false`. */
|
|
1562
|
+
export function policy(options: policy.Options | false): MiddlewareHandler {
|
|
1017
1563
|
const middleware = createMiddleware((_, next) => next()) as MiddlewareHandler & PolicyHandler
|
|
1018
1564
|
middleware[policySymbol] = options
|
|
1019
1565
|
return middleware
|
|
@@ -1042,7 +1588,7 @@ export function installMppManagementRoutes(
|
|
|
1042
1588
|
if (route.method !== 'GET') continue
|
|
1043
1589
|
const target = targets.get(route.path) ?? { path: route.path }
|
|
1044
1590
|
const override = policyFromRoute(route)
|
|
1045
|
-
if (override
|
|
1591
|
+
if (override && override.mpp !== undefined)
|
|
1046
1592
|
target.mpp = resolveMppLane(target.mpp, override.mpp, { session: {} })
|
|
1047
1593
|
|
|
1048
1594
|
const spec = openApiSpec(route) as MppManagementSpec | undefined
|
|
@@ -1127,7 +1673,7 @@ type OpenApiRoute = {
|
|
|
1127
1673
|
}
|
|
1128
1674
|
|
|
1129
1675
|
type PolicyHandler = {
|
|
1130
|
-
[policySymbol]?: policy.Options | undefined
|
|
1676
|
+
[policySymbol]?: policy.Options | false | undefined
|
|
1131
1677
|
}
|
|
1132
1678
|
|
|
1133
1679
|
type MppManagementHandler = {
|
|
@@ -1168,7 +1714,7 @@ function laneDefaults(options: middleware.Options): LaneDefaults {
|
|
|
1168
1714
|
scopes: apiKey?.scopes ?? [Scope.wildcard],
|
|
1169
1715
|
},
|
|
1170
1716
|
mpp: { session: {} },
|
|
1171
|
-
public: { rateLimit: public_?.rateLimit ??
|
|
1717
|
+
public: { rateLimit: public_?.rateLimit ?? defaultPublicRateLimit },
|
|
1172
1718
|
session: true,
|
|
1173
1719
|
}
|
|
1174
1720
|
}
|
|
@@ -1304,7 +1850,7 @@ function policies(c: hono_Context) {
|
|
|
1304
1850
|
return matchedRoutes(c)
|
|
1305
1851
|
.slice(c.req.routeIndex + 1)
|
|
1306
1852
|
.map(policyFromRoute)
|
|
1307
|
-
.filter((routePolicy): routePolicy is policy.Options => routePolicy !== undefined)
|
|
1853
|
+
.filter((routePolicy): routePolicy is policy.Options | false => routePolicy !== undefined)
|
|
1308
1854
|
}
|
|
1309
1855
|
|
|
1310
1856
|
function openApiSpec(route: RouterRoute) {
|
|
@@ -1328,6 +1874,8 @@ function mppManagementFromRoute(route: RouterRoute) {
|
|
|
1328
1874
|
export type OperationAccess = {
|
|
1329
1875
|
/** Whether API-key access is allowed. */
|
|
1330
1876
|
apiKey: boolean
|
|
1877
|
+
/** Whether this operation explicitly bypasses auth instead of inheriting document security. */
|
|
1878
|
+
bypass?: true | undefined
|
|
1331
1879
|
/** Whether MPP payment is accepted (enables the `402` payment-challenge response). */
|
|
1332
1880
|
mpp: boolean
|
|
1333
1881
|
/** Whether anonymous public-quota access is allowed (keeps the anonymous security option). */
|
|
@@ -1346,14 +1894,14 @@ export type OperationAccess = {
|
|
|
1346
1894
|
* operation surfaces only the lanes its route opts into via {@link policy}.
|
|
1347
1895
|
*/
|
|
1348
1896
|
export function describeAccess(app: Hono<any, any>): Record<string, OperationAccess> {
|
|
1349
|
-
const groups = new Map<string, { operationId?: string; overrides: PolicyOverride[] }>()
|
|
1897
|
+
const groups = new Map<string, { operationId?: string; overrides: (PolicyOverride | false)[] }>()
|
|
1350
1898
|
for (const route of app.routes) {
|
|
1351
1899
|
const key = `${route.method} ${route.path}`
|
|
1352
1900
|
const group = groups.get(key) ?? { overrides: [] }
|
|
1353
1901
|
const spec = openApiSpec(route) as { operationId?: unknown } | undefined
|
|
1354
1902
|
if (typeof spec?.operationId === 'string') group.operationId = spec.operationId
|
|
1355
1903
|
const override = policyFromRoute(route)
|
|
1356
|
-
if (override) group.overrides.push(override)
|
|
1904
|
+
if (override !== undefined) group.overrides.push(override)
|
|
1357
1905
|
groups.set(key, group)
|
|
1358
1906
|
}
|
|
1359
1907
|
|
|
@@ -1365,7 +1913,12 @@ export function describeAccess(app: Hono<any, any>): Record<string, OperationAcc
|
|
|
1365
1913
|
let public_ = false
|
|
1366
1914
|
let mpp = false
|
|
1367
1915
|
let session = false
|
|
1916
|
+
let bypass = false
|
|
1368
1917
|
for (const override of overrides) {
|
|
1918
|
+
if (override === false) {
|
|
1919
|
+
bypass = true
|
|
1920
|
+
break
|
|
1921
|
+
}
|
|
1369
1922
|
if (override.apiKey !== undefined) apiKey = override.apiKey !== false
|
|
1370
1923
|
if (override.apiKey && override.apiKey !== true && override.apiKey.scopes)
|
|
1371
1924
|
scopes = override.apiKey.scopes
|
|
@@ -1373,7 +1926,14 @@ export function describeAccess(app: Hono<any, any>): Record<string, OperationAcc
|
|
|
1373
1926
|
if (override.mpp !== undefined) mpp = override.mpp !== false
|
|
1374
1927
|
if (override.session !== undefined) session = override.session !== false
|
|
1375
1928
|
}
|
|
1376
|
-
access[operationId] = {
|
|
1929
|
+
access[operationId] = {
|
|
1930
|
+
apiKey,
|
|
1931
|
+
...(bypass ? { bypass: true } : {}),
|
|
1932
|
+
mpp,
|
|
1933
|
+
public: public_,
|
|
1934
|
+
scopes: apiKey ? scopes : [],
|
|
1935
|
+
session,
|
|
1936
|
+
}
|
|
1377
1937
|
}
|
|
1378
1938
|
return access
|
|
1379
1939
|
}
|
|
@@ -1417,16 +1977,23 @@ export function require<environment extends Environment = Environment>(
|
|
|
1417
1977
|
const hasQueryApiKey = new URL(c.req.url).searchParams.has('key')
|
|
1418
1978
|
// Auth owns `key`; strict route schemas must not validate it.
|
|
1419
1979
|
stripApiKeyQuery(c)
|
|
1420
|
-
// Reject unknown chains before MPP builds a chain-bound challenge. Route
|
|
1421
|
-
// groups publish their supported chains into the shared app context.
|
|
1422
1980
|
const chainId = explicitChainId(c)
|
|
1423
1981
|
const supportedChainIds = (c.var as Record<string, unknown>)['supportedChainIds']
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1982
|
+
const unsupportedChain = (() => {
|
|
1983
|
+
if (
|
|
1984
|
+
chainId === undefined ||
|
|
1985
|
+
!(supportedChainIds instanceof Set) ||
|
|
1986
|
+
supportedChainIds.has(chainId)
|
|
1987
|
+
)
|
|
1988
|
+
return undefined
|
|
1989
|
+
return { chainId, supportedChainIds }
|
|
1990
|
+
})()
|
|
1991
|
+
if (unsupportedChain && !credential)
|
|
1992
|
+
return Response.unsupportedChainId(
|
|
1993
|
+
c,
|
|
1994
|
+
unsupportedChain.chainId,
|
|
1995
|
+
unsupportedChain.supportedChainIds,
|
|
1996
|
+
)
|
|
1430
1997
|
const proceed = async () => {
|
|
1431
1998
|
await next()
|
|
1432
1999
|
// Query credential responses must not enter shared caches.
|
|
@@ -1450,12 +2017,24 @@ export function require<environment extends Environment = Environment>(
|
|
|
1450
2017
|
// The super admin secret precedes key lookup: it is not a stored key.
|
|
1451
2018
|
// It must never reach KV resolution or scope/quota checks.
|
|
1452
2019
|
if (auth.superAdmin && ApiKey.hash(credential.token) === auth.superAdmin.tokenHash) {
|
|
2020
|
+
if (unsupportedChain)
|
|
2021
|
+
return Response.unsupportedChainId(
|
|
2022
|
+
c,
|
|
2023
|
+
unsupportedChain.chainId,
|
|
2024
|
+
unsupportedChain.supportedChainIds,
|
|
2025
|
+
)
|
|
1453
2026
|
c.set('principal', { actor: 'super_admin', id: 'super_admin', type: 'super_admin' })
|
|
1454
2027
|
return proceed()
|
|
1455
2028
|
}
|
|
1456
2029
|
|
|
1457
2030
|
const apiKey_resolved = await auth.apiKey?.resolve(c, credential.token)
|
|
1458
2031
|
if (!apiKey_resolved) {
|
|
2032
|
+
if (unsupportedChain)
|
|
2033
|
+
return Response.unsupportedChainId(
|
|
2034
|
+
c,
|
|
2035
|
+
unsupportedChain.chainId,
|
|
2036
|
+
unsupportedChain.supportedChainIds,
|
|
2037
|
+
)
|
|
1459
2038
|
// A bearer session token is indistinguishable from an API key at the
|
|
1460
2039
|
// header, so a failed key lookup falls through to the session lane
|
|
1461
2040
|
// before rejecting.
|
|
@@ -1498,6 +2077,34 @@ export function require<environment extends Environment = Environment>(
|
|
|
1498
2077
|
status: 403,
|
|
1499
2078
|
})
|
|
1500
2079
|
|
|
2080
|
+
// Non-paid requests consume API-key quota before rejection. Paid
|
|
2081
|
+
// requests use the MPP quota after access checks.
|
|
2082
|
+
const scope = policy.apiKey.scopes[0] ?? Scope.wildcard
|
|
2083
|
+
const throttled = apiKey.environment === 'sandbox' && apiKey.billingActive !== true
|
|
2084
|
+
const limit = throttled
|
|
2085
|
+
? (policy.public?.rateLimit ?? auth.publicRateLimit ?? { limit: 60, period: 'minute' })
|
|
2086
|
+
: resolveApiKeyLimit({ apiKey, auth, policy: policy.apiKey, scope })
|
|
2087
|
+
const paid = hasPayment && !throttled
|
|
2088
|
+
const result = paid
|
|
2089
|
+
? null
|
|
2090
|
+
: await consumeRateLimit(auth, {
|
|
2091
|
+
key: `api_key:${apiKey.id}:scope:${scope}`,
|
|
2092
|
+
limit,
|
|
2093
|
+
})
|
|
2094
|
+
if (result) {
|
|
2095
|
+
setRateLimitHeaders(c, result)
|
|
2096
|
+
// Surface the bucket so callers can correlate a 429 with the exhausted
|
|
2097
|
+
// quota. MPP challenges own their headers and drop these by design.
|
|
2098
|
+
c.header('RateLimit-Scope', scope)
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
if (unsupportedChain)
|
|
2102
|
+
return Response.unsupportedChainId(
|
|
2103
|
+
c,
|
|
2104
|
+
unsupportedChain.chainId,
|
|
2105
|
+
unsupportedChain.supportedChainIds,
|
|
2106
|
+
)
|
|
2107
|
+
|
|
1501
2108
|
if (
|
|
1502
2109
|
apiKey.allowedIps.length &&
|
|
1503
2110
|
!(await IpAllowlist.allows(c, {
|
|
@@ -1532,14 +2139,7 @@ export function require<environment extends Environment = Environment>(
|
|
|
1532
2139
|
status: 403,
|
|
1533
2140
|
})
|
|
1534
2141
|
|
|
1535
|
-
|
|
1536
|
-
// `billingActive` is snapshotted on the key record (stamped at mint,
|
|
1537
|
-
// re-synced when billing changes), so this needs no billing read on the
|
|
1538
|
-
// request path. Resolved before the paid lane so a payment credential
|
|
1539
|
-
// can't buy past the throttle: sandbox is non-billable testnet.
|
|
1540
|
-
const throttled = apiKey.environment === 'sandbox' && apiKey.billingActive !== true
|
|
1541
|
-
|
|
1542
|
-
if (hasPayment && !throttled)
|
|
2142
|
+
if (paid)
|
|
1543
2143
|
return requirePayment(c, proceed, {
|
|
1544
2144
|
auth,
|
|
1545
2145
|
payment: { reason: 'api_key_over_quota', type: 'mpp' },
|
|
@@ -1547,39 +2147,17 @@ export function require<environment extends Environment = Environment>(
|
|
|
1547
2147
|
principal,
|
|
1548
2148
|
})
|
|
1549
2149
|
|
|
1550
|
-
if (
|
|
1551
|
-
// A
|
|
1552
|
-
//
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
:
|
|
1560
|
-
const result = await consumeRateLimit(auth, {
|
|
1561
|
-
key: `api_key:${apiKey.id}:scope:${scope}`,
|
|
1562
|
-
limit,
|
|
2150
|
+
if (result && !result.allowed) {
|
|
2151
|
+
// A throttled sandbox key gets a plain 429, never an MPP challenge. It
|
|
2152
|
+
// must activate billing to lift the ceiling, not pay per request.
|
|
2153
|
+
if (throttled) return rateLimitExceeded(c, result)
|
|
2154
|
+
return requirePaymentOrRateLimit(c, proceed, {
|
|
2155
|
+
auth,
|
|
2156
|
+
payment: { reason: 'api_key_over_quota', type: 'mpp' },
|
|
2157
|
+
policy,
|
|
2158
|
+
principal,
|
|
2159
|
+
rateLimit: result,
|
|
1563
2160
|
})
|
|
1564
|
-
if (result) {
|
|
1565
|
-
setRateLimitHeaders(c, result)
|
|
1566
|
-
// Surface the bucket so callers can correlate a 429 with the exhausted
|
|
1567
|
-
// quota. Set before the over-quota branch so it rides the 429 (an MPP
|
|
1568
|
-
// 402 challenge is owned by mppx and drops these headers — by design).
|
|
1569
|
-
c.header('RateLimit-Scope', scope)
|
|
1570
|
-
}
|
|
1571
|
-
if (result && !result.allowed) {
|
|
1572
|
-
// A throttled sandbox key gets a plain 429, never an MPP challenge —
|
|
1573
|
-
// it must activate billing to lift the ceiling, not pay per request.
|
|
1574
|
-
if (throttled) return rateLimitExceeded(c, result)
|
|
1575
|
-
return requirePaymentOrRateLimit(c, proceed, {
|
|
1576
|
-
auth,
|
|
1577
|
-
payment: { reason: 'api_key_over_quota', type: 'mpp' },
|
|
1578
|
-
policy,
|
|
1579
|
-
principal,
|
|
1580
|
-
rateLimit: result,
|
|
1581
|
-
})
|
|
1582
|
-
}
|
|
1583
2161
|
}
|
|
1584
2162
|
|
|
1585
2163
|
return proceed()
|
|
@@ -1679,7 +2257,7 @@ export declare namespace require {
|
|
|
1679
2257
|
rateLimit: RateLimit.Limit
|
|
1680
2258
|
}
|
|
1681
2259
|
| undefined
|
|
1682
|
-
/** Session access policy: `true` allows signed-in
|
|
2260
|
+
/** Session access policy: `true` allows signed-in sessions. */
|
|
1683
2261
|
session?: boolean | undefined
|
|
1684
2262
|
}
|
|
1685
2263
|
}
|
|
@@ -1709,7 +2287,8 @@ type RateLimitAccess = PaymentAccess & {
|
|
|
1709
2287
|
*/
|
|
1710
2288
|
const rateLimitConsumeTimeout = 300
|
|
1711
2289
|
|
|
1712
|
-
|
|
2290
|
+
/** Consumes one quota and returns null when its counter is unavailable, allowing callers to fail open. */
|
|
2291
|
+
export function consumeRateLimit(
|
|
1713
2292
|
auth: Context,
|
|
1714
2293
|
options: RateLimit.Store.ConsumeOptions,
|
|
1715
2294
|
): Promise<RateLimit.Result | null> {
|
|
@@ -1822,10 +2401,17 @@ function clientIp(c: hono_Context, auth: Context): string | undefined {
|
|
|
1822
2401
|
}
|
|
1823
2402
|
|
|
1824
2403
|
function trustedClientIp(c: hono_Context, auth: Context): string | undefined {
|
|
1825
|
-
|
|
2404
|
+
return resolveTrustedClientIp(c.req.raw, auth.publicClientIp)
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
function resolveTrustedClientIp(
|
|
2408
|
+
request: Request,
|
|
2409
|
+
resolve: ((request: Request) => string | undefined) | undefined,
|
|
2410
|
+
) {
|
|
2411
|
+
if (resolve) return resolve(request)
|
|
1826
2412
|
// Cloudflare supplies both the request metadata and this header.
|
|
1827
|
-
if (!('cf' in
|
|
1828
|
-
return
|
|
2413
|
+
if (!('cf' in request)) return undefined
|
|
2414
|
+
return request.headers.get('cf-connecting-ip') ?? undefined
|
|
1829
2415
|
}
|
|
1830
2416
|
|
|
1831
2417
|
/** Removes the reserved auth query parameter before route validation. */
|
|
@@ -2050,17 +2636,12 @@ export type Session = {
|
|
|
2050
2636
|
resolve: (c: hono_Context) => Promise<SessionPrincipal | null>
|
|
2051
2637
|
}
|
|
2052
2638
|
|
|
2053
|
-
// Resolve the session lane from the auth context's capability.
|
|
2054
|
-
//
|
|
2639
|
+
// Resolve the session lane from the auth context's capability. Dependency
|
|
2640
|
+
// failures propagate to the app error boundary instead of becoming a `401`.
|
|
2055
2641
|
async function resolveSession(c: hono_Context, auth: Context): Promise<SessionPrincipal | null> {
|
|
2056
2642
|
const session = auth.session
|
|
2057
2643
|
if (!session) return null
|
|
2058
|
-
|
|
2059
|
-
return await session.resolve(c)
|
|
2060
|
-
} catch (error) {
|
|
2061
|
-
console.error('[auth] session resolve failed; treating as no session', error)
|
|
2062
|
-
return null
|
|
2063
|
-
}
|
|
2644
|
+
return session.resolve(c)
|
|
2064
2645
|
}
|
|
2065
2646
|
|
|
2066
2647
|
/** Maximum resolve-cache entries held per isolate before eviction. */
|
|
@@ -2078,40 +2659,53 @@ const cachedMaxEntries = 10_000
|
|
|
2078
2659
|
function cachedResolve(
|
|
2079
2660
|
resolve: (c: hono_Context, token: string) => Promise<ApiKey.ApiKey | null>,
|
|
2080
2661
|
options: middleware.Cache,
|
|
2081
|
-
)
|
|
2662
|
+
) {
|
|
2082
2663
|
const { negativeTtl = 10_000, now = Date.now, ttl = 60_000 } = options
|
|
2083
2664
|
type Cell = { expiresAt: number; value: ApiKey.ApiKey | null }
|
|
2084
2665
|
const cells = new Map<string, Cell>()
|
|
2085
2666
|
const flights = new Map<string, Promise<ApiKey.ApiKey | null>>()
|
|
2086
2667
|
|
|
2087
|
-
return
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
// so
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2668
|
+
return {
|
|
2669
|
+
invalidate(token: string) {
|
|
2670
|
+
cells.delete(`v1:${ApiKey.hash(token)}`)
|
|
2671
|
+
},
|
|
2672
|
+
peek(token: string) {
|
|
2673
|
+
const key = `v1:${ApiKey.hash(token)}`
|
|
2674
|
+
const cell = cells.get(key)
|
|
2675
|
+
if (!cell) return undefined
|
|
2676
|
+
if (cell.expiresAt > now()) return cell.value
|
|
2677
|
+
cells.delete(key)
|
|
2678
|
+
return undefined
|
|
2679
|
+
},
|
|
2680
|
+
async resolve(c: hono_Context, token: string) {
|
|
2681
|
+
// Versioned so a future record-shape change can't serve stale shapes.
|
|
2682
|
+
const key = `v1:${ApiKey.hash(token)}`
|
|
2683
|
+
const cell = cells.get(key)
|
|
2684
|
+
if (cell && cell.expiresAt > now()) return cell.value
|
|
2685
|
+
if (cell) cells.delete(key)
|
|
2686
|
+
|
|
2687
|
+
const existing = flights.get(key)
|
|
2688
|
+
if (existing) return existing
|
|
2689
|
+
|
|
2690
|
+
const flight = (async () => {
|
|
2691
|
+
const value = await resolve(c, token)
|
|
2692
|
+
// Bound the cache: random invalid tokens each add a (negative) entry,
|
|
2693
|
+
// so sweep expired cells at the cap and then drop the oldest.
|
|
2694
|
+
if (cells.size >= cachedMaxEntries) {
|
|
2695
|
+
const time = now()
|
|
2696
|
+
for (const [name, entry] of cells) if (entry.expiresAt <= time) cells.delete(name)
|
|
2697
|
+
while (cells.size >= cachedMaxEntries) cells.delete(cells.keys().next().value as string)
|
|
2698
|
+
}
|
|
2699
|
+
cells.set(key, { expiresAt: now() + (value ? ttl : negativeTtl), value })
|
|
2700
|
+
return value
|
|
2701
|
+
})()
|
|
2702
|
+
flights.set(key, flight)
|
|
2703
|
+
try {
|
|
2704
|
+
return await flight
|
|
2705
|
+
} finally {
|
|
2706
|
+
flights.delete(key)
|
|
2105
2707
|
}
|
|
2106
|
-
|
|
2107
|
-
return value
|
|
2108
|
-
})()
|
|
2109
|
-
flights.set(key, flight)
|
|
2110
|
-
try {
|
|
2111
|
-
return await flight
|
|
2112
|
-
} finally {
|
|
2113
|
-
flights.delete(key)
|
|
2114
|
-
}
|
|
2708
|
+
},
|
|
2115
2709
|
}
|
|
2116
2710
|
}
|
|
2117
2711
|
|