tapimo 0.15.1 → 0.18.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 +137 -0
- package/dist/ApiKey.d.ts +1 -0
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +4 -2
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +37 -11
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +163 -10
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +13085 -11974
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +46 -15
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +1 -1
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +1 -1
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +893 -191
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +5 -1
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +70 -70
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +8 -3
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +66 -27
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +36 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +25 -25
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +5 -4
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/route-policies.d.ts +632 -0
- package/dist/admin/apps/route-policies.d.ts.map +1 -0
- package/dist/admin/apps/route-policies.js +257 -0
- package/dist/admin/apps/route-policies.js.map +1 -0
- package/dist/admin/apps/routes-support.js +39 -3
- package/dist/admin/apps/routes-support.js.map +1 -1
- package/dist/admin/apps/routes.d.ts +529 -76
- package/dist/admin/apps/routes.d.ts.map +1 -1
- package/dist/admin/apps/routes.js +82 -1
- package/dist/admin/apps/routes.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +157 -157
- package/dist/admin/index.d.ts +0 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +0 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +205 -201
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +65 -1
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +1 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +58 -59
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +2709 -2670
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +357 -357
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +50 -0
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +248 -248
- package/dist/apps/data/routes/balances.d.ts +22 -22
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +5 -7
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +125 -125
- package/dist/apps/data/routes/coingecko.d.ts +54 -54
- package/dist/apps/data/routes/earn.d.ts +103 -12
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +456 -220
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +267 -97
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +109 -127
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +83 -54
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +43 -43
- package/dist/apps/data/routes/receipts.d.ts +235 -235
- package/dist/apps/data/routes/rpc.d.ts +30 -30
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +11 -6
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +2 -0
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +30 -22
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +77 -77
- package/dist/apps/data/routes/valuation.d.ts +32 -32
- package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +1 -1
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +31 -31
- package/dist/apps/management/App.d.ts +2909 -2064
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +2 -0
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/Billing.d.ts +2 -4
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +65 -26
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +257 -245
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +70 -11
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +84 -84
- package/dist/apps/management/routes/cli.d.ts +912 -0
- package/dist/apps/management/routes/cli.d.ts.map +1 -0
- package/dist/apps/management/routes/cli.js +416 -0
- package/dist/apps/management/routes/cli.js.map +1 -0
- package/dist/apps/management/routes/faucet.d.ts +8 -8
- package/dist/apps/management/routes/invitations.d.ts +138 -138
- package/dist/apps/management/routes/invite-links.d.ts +172 -172
- package/dist/apps/management/routes/members.d.ts +16 -16
- package/dist/apps/management/routes/orgs.d.ts +104 -104
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +8 -2
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +125 -125
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
- package/dist/apps/management/routes/webhooks.d.ts +485 -485
- package/dist/apps/mpp/App.d.ts +44 -44
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Policy.js +4 -2
- package/dist/apps/mpp/internal/Policy.js.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.js +6 -4
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
- package/dist/apps/relay/App.d.ts +8 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +16 -4
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +4 -6
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +71 -60
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/apps/routes/Access.d.ts +53 -0
- package/dist/apps/routes/Access.d.ts.map +1 -1
- package/dist/apps/routes/Access.js +121 -0
- package/dist/apps/routes/Access.js.map +1 -1
- package/dist/apps/routes/App.d.ts +397 -158
- package/dist/apps/routes/App.d.ts.map +1 -1
- package/dist/apps/routes/App.js.map +1 -1
- package/dist/apps/routes/routes/chains.d.ts +25 -25
- package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
- package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/routes/routes/deposit-addresses.js +217 -32
- package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/routes/routes/quotes.d.ts +171 -81
- package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
- package/dist/apps/routes/routes/quotes.js +101 -27
- package/dist/apps/routes/routes/quotes.js.map +1 -1
- package/dist/apps/routes/routes/transfers.d.ts +532 -480
- package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
- package/dist/apps/routes/routes/transfers.js +182 -37
- package/dist/apps/routes/routes/transfers.js.map +1 -1
- package/dist/cli/ApiKeys.d.ts +120 -0
- package/dist/cli/ApiKeys.d.ts.map +1 -0
- package/dist/cli/ApiKeys.js +138 -0
- package/dist/cli/ApiKeys.js.map +1 -0
- package/dist/cli/Cli.d.ts +92 -34
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/Cli.js +188 -11
- package/dist/cli/Cli.js.map +1 -1
- package/dist/cli/Credentials.d.ts +95 -0
- package/dist/cli/Credentials.d.ts.map +1 -0
- package/dist/cli/Credentials.js +110 -0
- package/dist/cli/Credentials.js.map +1 -0
- package/dist/cli/Spec.d.ts +59 -0
- package/dist/cli/Spec.d.ts.map +1 -0
- package/dist/cli/Spec.js +77 -0
- package/dist/cli/Spec.js.map +1 -0
- package/dist/cli/bin.js +5 -1
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/admin.d.ts +5 -5
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/auth.d.ts +73 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +204 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/keys.d.ts +17 -0
- package/dist/cli/commands/keys.d.ts.map +1 -0
- package/dist/cli/commands/keys.js +109 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cloudflare.d.ts +27 -2
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +144 -17
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +23 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +413 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +44 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +56 -3
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
- package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
- package/dist/db/tables/apiKeyAdmissions.js +65 -9
- package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
- package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
- package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
- package/dist/db/tables/authAccounts.d.ts.map +1 -1
- package/dist/db/tables/authAccounts.js +1 -0
- package/dist/db/tables/authAccounts.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +12 -1
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +4 -2
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +8 -34
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +5 -1
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js +10 -2
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
- package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
- package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
- package/dist/db/tables/rewardRuns.d.ts.map +1 -1
- package/dist/db/tables/rewardRuns.js +4 -0
- package/dist/db/tables/rewardRuns.js.map +1 -1
- package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
- package/dist/db/tables/rewardTransactionAttempts.js +2 -0
- package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
- package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
- package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
- package/dist/db/tables/routesDepositAddresses.js +84 -31
- package/dist/db/tables/routesDepositAddresses.js.map +1 -1
- package/dist/db/tables/routesDeposits.d.ts.map +1 -1
- package/dist/db/tables/routesDeposits.js +31 -21
- package/dist/db/tables/routesDeposits.js.map +1 -1
- package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
- package/dist/db/tables/routesIdempotency.js +2 -0
- package/dist/db/tables/routesIdempotency.js.map +1 -1
- package/dist/db/tables/routesPolicies.d.ts +58 -0
- package/dist/db/tables/routesPolicies.d.ts.map +1 -0
- package/dist/db/tables/routesPolicies.js +198 -0
- package/dist/db/tables/routesPolicies.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
- package/dist/db/tables/routesTransferSubsidies.js +41 -0
- package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
- package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
- package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
- package/dist/db/tables/routesTransfers.d.ts +26 -1
- package/dist/db/tables/routesTransfers.d.ts.map +1 -1
- package/dist/db/tables/routesTransfers.js +36 -6
- package/dist/db/tables/routesTransfers.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +144 -33
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/users.d.ts +2 -0
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +11 -0
- package/dist/db/tables/users.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +1 -1
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +3 -2
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/relay.d.ts +2 -0
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +34 -15
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +57 -6
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +182 -78
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/BetterAuth.d.ts +22 -0
- package/dist/internal/BetterAuth.d.ts.map +1 -1
- package/dist/internal/BetterAuth.js +17 -14
- package/dist/internal/BetterAuth.js.map +1 -1
- package/dist/internal/Cache.d.ts +5 -0
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +3 -1
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/CliAuth.d.ts +243 -0
- package/dist/internal/CliAuth.d.ts.map +1 -0
- package/dist/internal/CliAuth.js +249 -0
- package/dist/internal/CliAuth.js.map +1 -0
- package/dist/internal/EarnSharePrices.d.ts +1 -1
- package/dist/internal/EarnSharePrices.d.ts.map +1 -1
- package/dist/internal/EarnSharePrices.js +7 -3
- package/dist/internal/EarnSharePrices.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +47 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +188 -4
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/EarnWithdrawals.d.ts +73 -0
- package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
- package/dist/internal/EarnWithdrawals.js +189 -0
- package/dist/internal/EarnWithdrawals.js.map +1 -0
- package/dist/internal/ExecutionContext.d.ts +21 -0
- package/dist/internal/ExecutionContext.d.ts.map +1 -0
- package/dist/internal/ExecutionContext.js +16 -0
- package/dist/internal/ExecutionContext.js.map +1 -0
- package/dist/internal/Log.d.ts +7 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +163 -130
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +26 -1
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/RateLimit.d.ts +67 -0
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +174 -27
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Store.d.ts +6 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +4 -5
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Timing.d.ts +6 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +21 -1
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/Tron.d.ts +124 -0
- package/dist/internal/Tron.d.ts.map +1 -0
- package/dist/internal/Tron.js +202 -0
- package/dist/internal/Tron.js.map +1 -0
- package/dist/internal/Viem.d.ts +4 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +25 -6
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/rewards/Read.d.ts +2 -2
- package/dist/internal/rewards/Read.d.ts.map +1 -1
- package/dist/internal/rewards/Read.js +11 -2
- package/dist/internal/rewards/Read.js.map +1 -1
- package/dist/internal/routes/Action.d.ts +27 -0
- package/dist/internal/routes/Action.d.ts.map +1 -1
- package/dist/internal/routes/Action.js +49 -1
- package/dist/internal/routes/Action.js.map +1 -1
- package/dist/internal/routes/Chain.d.ts +2 -0
- package/dist/internal/routes/Chain.d.ts.map +1 -1
- package/dist/internal/routes/Chain.js +4 -0
- package/dist/internal/routes/Chain.js.map +1 -1
- package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
- package/dist/internal/routes/DepositAddress.js +5 -0
- package/dist/internal/routes/DepositAddress.js.map +1 -1
- package/dist/internal/routes/Evidence.d.ts.map +1 -1
- package/dist/internal/routes/Evidence.js +6 -2
- package/dist/internal/routes/Evidence.js.map +1 -1
- package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
- package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/EvmTransferSettlement.js +196 -0
- package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
- package/dist/internal/routes/Policy.d.ts +161 -0
- package/dist/internal/routes/Policy.d.ts.map +1 -0
- package/dist/internal/routes/Policy.js +249 -0
- package/dist/internal/routes/Policy.js.map +1 -0
- package/dist/internal/routes/Provider.d.ts +66 -3
- package/dist/internal/routes/Provider.d.ts.map +1 -1
- package/dist/internal/routes/Provider.js +106 -27
- package/dist/internal/routes/Provider.js.map +1 -1
- package/dist/internal/routes/Quota.d.ts +57 -0
- package/dist/internal/routes/Quota.d.ts.map +1 -0
- package/dist/internal/routes/Quota.js +144 -0
- package/dist/internal/routes/Quota.js.map +1 -0
- package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
- package/dist/internal/routes/Reconciliation.js +163 -47
- package/dist/internal/routes/Reconciliation.js.map +1 -1
- package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
- package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
- package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
- package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
- package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
- package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
- package/dist/internal/routes/Subsidy.d.ts +2 -2
- package/dist/internal/routes/Subsidy.d.ts.map +1 -1
- package/dist/internal/routes/Subsidy.js +2 -2
- package/dist/internal/routes/Subsidy.js.map +1 -1
- package/dist/internal/routes/Transfer.d.ts +229 -1
- package/dist/internal/routes/Transfer.d.ts.map +1 -1
- package/dist/internal/routes/Transfer.js +644 -7
- package/dist/internal/routes/Transfer.js.map +1 -1
- package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
- package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
- package/dist/internal/routes/TransferReconciliation.js +83 -159
- package/dist/internal/routes/TransferReconciliation.js.map +1 -1
- package/dist/internal/routes/TransferSettlement.d.ts +45 -0
- package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/TransferSettlement.js +2 -0
- package/dist/internal/routes/TransferSettlement.js.map +1 -0
- package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
- package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
- package/dist/internal/routes/TransferSubsidy.js +64 -5
- package/dist/internal/routes/TransferSubsidy.js.map +1 -1
- package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
- package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
- package/dist/internal/routes/TronTransferSettlement.js +201 -0
- package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
- package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
- package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/TronTransferSubsidy.js +439 -0
- package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
- package/dist/internal/routes/index.d.ts +3 -0
- package/dist/internal/routes/index.d.ts.map +1 -1
- package/dist/internal/routes/index.js +3 -0
- package/dist/internal/routes/index.js.map +1 -1
- package/dist/internal/routes/providers/across.d.ts +3 -0
- package/dist/internal/routes/providers/across.d.ts.map +1 -1
- package/dist/internal/routes/providers/across.js +11 -0
- package/dist/internal/routes/providers/across.js.map +1 -1
- package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
- package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMesh.js +474 -0
- package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
- package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
- package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
- package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
- package/dist/internal/routes/providers/propAmm.d.ts +70 -0
- package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
- package/dist/internal/routes/providers/propAmm.js +524 -0
- package/dist/internal/routes/providers/propAmm.js.map +1 -0
- package/dist/internal/routes/providers/relay.d.ts +3 -0
- package/dist/internal/routes/providers/relay.d.ts.map +1 -1
- package/dist/internal/routes/providers/relay.js +352 -41
- package/dist/internal/routes/providers/relay.js.map +1 -1
- package/dist/internal/routes/providers/rhino.d.ts +3 -0
- package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
- package/dist/internal/routes/providers/rhino.js +11 -0
- package/dist/internal/routes/providers/rhino.js.map +1 -1
- package/dist/internal/routes/providers/squid.d.ts +3 -0
- package/dist/internal/routes/providers/squid.d.ts.map +1 -1
- package/dist/internal/routes/providers/squid.js +19 -0
- package/dist/internal/routes/providers/squid.js.map +1 -1
- package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
- package/dist/internal/routes/providers/stargate.js +22 -9
- package/dist/internal/routes/providers/stargate.js.map +1 -1
- package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
- package/dist/internal/routes/providers/symbiosis.js +13 -17
- package/dist/internal/routes/providers/symbiosis.js.map +1 -1
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +6 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +16 -6
- package/src/ApiKey.ts +7 -3
- package/src/ApiKeys.test.ts +652 -8
- package/src/ApiKeys.ts +191 -11
- package/src/App.test.ts +405 -18
- package/src/App.ts +51 -15
- package/src/Client.test-d.ts +157 -10
- package/src/Client.test.ts +4 -4
- package/src/Scope.ts +1 -2
- package/src/admin/App.ts +11 -5
- package/src/admin/apps/api-keys.test.ts +98 -2
- package/src/admin/apps/api-keys.ts +21 -12
- package/src/admin/apps/earn-vaults.test.ts +76 -7
- package/src/admin/apps/earn-vaults.ts +47 -8
- package/src/admin/apps/organizations.test.ts +147 -31
- package/src/admin/apps/organizations.ts +5 -4
- package/src/admin/apps/route-policies.test.ts +220 -0
- package/src/admin/apps/route-policies.ts +322 -0
- package/src/admin/apps/routes-support.test.ts +107 -2
- package/src/admin/apps/routes-support.ts +43 -3
- package/src/admin/apps/routes.test.ts +150 -0
- package/src/admin/apps/routes.ts +97 -1
- package/src/admin/apps/scopes.test.ts +1 -1
- package/src/admin/index.ts +0 -1
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/components/Dialog.tsx +1 -1
- package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
- package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
- package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
- package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
- package/src/admin/ui/src/lib/route-policies.ts +232 -0
- package/src/admin/ui/src/lib/routes.ts +34 -0
- package/src/admin/ui/src/routeTree.gen.ts +21 -0
- package/src/admin/ui/src/routes/api-keys.tsx +21 -2
- package/src/admin/ui/src/routes/early-access.tsx +1 -0
- package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
- package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
- package/src/admin/ui/src/routes/organizations.tsx +1 -0
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
- package/src/admin/ui/src/routes/route-policies.tsx +678 -0
- package/src/admin/ui/src/routes/routes.tsx +85 -2
- package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
- package/src/admin/ui/src/routes/subsidies.tsx +1 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
- package/src/admin/ui.generated.ts +258 -202
- package/src/analytics/Analytics.test.ts +4 -50
- package/src/analytics/Analytics.ts +65 -1
- package/src/analytics/tables/requestEvents.test.ts +402 -1
- package/src/analytics/tables/requestEvents.ts +62 -93
- package/src/apps/data/routes/activities.test.ts +315 -14
- package/src/apps/data/routes/activities.ts +60 -0
- package/src/apps/data/routes/balances.ts +5 -7
- package/src/apps/data/routes/earn.bench.ts +18 -0
- package/src/apps/data/routes/earn.local.test.ts +507 -0
- package/src/apps/data/routes/earn.test.ts +405 -127
- package/src/apps/data/routes/earn.ts +660 -270
- package/src/apps/data/routes/exchanges.bench.ts +3 -1
- package/src/apps/data/routes/exchanges.test.ts +166 -2
- package/src/apps/data/routes/exchanges.ts +308 -101
- package/src/apps/data/routes/fee-amm.test.ts +134 -2
- package/src/apps/data/routes/fee-amm.ts +122 -60
- package/src/apps/data/routes/receipts.test.ts +21 -18
- package/src/apps/data/routes/rpc.test.ts +2 -2
- package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
- package/src/apps/data/routes/tokens.test.ts +4 -4
- package/src/apps/data/routes/tokens.ts +11 -6
- package/src/apps/data/routes/transactions.test.ts +29 -0
- package/src/apps/data/routes/transactions.ts +33 -22
- package/src/apps/data/routes/webhooks.test.ts +12 -3
- package/src/apps/data/routes/webhooks.ts +2 -1
- package/src/apps/management/App.ts +4 -0
- package/src/apps/management/Billing.test.ts +253 -27
- package/src/apps/management/Billing.ts +83 -29
- package/src/apps/management/routes/api-keys.test.ts +1 -1
- package/src/apps/management/routes/api-keys.ts +85 -11
- package/src/apps/management/routes/billing.test.ts +68 -4
- package/src/apps/management/routes/cli.test.ts +370 -0
- package/src/apps/management/routes/cli.ts +533 -0
- package/src/apps/management/routes/me.test.ts +14 -4
- package/src/apps/management/routes/orgs.test.ts +108 -4
- package/src/apps/management/routes/orgs.ts +7 -2
- package/src/apps/management/routes/usage.test.ts +2 -2
- package/src/apps/mpp/internal/Policy.test.ts +51 -4
- package/src/apps/mpp/internal/Policy.ts +6 -2
- package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
- package/src/apps/mpp/internal/Sponsorship.ts +6 -4
- package/src/apps/relay/App.test.ts +85 -1
- package/src/apps/relay/App.ts +28 -4
- package/src/apps/relay/Sponsorships.test.ts +97 -1
- package/src/apps/relay/Sponsorships.ts +77 -66
- package/src/apps/routes/Access.test.ts +319 -0
- package/src/apps/routes/Access.ts +147 -0
- package/src/apps/routes/App.ts +10 -0
- package/src/apps/routes/routes/chains.test.ts +3 -2
- package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
- package/src/apps/routes/routes/deposit-addresses.ts +243 -32
- package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
- package/src/apps/routes/routes/quotes.test.ts +81 -8
- package/src/apps/routes/routes/quotes.ts +109 -27
- package/src/apps/routes/routes/transfers.test.ts +252 -15
- package/src/apps/routes/routes/transfers.ts +212 -33
- package/src/cli/ApiKeys.test.ts +265 -0
- package/src/cli/ApiKeys.ts +189 -0
- package/src/cli/Cli.test.ts +188 -0
- package/src/cli/Cli.ts +280 -12
- package/src/cli/Credentials.test.ts +122 -0
- package/src/cli/Credentials.ts +144 -0
- package/src/cli/Spec.test.ts +133 -0
- package/src/cli/Spec.ts +132 -0
- package/src/cli/bin.test.ts +49 -0
- package/src/cli/bin.ts +5 -1
- package/src/cli/commands/auth.test.ts +138 -0
- package/src/cli/commands/auth.ts +254 -0
- package/src/cli/commands/keys.test.ts +68 -0
- package/src/cli/commands/keys.ts +125 -0
- package/src/cloudflare.ts +184 -36
- package/src/db/Db.test.ts +877 -0
- package/src/db/Db.ts +498 -1
- package/src/db/Schema.ts +75 -4
- package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
- package/src/db/tables/apiKeyAdmissions.ts +101 -11
- package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
- package/src/db/tables/authAccounts.test.ts +30 -0
- package/src/db/tables/authAccounts.ts +1 -0
- package/src/db/tables/earnVaults.test.ts +34 -0
- package/src/db/tables/earnVaults.ts +17 -2
- package/src/db/tables/organizations.test.ts +148 -84
- package/src/db/tables/organizations.ts +11 -43
- package/src/db/tables/requestUsage.ts +13 -2
- package/src/db/tables/rewardCampaigns.test.ts +163 -0
- package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
- package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
- package/src/db/tables/rewardRuns.ts +4 -0
- package/src/db/tables/rewardTransactionAttempts.ts +2 -0
- package/src/db/tables/routesDepositAddresses.test.ts +263 -0
- package/src/db/tables/routesDepositAddresses.ts +118 -34
- package/src/db/tables/routesDeposits.test.ts +66 -5
- package/src/db/tables/routesDeposits.ts +47 -26
- package/src/db/tables/routesIdempotency.test.ts +80 -0
- package/src/db/tables/routesIdempotency.ts +2 -0
- package/src/db/tables/routesPolicies.test.ts +143 -0
- package/src/db/tables/routesPolicies.ts +251 -0
- package/src/db/tables/routesTransferSubsidies.ts +64 -0
- package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
- package/src/db/tables/routesTransfers.test.ts +183 -2
- package/src/db/tables/routesTransfers.ts +65 -6
- package/src/db/tables/sponsoredTransactions.test.ts +351 -76
- package/src/db/tables/sponsoredTransactions.ts +182 -38
- package/src/db/tables/users.test.ts +51 -0
- package/src/db/tables/users.ts +12 -0
- package/src/handlers/internal/multisig.store.test.ts +120 -0
- package/src/handlers/internal/multisig.test.ts +389 -0
- package/src/handlers/internal/multisig.ts +13 -10
- package/src/handlers/relay.test.ts +259 -83
- package/src/handlers/relay.ts +36 -17
- package/src/internal/Auth.test.ts +291 -8
- package/src/internal/Auth.ts +227 -96
- package/src/internal/BetterAuth.test.ts +58 -22
- package/src/internal/BetterAuth.ts +23 -17
- package/src/internal/Cache.ts +3 -1
- package/src/internal/CliAuth.test.ts +279 -0
- package/src/internal/CliAuth.ts +319 -0
- package/src/internal/EarnSharePrices.test.ts +25 -0
- package/src/internal/EarnSharePrices.ts +9 -2
- package/src/internal/EarnVaults.test.ts +67 -0
- package/src/internal/EarnVaults.ts +299 -4
- package/src/internal/EarnWithdrawals.test.ts +315 -0
- package/src/internal/EarnWithdrawals.ts +266 -0
- package/src/internal/ExecutionContext.ts +31 -0
- package/src/internal/Log.test.ts +210 -0
- package/src/internal/Log.ts +180 -142
- package/src/internal/MetricSink.test.ts +190 -15
- package/src/internal/MetricSink.ts +27 -1
- package/src/internal/RateLimit.test.ts +144 -8
- package/src/internal/RateLimit.ts +254 -26
- package/src/internal/Store.ts +4 -5
- package/src/internal/Timing.test.ts +32 -0
- package/src/internal/Timing.ts +20 -1
- package/src/internal/Tron.test-d.ts +22 -0
- package/src/internal/Tron.test.ts +94 -0
- package/src/internal/Tron.ts +289 -0
- package/src/internal/Viem.rpc.test.ts +76 -0
- package/src/internal/Viem.ts +29 -6
- package/src/internal/rewards/Read.test.ts +109 -0
- package/src/internal/rewards/Read.ts +13 -4
- package/src/internal/routes/Action.test.ts +70 -0
- package/src/internal/routes/Action.ts +76 -1
- package/src/internal/routes/Chain.test.ts +18 -0
- package/src/internal/routes/Chain.ts +5 -0
- package/src/internal/routes/DepositAddress.ts +5 -0
- package/src/internal/routes/Evidence.test.ts +64 -0
- package/src/internal/routes/Evidence.ts +11 -3
- package/src/internal/routes/EvmTransferSettlement.ts +213 -0
- package/src/internal/routes/Policy.test.ts +316 -0
- package/src/internal/routes/Policy.ts +399 -0
- package/src/internal/routes/Provider.test.ts +103 -2
- package/src/internal/routes/Provider.ts +149 -27
- package/src/internal/routes/Quota.test.ts +149 -0
- package/src/internal/routes/Quota.ts +226 -0
- package/src/internal/routes/Reconciliation.local.test.ts +285 -0
- package/src/internal/routes/Reconciliation.test.ts +371 -13
- package/src/internal/routes/Reconciliation.ts +193 -42
- package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
- package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
- package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
- package/src/internal/routes/SourceObservation.test.ts +221 -0
- package/src/internal/routes/Subsidy.local.test.ts +46 -0
- package/src/internal/routes/Subsidy.ts +4 -2
- package/src/internal/routes/Transfer.solana.test.ts +389 -0
- package/src/internal/routes/Transfer.test.ts +130 -1
- package/src/internal/routes/Transfer.tron.test.ts +172 -0
- package/src/internal/routes/Transfer.ts +866 -8
- package/src/internal/routes/TransferReconciliation.test.ts +26 -4
- package/src/internal/routes/TransferReconciliation.ts +91 -166
- package/src/internal/routes/TransferSettlement.ts +48 -0
- package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
- package/src/internal/routes/TransferSubsidy.test.ts +34 -4
- package/src/internal/routes/TransferSubsidy.ts +87 -12
- package/src/internal/routes/TronTransferSettlement.ts +212 -0
- package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
- package/src/internal/routes/TronTransferSubsidy.ts +619 -0
- package/src/internal/routes/index.test.ts +3 -0
- package/src/internal/routes/index.ts +3 -0
- package/src/internal/routes/providers/across.ts +13 -0
- package/src/internal/routes/providers/index.test.ts +141 -0
- package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
- package/src/internal/routes/providers/legacyMesh.ts +633 -0
- package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
- package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
- package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
- package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
- package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
- package/src/internal/routes/providers/propAmm.ts +640 -0
- package/src/internal/routes/providers/relay.test.ts +1263 -41
- package/src/internal/routes/providers/relay.ts +423 -38
- package/src/internal/routes/providers/rhino.ts +14 -1
- package/src/internal/routes/providers/squid.ts +21 -0
- package/src/internal/routes/providers/stargate.test.ts +105 -1
- package/src/internal/routes/providers/stargate.ts +22 -9
- package/src/internal/routes/providers/symbiosis.ts +13 -47
- package/src/providers/index.test.ts +2 -0
- package/src/providers/index.ts +18 -0
- package/dist/admin/Access.d.ts +0 -39
- package/dist/admin/Access.d.ts.map +0 -1
- package/dist/admin/Access.js +0 -73
- package/dist/admin/Access.js.map +0 -1
- package/src/admin/Access.test.ts +0 -130
- package/src/admin/Access.ts +0 -85
|
@@ -13,7 +13,6 @@ import type * as Scope from '../../Scope.js'
|
|
|
13
13
|
import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
|
|
14
14
|
import type * as Store from '../../internal/Store.js'
|
|
15
15
|
import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
|
|
16
|
-
import * as Viem from '../../internal/Viem.js'
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Whether the organization has any active billing source — the production
|
|
@@ -449,12 +448,18 @@ export class DuplicateSubscriptionError extends Error {
|
|
|
449
448
|
}
|
|
450
449
|
}
|
|
451
450
|
|
|
451
|
+
/** Safe Stripe meter-event ingestion window below its documented 35-day limit. */
|
|
452
|
+
const meterEventIngestionWindowMs = 34 * 24 * 60 * 60 * 1_000
|
|
453
|
+
|
|
454
|
+
/** Safe retry window below Stripe's documented 24-hour identifier uniqueness period. */
|
|
455
|
+
const meterEventRetryWindowMs = 23 * 60 * 60 * 1_000
|
|
456
|
+
|
|
452
457
|
/**
|
|
453
458
|
* Creates the sponsorship and Route Subsidy metering job. Each tick reports
|
|
454
459
|
* finalized usage, then marks each row after Stripe acknowledges it.
|
|
455
460
|
*/
|
|
456
461
|
export function createReporter(options: createReporter.Options): createReporter.Reporter {
|
|
457
|
-
const { batchSize = 100,
|
|
462
|
+
const { batchSize = 100, db, stripe } = options
|
|
458
463
|
return {
|
|
459
464
|
async tick() {
|
|
460
465
|
// Resolve per tick so Workers factories build a fresh Hyperdrive-pooled
|
|
@@ -462,7 +467,10 @@ export function createReporter(options: createReporter.Options): createReporter.
|
|
|
462
467
|
const database = Db.get(db)
|
|
463
468
|
const [depositSubsidies, sponsorships, transferSubsidies] = await Promise.all([
|
|
464
469
|
RoutesDeposits.listUnreportedSubsidies(database, { limit: batchSize }),
|
|
465
|
-
SponsoredTransactions.
|
|
470
|
+
SponsoredTransactions.claimUnreported(database, {
|
|
471
|
+
attemptedAt: new Date().toISOString(),
|
|
472
|
+
limit: batchSize,
|
|
473
|
+
}),
|
|
466
474
|
RoutesTransfers.listUnreportedSubsidies(database, { limit: batchSize }),
|
|
467
475
|
])
|
|
468
476
|
const rows: UsageRow[] = [
|
|
@@ -532,7 +540,7 @@ export function createReporter(options: createReporter.Options): createReporter.
|
|
|
532
540
|
// just-created meter item bills nothing before its start, so
|
|
533
541
|
// its backlog stamps at now too.
|
|
534
542
|
const finalizedAt = new Date(row.finalizedAt!).getTime()
|
|
535
|
-
const recent = Date.now() - finalizedAt <
|
|
543
|
+
const recent = Date.now() - finalizedAt < meterEventIngestionWindowMs
|
|
536
544
|
const item = subscription.items[kind]
|
|
537
545
|
const stamp =
|
|
538
546
|
recent && item !== undefined && !item.created && finalizedAt >= item.createdAt * 1_000
|
|
@@ -540,6 +548,19 @@ export function createReporter(options: createReporter.Options): createReporter.
|
|
|
540
548
|
meteredAt = new Date(
|
|
541
549
|
(timestamp ?? Math.floor(Date.now() / 1_000)) * 1_000,
|
|
542
550
|
).toISOString()
|
|
551
|
+
if (row.source === 'sponsorship') {
|
|
552
|
+
const firstAttemptedAt = await SponsoredTransactions.beginMeterEvent(
|
|
553
|
+
database,
|
|
554
|
+
row.id,
|
|
555
|
+
new Date().toISOString(),
|
|
556
|
+
)
|
|
557
|
+
// Stripe only deduplicates identifiers for 24 hours. An older
|
|
558
|
+
// uncertain acknowledgment requires reconciliation before resend.
|
|
559
|
+
if (Date.now() - new Date(firstAttemptedAt).getTime() >= meterEventRetryWindowMs)
|
|
560
|
+
throw new Error(
|
|
561
|
+
`Stripe acknowledgement is ambiguous after the safe meter-event retry window for ${row.id}`,
|
|
562
|
+
)
|
|
563
|
+
}
|
|
543
564
|
// The row id makes short-window retries idempotent on Stripe's
|
|
544
565
|
// side; `meter_reported_at` is the durable exactly-once guard.
|
|
545
566
|
try {
|
|
@@ -556,7 +577,20 @@ export function createReporter(options: createReporter.Options): createReporter.
|
|
|
556
577
|
} catch (error) {
|
|
557
578
|
// Stripe may persist the event before the Worker records its ack.
|
|
558
579
|
// Its duplicate response proves this exact row was already metered.
|
|
559
|
-
if (!isDuplicateMeterEvent(error, row.id))
|
|
580
|
+
if (!isDuplicateMeterEvent(error, row.id)) {
|
|
581
|
+
// An explicit client error rejects this submission. Only
|
|
582
|
+
// uncertain outcomes retain the first-send retry clock.
|
|
583
|
+
if (
|
|
584
|
+
row.source === 'sponsorship' &&
|
|
585
|
+
error instanceof Stripe.errors.StripeError &&
|
|
586
|
+
error.statusCode !== undefined &&
|
|
587
|
+
error.statusCode >= 400 &&
|
|
588
|
+
error.statusCode < 500 &&
|
|
589
|
+
error.statusCode !== 409
|
|
590
|
+
)
|
|
591
|
+
await SponsoredTransactions.clearRejectedMeterEventAttempt(database, row.id)
|
|
592
|
+
throw error
|
|
593
|
+
}
|
|
560
594
|
}
|
|
561
595
|
reported++
|
|
562
596
|
} else if (row.source === 'routes-deposit' && row.orgId.startsWith('key_')) {
|
|
@@ -564,16 +598,11 @@ export function createReporter(options: createReporter.Options): createReporter.
|
|
|
564
598
|
// Stripe customer. Provider subsidies on those routes are non-billable.
|
|
565
599
|
meteredAt = new Date().toISOString()
|
|
566
600
|
skipped++
|
|
567
|
-
} else if (row.source !== 'sponsorship') {
|
|
568
|
-
// Production Routes subsidies were authorized against active billing.
|
|
569
|
-
// Keep the liability durable if that customer disappears before reporting.
|
|
570
|
-
throw new Error(`Stripe customer unavailable for Routes subsidy ${row.id}`)
|
|
571
601
|
} else {
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
skipped++
|
|
602
|
+
// Missing billing identity cannot discharge a committed liability; preserve it for retry and alert through the scheduled-task failure counter.
|
|
603
|
+
throw new Error(`Stripe customer unavailable for ${row.source} ${row.id}`)
|
|
575
604
|
}
|
|
576
|
-
// Mark only after the Stripe ack
|
|
605
|
+
// Mark only after the Stripe ack or the non-billable one-off-key exemption.
|
|
577
606
|
const reportedAt = new Date().toISOString()
|
|
578
607
|
if (row.source !== 'sponsorship') {
|
|
579
608
|
if (!meteredAt) throw new Error(`Routes subsidy ${row.id} has no meter timestamp`)
|
|
@@ -635,10 +664,8 @@ function isDuplicateMeterEvent(error: unknown, identifier: string): boolean {
|
|
|
635
664
|
export declare namespace createReporter {
|
|
636
665
|
/** Options for {@link createReporter}. */
|
|
637
666
|
type Options = {
|
|
638
|
-
/** Maximum rows
|
|
667
|
+
/** Maximum rows attempted per source per tick. @default 100 */
|
|
639
668
|
batchSize?: number | undefined
|
|
640
|
-
/** Chains whose spend is metered. @default mainnet */
|
|
641
|
-
chainIds?: readonly number[] | undefined
|
|
642
669
|
/** Database holding sponsorship rows, or a factory resolved per tick (Workers/Hyperdrive). */
|
|
643
670
|
db: Db.Source
|
|
644
671
|
/** Stripe client used to send meter events. */
|
|
@@ -647,7 +674,7 @@ export declare namespace createReporter {
|
|
|
647
674
|
|
|
648
675
|
/** A scheduled metering job. */
|
|
649
676
|
type Reporter = {
|
|
650
|
-
/** Runs one reporting pass. Failed rows stay unmarked and retry
|
|
677
|
+
/** Runs one reporting pass. Failed rows stay unmarked and retry on later ticks. */
|
|
651
678
|
tick(): Promise<{ failed: number; reported: number; skipped: number }>
|
|
652
679
|
}
|
|
653
680
|
}
|
|
@@ -729,14 +756,36 @@ export function createRequestUsageReporter(
|
|
|
729
756
|
const blocked = new Set<string>()
|
|
730
757
|
for (const event of await RequestUsage.listPending(database, environment)) {
|
|
731
758
|
try {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
759
|
+
const eventTimestamp = event.eventTimestamp
|
|
760
|
+
if (
|
|
761
|
+
nowMs - new Date(event.firstAttemptedAt).getTime() >= meterEventRetryWindowMs ||
|
|
762
|
+
(eventTimestamp !== undefined &&
|
|
763
|
+
nowMs - new Date(eventTimestamp).getTime() >= meterEventIngestionWindowMs)
|
|
764
|
+
) {
|
|
765
|
+
failed++
|
|
766
|
+
blocked.add(bucketKey(event.orgId, event.bucketStart))
|
|
767
|
+
await RequestUsage.markError(
|
|
768
|
+
database,
|
|
769
|
+
event.identifier,
|
|
770
|
+
'Stripe acknowledgement is ambiguous after the safe meter-event retry window.',
|
|
771
|
+
)
|
|
772
|
+
continue
|
|
773
|
+
}
|
|
774
|
+
try {
|
|
775
|
+
await client.billing.meterEvents.create({
|
|
776
|
+
event_name: meters.apiRequests.eventName,
|
|
777
|
+
identifier: event.identifier,
|
|
778
|
+
payload: {
|
|
779
|
+
stripe_customer_id: event.stripeCustomerId,
|
|
780
|
+
value: String(event.deltaCount),
|
|
781
|
+
},
|
|
782
|
+
...(eventTimestamp === undefined
|
|
783
|
+
? {}
|
|
784
|
+
: { timestamp: Math.floor(new Date(eventTimestamp).getTime() / 1_000) }),
|
|
785
|
+
})
|
|
786
|
+
} catch (error) {
|
|
787
|
+
if (!isDuplicateMeterEvent(error, event.identifier)) throw error
|
|
788
|
+
}
|
|
740
789
|
if (await RequestUsage.settle(database, event.identifier, new Date().toISOString()))
|
|
741
790
|
reported++
|
|
742
791
|
} catch (error) {
|
|
@@ -781,9 +830,17 @@ export function createRequestUsageReporter(
|
|
|
781
830
|
// The observed watermark is stable for every tick claiming this delta.
|
|
782
831
|
const sequence = watermark?.reportedCount ?? 0
|
|
783
832
|
const identifier = usageIdentifier(environment, orgId, bucketStart, sequence)
|
|
833
|
+
const item = subscription.items.apiRequests
|
|
834
|
+
if (!item) throw new Error(`API request meter item unavailable for ${orgId}`)
|
|
835
|
+
// Meter events before the subscription item's creation are accepted
|
|
836
|
+
// but not invoiced, so clamp backlog to its billing eligibility window.
|
|
837
|
+
const eventTimestamp = new Date(
|
|
838
|
+
Math.max(new Date(bucketStart).getTime(), item.createdAt * 1_000),
|
|
839
|
+
).toISOString()
|
|
784
840
|
const inserted = await RequestUsage.insertPending(database, {
|
|
785
841
|
...key,
|
|
786
842
|
deltaCount: delta,
|
|
843
|
+
eventTimestamp,
|
|
787
844
|
identifier,
|
|
788
845
|
sequence,
|
|
789
846
|
stripeCustomerId: customer.stripeCustomerId,
|
|
@@ -791,14 +848,11 @@ export function createRequestUsageReporter(
|
|
|
791
848
|
// A concurrent tick already claimed this delta; leave it to that run.
|
|
792
849
|
if (!inserted) continue
|
|
793
850
|
|
|
794
|
-
// Backdate to the bucket hour unless the item was just created (it
|
|
795
|
-
// bills nothing before its start, so its backlog stamps at now).
|
|
796
|
-
const stamp = !subscription.items.apiRequests?.created
|
|
797
851
|
await client.billing.meterEvents.create({
|
|
798
852
|
event_name: meters.apiRequests.eventName,
|
|
799
853
|
identifier,
|
|
800
854
|
payload: { stripe_customer_id: customer.stripeCustomerId, value: String(delta) },
|
|
801
|
-
|
|
855
|
+
timestamp: Math.floor(new Date(eventTimestamp).getTime() / 1_000),
|
|
802
856
|
})
|
|
803
857
|
if (await RequestUsage.settle(database, identifier, new Date().toISOString()))
|
|
804
858
|
reported++
|
|
@@ -1010,7 +1010,7 @@ describe('keys', () => {
|
|
|
1010
1010
|
{
|
|
1011
1011
|
"error": {
|
|
1012
1012
|
"code": "api_key_forbidden",
|
|
1013
|
-
"message": "API key missing required
|
|
1013
|
+
"message": "API key is missing required permissions: data:read. Use an API key with these scopes.",
|
|
1014
1014
|
},
|
|
1015
1015
|
}
|
|
1016
1016
|
`)
|
|
@@ -7,6 +7,7 @@ import * as ApiKey from '../../../ApiKey.js'
|
|
|
7
7
|
import * as ApiKeys from '../../../ApiKeys.js'
|
|
8
8
|
import type * as App from '../../../App.js'
|
|
9
9
|
import * as Db from '../../../db/Db.js'
|
|
10
|
+
import * as RoutesPolicies from '../../../db/tables/routesPolicies.js'
|
|
10
11
|
import * as Auth from '../../../internal/Auth.js'
|
|
11
12
|
import * as Billing from '../Billing.js'
|
|
12
13
|
import * as OpenApi from '../../../internal/OpenApi.js'
|
|
@@ -84,7 +85,7 @@ export namespace schema {
|
|
|
84
85
|
.array(z.string().check(z.minLength(1)))
|
|
85
86
|
.check(
|
|
86
87
|
z.describe(
|
|
87
|
-
"Granted scopes. '*'
|
|
88
|
+
"Granted scopes. '*' requires the super admin; a CLI can derive Routes writes from a provisioned project key.",
|
|
88
89
|
),
|
|
89
90
|
z.meta({ examples: [['data:read']] }),
|
|
90
91
|
),
|
|
@@ -205,6 +206,14 @@ export namespace schema {
|
|
|
205
206
|
z.describe('Unique scopes to grant.'),
|
|
206
207
|
z.meta({ examples: [['data:read']] }),
|
|
207
208
|
),
|
|
209
|
+
sourceKeyId: z.optional(
|
|
210
|
+
z
|
|
211
|
+
.string()
|
|
212
|
+
.check(
|
|
213
|
+
z.describe('Approved project key to derive a scoped CLI credential from.'),
|
|
214
|
+
z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
|
|
215
|
+
),
|
|
216
|
+
),
|
|
208
217
|
})
|
|
209
218
|
.check(z.describe('Fields for minting an API key.')),
|
|
210
219
|
'CreateApiKeyRequest',
|
|
@@ -384,6 +393,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
384
393
|
if (!kv) return notEnabled(c)
|
|
385
394
|
const createdBy = mintedBy(c)
|
|
386
395
|
if (!createdBy) return ManagementError.sessionRequired(c)
|
|
396
|
+
const principal = Auth.getPrincipal(c)
|
|
387
397
|
|
|
388
398
|
const body = c.req.valid('json')
|
|
389
399
|
|
|
@@ -395,7 +405,23 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
395
405
|
})
|
|
396
406
|
|
|
397
407
|
// Session issuers are limited to the finite self-serve catalog, so uniqueness bounds the vector without a new policy cap.
|
|
398
|
-
|
|
408
|
+
const source =
|
|
409
|
+
body.sourceKeyId && principal?.type === 'session' && principal.cli
|
|
410
|
+
? await ApiKeys.get(kv.store, body.sourceKeyId, { scopeCatalog: c.get('scopeCatalog') })
|
|
411
|
+
: undefined
|
|
412
|
+
if (
|
|
413
|
+
body.sourceKeyId &&
|
|
414
|
+
(!source ||
|
|
415
|
+
source.orgId !== Auth.org(c).id ||
|
|
416
|
+
source.projectId !== Auth.project(c).id ||
|
|
417
|
+
source.environment !== body.environment)
|
|
418
|
+
)
|
|
419
|
+
return Response.error(c, {
|
|
420
|
+
code: 'scope_not_issuable',
|
|
421
|
+
message: 'Select an approved API key from this project and environment.',
|
|
422
|
+
status: 403,
|
|
423
|
+
})
|
|
424
|
+
if (!canIssue(c, body.scopes, source ?? undefined))
|
|
399
425
|
return Response.error(c, {
|
|
400
426
|
code: 'scope_not_issuable',
|
|
401
427
|
message: 'The requested scopes are not issuable.',
|
|
@@ -416,14 +442,27 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
416
442
|
{
|
|
417
443
|
createdBy,
|
|
418
444
|
environment: body.environment,
|
|
419
|
-
...(
|
|
445
|
+
...(principal?.type === 'session' && principal.cli
|
|
446
|
+
? { expiresAt: principal.cli.expiresAt }
|
|
447
|
+
: {}),
|
|
448
|
+
...(!source && body.allowedIps !== undefined ? { allowedIps: body.allowedIps } : {}),
|
|
420
449
|
...(billingActive === undefined ? {} : { billingActive }),
|
|
421
450
|
...(body.name === undefined ? {} : { name: body.name }),
|
|
422
451
|
orgId,
|
|
423
452
|
projectId: Auth.project(c).id,
|
|
424
453
|
scopes: body.scopes,
|
|
425
454
|
},
|
|
426
|
-
{
|
|
455
|
+
{
|
|
456
|
+
...(source
|
|
457
|
+
? {
|
|
458
|
+
policySourceApiKeyId: source.id,
|
|
459
|
+
sourceScopes: body.scopes.filter(
|
|
460
|
+
(scope) => !Scope.selfServeFrom(c.get('scopeCatalog')).includes(scope),
|
|
461
|
+
),
|
|
462
|
+
}
|
|
463
|
+
: {}),
|
|
464
|
+
scopeCatalog: c.get('scopeCatalog'),
|
|
465
|
+
},
|
|
427
466
|
)
|
|
428
467
|
return c.json(
|
|
429
468
|
Response.validated(schema.createApiKey.Response, { ...serializeKey(record), token }),
|
|
@@ -432,6 +471,12 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
432
471
|
} catch (cause) {
|
|
433
472
|
if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureProjectError(c)
|
|
434
473
|
if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
|
|
474
|
+
if (cause instanceof RoutesPolicies.InvalidScopeError)
|
|
475
|
+
return Response.error(c, {
|
|
476
|
+
code: 'scope_not_issuable',
|
|
477
|
+
message: 'The approved source key is no longer available.',
|
|
478
|
+
status: 403,
|
|
479
|
+
})
|
|
435
480
|
return Response.upstream(c, cause)
|
|
436
481
|
}
|
|
437
482
|
},
|
|
@@ -637,6 +682,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
637
682
|
})
|
|
638
683
|
return await rotate(c, kv.store, source, createdBy)
|
|
639
684
|
} catch (cause) {
|
|
685
|
+
if (cause instanceof RoutesPolicies.InvalidScopeError) return keyNotFound(c)
|
|
640
686
|
if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureOrgError(c)
|
|
641
687
|
if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
|
|
642
688
|
return Response.upstream(c, cause)
|
|
@@ -848,6 +894,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
|
|
|
848
894
|
})
|
|
849
895
|
return await rotate(c, kv.store, source, createdBy)
|
|
850
896
|
} catch (cause) {
|
|
897
|
+
if (cause instanceof RoutesPolicies.InvalidScopeError) return keyNotFound(c)
|
|
851
898
|
if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureProjectError(c)
|
|
852
899
|
if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
|
|
853
900
|
return Response.upstream(c, cause)
|
|
@@ -967,14 +1014,27 @@ function mintedBy(c: Context<App.Environment>) {
|
|
|
967
1014
|
}
|
|
968
1015
|
|
|
969
1016
|
/** Checks whether the caller may grant every requested scope. */
|
|
970
|
-
function canIssue(
|
|
1017
|
+
function canIssue(
|
|
1018
|
+
c: Context<App.Environment>,
|
|
1019
|
+
scopes: readonly Scope.Id[],
|
|
1020
|
+
source?: ApiKeys.Record,
|
|
1021
|
+
) {
|
|
971
1022
|
const principal = Auth.getPrincipal(c)
|
|
972
1023
|
if (principal?.type === 'super_admin') return true
|
|
973
1024
|
if (principal?.type === 'session') {
|
|
974
1025
|
const selfServe = Scope.selfServeFrom(c.get('scopeCatalog'))
|
|
975
1026
|
return (
|
|
976
|
-
scopes.every(
|
|
977
|
-
|
|
1027
|
+
scopes.every(
|
|
1028
|
+
(scope) =>
|
|
1029
|
+
selfServe.includes(scope) ||
|
|
1030
|
+
(principal.cli &&
|
|
1031
|
+
source &&
|
|
1032
|
+
scope === 'routes:write' &&
|
|
1033
|
+
(source.scopes.includes(scope) || source.scopes.includes(Scope.wildcard))),
|
|
1034
|
+
) &&
|
|
1035
|
+
(!principal.cli || scopes.every((scope) => principal.cli!.scopes.includes(scope))) &&
|
|
1036
|
+
((!scopes.includes('management:write') && !scopes.includes('routes:write')) ||
|
|
1037
|
+
Auth.membership(c)?.role === 'owner')
|
|
978
1038
|
)
|
|
979
1039
|
}
|
|
980
1040
|
return false
|
|
@@ -986,8 +1046,11 @@ function canRotate(c: Context<App.Environment>, scopes: readonly Scope.Id[]) {
|
|
|
986
1046
|
if (principal?.type === 'super_admin') return true
|
|
987
1047
|
if (principal?.type !== 'session') return false
|
|
988
1048
|
return (
|
|
989
|
-
(!scopes.
|
|
990
|
-
|
|
1049
|
+
(!principal.cli || scopes.every((scope) => principal.cli!.scopes.includes(scope))) &&
|
|
1050
|
+
((!scopes.includes('management:write') &&
|
|
1051
|
+
!scopes.includes('routes:write') &&
|
|
1052
|
+
!scopes.includes(Scope.wildcard)) ||
|
|
1053
|
+
Auth.membership(c)?.role === 'owner')
|
|
991
1054
|
)
|
|
992
1055
|
}
|
|
993
1056
|
|
|
@@ -998,6 +1061,8 @@ async function rotate(
|
|
|
998
1061
|
source: ApiKeys.Record,
|
|
999
1062
|
createdBy: string,
|
|
1000
1063
|
) {
|
|
1064
|
+
const principal = Auth.getPrincipal(c)
|
|
1065
|
+
const expiresAt = principal?.type === 'session' ? principal.cli?.expiresAt : undefined
|
|
1001
1066
|
const billingActive =
|
|
1002
1067
|
source.environment === 'sandbox'
|
|
1003
1068
|
? await Billing.active(Db.get(c.get('db')), source.orgId, 'sandbox')
|
|
@@ -1013,11 +1078,20 @@ async function rotate(
|
|
|
1013
1078
|
...(source.projectId === undefined ? {} : { projectId: source.projectId }),
|
|
1014
1079
|
scopes: [...new Set(source.scopes)],
|
|
1015
1080
|
...(billingActive === undefined ? {} : { billingActive }),
|
|
1016
|
-
...(
|
|
1081
|
+
...(expiresAt || source.expiresAt
|
|
1082
|
+
? {
|
|
1083
|
+
expiresAt: [expiresAt, source.expiresAt]
|
|
1084
|
+
.filter(Boolean)
|
|
1085
|
+
.sort((a, b) => Date.parse(a!) - Date.parse(b!))[0]!,
|
|
1086
|
+
}
|
|
1087
|
+
: {}),
|
|
1017
1088
|
...(source.name === undefined ? {} : { name: source.name }),
|
|
1018
1089
|
...(source.rateLimits === undefined ? {} : { rateLimits: source.rateLimits }),
|
|
1019
1090
|
},
|
|
1020
|
-
{
|
|
1091
|
+
{
|
|
1092
|
+
policySourceApiKeyId: source.id,
|
|
1093
|
+
scopeCatalog: c.get('scopeCatalog'),
|
|
1094
|
+
},
|
|
1021
1095
|
)
|
|
1022
1096
|
return c.json(
|
|
1023
1097
|
Response.validated(schema.rotateApiKey.Response, { ...serializeKey(record), token }),
|
|
@@ -1636,16 +1636,18 @@ describe.runIf(TestStripe.secretKey)('stripe sandbox (metering)', () => {
|
|
|
1636
1636
|
const finalize = async (input: { feeAmount: string; orgId: string; seed: string }) => {
|
|
1637
1637
|
const row = await SponsoredTransactions.upsert(db, { ...meterable(input.orgId), signPayload: `0x${input.seed.repeat(32)}` }) // prettier-ignore
|
|
1638
1638
|
await SponsoredTransactions.finalize(db, row.id, { feeAmount: input.feeAmount, finalizedAt: new Date().toISOString() }) // prettier-ignore
|
|
1639
|
+
return row
|
|
1639
1640
|
}
|
|
1640
1641
|
await finalize({ feeAmount: '100000', orgId: 'org_1', seed: '41' })
|
|
1641
1642
|
await finalize({ feeAmount: '250000', orgId: 'org_1', seed: '42' })
|
|
1642
|
-
// A
|
|
1643
|
-
await finalize({ feeAmount: '900000', orgId: 'org_ghost', seed: '43' })
|
|
1643
|
+
// A missing customer's liability stays unreported for retry; a pending row waits.
|
|
1644
|
+
const ghost = await finalize({ feeAmount: '900000', orgId: 'org_ghost', seed: '43' })
|
|
1644
1645
|
await SponsoredTransactions.upsert(db, { ...meterable('org_1'), signPayload: `0x${'44'.repeat(32)}` }) // prettier-ignore
|
|
1645
1646
|
|
|
1646
1647
|
const reporter = core_Billing.createReporter({ db, stripe })
|
|
1647
|
-
expect(await reporter.tick()).toStrictEqual({ failed:
|
|
1648
|
-
expect(await reporter.tick()).toStrictEqual({ failed:
|
|
1648
|
+
expect(await reporter.tick()).toStrictEqual({ failed: 1, reported: 2, skipped: 0 })
|
|
1649
|
+
expect(await reporter.tick()).toStrictEqual({ failed: 1, reported: 0, skipped: 0 })
|
|
1650
|
+
expect((await SponsoredTransactions.get(db, ghost.id))?.meterReportedAt).toBeNull()
|
|
1649
1651
|
})
|
|
1650
1652
|
|
|
1651
1653
|
test('the metered invoice preview matches reported spend', { timeout: 240_000 }, async () => {
|
|
@@ -1689,6 +1691,68 @@ describe.runIf(TestStripe.secretKey)('stripe sandbox (metering)', () => {
|
|
|
1689
1691
|
expect(line?.amount).toBe(35)
|
|
1690
1692
|
})
|
|
1691
1693
|
|
|
1694
|
+
test.each(['request-first', 'sponsorship-first'] as const)(
|
|
1695
|
+
'request backlog reaches the invoice when the %s reporter provisions meters',
|
|
1696
|
+
{ timeout: 240_000 },
|
|
1697
|
+
async (ordering) => {
|
|
1698
|
+
const db = TestApp.database()
|
|
1699
|
+
const stripe = TestStripe.client()
|
|
1700
|
+
const orgId = `org_${nanoid(10)}`
|
|
1701
|
+
const customer = await stripe.customers.create({
|
|
1702
|
+
metadata: { orgId },
|
|
1703
|
+
name: `Test Org ${nanoid(10)}`,
|
|
1704
|
+
})
|
|
1705
|
+
TestStripe.track(customer.id)
|
|
1706
|
+
await StripeCustomers.create(db, { orgId, stripeCustomerId: customer.id })
|
|
1707
|
+
const bucket = new Date(Date.now() - 2 * 60 * 60 * 1_000)
|
|
1708
|
+
bucket.setUTCMinutes(0, 0, 0)
|
|
1709
|
+
const bucketStart = bucket.toISOString()
|
|
1710
|
+
const reportRequests = () =>
|
|
1711
|
+
core_Billing
|
|
1712
|
+
.createRequestUsageReporter({
|
|
1713
|
+
db,
|
|
1714
|
+
readCounts: async () => [{ bucketStart, count: 100, orgId }],
|
|
1715
|
+
stripe,
|
|
1716
|
+
})
|
|
1717
|
+
.tick()
|
|
1718
|
+
const reportSponsorship = async () => {
|
|
1719
|
+
const seed = ordering === 'request-first' ? '61' : '62'
|
|
1720
|
+
const row = await SponsoredTransactions.upsert(db, {
|
|
1721
|
+
...meterable(orgId),
|
|
1722
|
+
signPayload: `0x${seed.repeat(32)}`,
|
|
1723
|
+
})
|
|
1724
|
+
await SponsoredTransactions.finalize(db, row.id, {
|
|
1725
|
+
feeAmount: '100000',
|
|
1726
|
+
finalizedAt: new Date().toISOString(),
|
|
1727
|
+
})
|
|
1728
|
+
return core_Billing.createReporter({ db, stripe }).tick()
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
if (ordering === 'request-first') {
|
|
1732
|
+
expect(await reportRequests()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
|
|
1733
|
+
expect(await reportSponsorship()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
|
|
1734
|
+
} else {
|
|
1735
|
+
expect(await reportSponsorship()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
|
|
1736
|
+
expect(await reportRequests()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
const { priceId } = await core_Billing.ensureFixtures(stripe, 'apiRequests')
|
|
1740
|
+
const [subscription] = (
|
|
1741
|
+
await stripe.subscriptions.list({ customer: customer.id, limit: 1, price: priceId })
|
|
1742
|
+
).data
|
|
1743
|
+
let line: { amount: number; quantity: number | null } | undefined
|
|
1744
|
+
await until(async () => {
|
|
1745
|
+
const preview = await stripe.invoices.createPreview({
|
|
1746
|
+
customer: customer.id,
|
|
1747
|
+
subscription: subscription!.id,
|
|
1748
|
+
})
|
|
1749
|
+
line = preview.lines.data.find((item) => item.pricing?.price_details?.price === priceId)
|
|
1750
|
+
return line?.quantity === 100
|
|
1751
|
+
}, 180_000)
|
|
1752
|
+
expect(line).toMatchObject({ amount: 1, quantity: 100 })
|
|
1753
|
+
},
|
|
1754
|
+
)
|
|
1755
|
+
|
|
1692
1756
|
test.each(['past_due', 'canceled'] as const)(
|
|
1693
1757
|
'a failed metered invoice blocks a %s subscription until payment',
|
|
1694
1758
|
{ timeout: 600_000 },
|