tapimo 0.15.1 → 0.18.1
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
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid'
|
|
2
2
|
|
|
3
|
+
import * as TestApp from '../../../test/App.js'
|
|
3
4
|
import * as Runtime from '../../../test/runtime.js'
|
|
4
5
|
import * as Db from '../Db.js'
|
|
6
|
+
import * as ApiKeyOwnerTombstones from './apiKeyOwnerTombstones.js'
|
|
5
7
|
import * as Organizations from './organizations.js'
|
|
6
8
|
import * as Projects from './projects.js'
|
|
7
9
|
import * as SponsorshipAttributions from './sponsorshipAttributions.js'
|
|
8
10
|
import * as SponsoredTransactions from './sponsoredTransactions.js'
|
|
9
11
|
|
|
10
|
-
const create = () => Db.postgres({ connectionString: Runtime.postgresUrl, schema: `t_${nanoid()}` })
|
|
11
|
-
|
|
12
12
|
/** Baseline insert input; tests override per case. */
|
|
13
13
|
const input = {
|
|
14
14
|
apiKeyId: 'key_1',
|
|
@@ -33,9 +33,22 @@ function redact(record: SponsoredTransactions.Record) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
describe('upsert', () => {
|
|
36
|
+
test('behavior: a deleted organization cannot reopen a non-billable commitment', async () => {
|
|
37
|
+
const db = TestApp.database()
|
|
38
|
+
await Organizations.create(db, { id: input.orgId, name: 'One' })
|
|
39
|
+
const row = await SponsoredTransactions.upsert(db, { ...input, billable: false })
|
|
40
|
+
await SponsoredTransactions.fail(db, row.id, new Date().toISOString())
|
|
41
|
+
await db.transaction((tx) => ApiKeyOwnerTombstones.markDeleted(tx, { orgId: input.orgId }))
|
|
42
|
+
|
|
43
|
+
await expect(SponsoredTransactions.upsert(db, input)).rejects.toThrow(
|
|
44
|
+
SponsoredTransactions.OrganizationDeletedError,
|
|
45
|
+
)
|
|
46
|
+
expect((await SponsoredTransactions.get(db, row.id))?.status).toMatchInlineSnapshot(`"failed"`)
|
|
47
|
+
await db.close()
|
|
48
|
+
})
|
|
49
|
+
|
|
36
50
|
test('behavior: records a pending sponsorship with a generated id', async () => {
|
|
37
|
-
const db =
|
|
38
|
-
await db.migrate()
|
|
51
|
+
const db = TestApp.database()
|
|
39
52
|
const record = await SponsoredTransactions.upsert(db, input)
|
|
40
53
|
expect(record.id).toMatch(/^stx_/)
|
|
41
54
|
expect(redact(record)).toMatchInlineSnapshot(`
|
|
@@ -52,6 +65,8 @@ describe('upsert', () => {
|
|
|
52
65
|
"finalizationAttemptedAt": null,
|
|
53
66
|
"finalizedAt": null,
|
|
54
67
|
"id": "stx_<id>",
|
|
68
|
+
"meterEventFirstAttemptedAt": null,
|
|
69
|
+
"meterReportAttemptedAt": null,
|
|
55
70
|
"meterReportedAt": null,
|
|
56
71
|
"orgId": "org_1",
|
|
57
72
|
"projectId": "prj_1",
|
|
@@ -60,6 +75,7 @@ describe('upsert', () => {
|
|
|
60
75
|
"status": "pending",
|
|
61
76
|
"transaction": "0x76cccccccccccccccccccccccccccccccc",
|
|
62
77
|
"transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
78
|
+
"transactionHashReconciled": false,
|
|
63
79
|
}
|
|
64
80
|
`)
|
|
65
81
|
expect(await SponsoredTransactions.get(db, record.id)).toStrictEqual(record)
|
|
@@ -67,8 +83,7 @@ describe('upsert', () => {
|
|
|
67
83
|
})
|
|
68
84
|
|
|
69
85
|
test('behavior: records organization-level sponsorship without a project', async () => {
|
|
70
|
-
const db =
|
|
71
|
-
await db.migrate()
|
|
86
|
+
const db = TestApp.database()
|
|
72
87
|
const { projectId: _, ...organization } = input
|
|
73
88
|
const record = await SponsoredTransactions.upsert(db, organization)
|
|
74
89
|
|
|
@@ -78,16 +93,14 @@ describe('upsert', () => {
|
|
|
78
93
|
})
|
|
79
94
|
|
|
80
95
|
test('behavior: preserves an explicit fee token', async () => {
|
|
81
|
-
const db =
|
|
82
|
-
await db.migrate()
|
|
96
|
+
const db = TestApp.database()
|
|
83
97
|
const record = await SponsoredTransactions.upsert(db, { ...input, feeToken: `0x${'fe'.repeat(20)}` }) // prettier-ignore
|
|
84
98
|
expect(record.feeToken).toMatchInlineSnapshot(`"0xfefefefefefefefefefefefefefefefefefefefe"`)
|
|
85
99
|
await db.close()
|
|
86
100
|
})
|
|
87
101
|
|
|
88
102
|
test('behavior: records fill intents without a transaction hash', async () => {
|
|
89
|
-
const db =
|
|
90
|
-
await db.migrate()
|
|
103
|
+
const db = TestApp.database()
|
|
91
104
|
const { transactionHash: _, ...intent } = input
|
|
92
105
|
const record = await SponsoredTransactions.upsert(db, intent)
|
|
93
106
|
expect(record.transactionHash).toBeNull()
|
|
@@ -96,8 +109,7 @@ describe('upsert', () => {
|
|
|
96
109
|
})
|
|
97
110
|
|
|
98
111
|
test('behavior: a raw submission upgrades a fill intent in place', async () => {
|
|
99
|
-
const db =
|
|
100
|
-
await db.migrate()
|
|
112
|
+
const db = TestApp.database()
|
|
101
113
|
const { transactionHash: _, ...intent } = input
|
|
102
114
|
const first = await SponsoredTransactions.upsert(db, intent)
|
|
103
115
|
const second = await SponsoredTransactions.upsert(db, input)
|
|
@@ -112,8 +124,7 @@ describe('upsert', () => {
|
|
|
112
124
|
})
|
|
113
125
|
|
|
114
126
|
test('behavior: rejects a sign payload already attributed to another org', async () => {
|
|
115
|
-
const db =
|
|
116
|
-
await db.migrate()
|
|
127
|
+
const db = TestApp.database()
|
|
117
128
|
const first = await SponsoredTransactions.upsert(db, input)
|
|
118
129
|
|
|
119
130
|
await expect(
|
|
@@ -129,8 +140,7 @@ describe('upsert', () => {
|
|
|
129
140
|
})
|
|
130
141
|
|
|
131
142
|
test('behavior: rejects a sign payload already attributed to another project', async () => {
|
|
132
|
-
const db =
|
|
133
|
-
await db.migrate()
|
|
143
|
+
const db = TestApp.database()
|
|
134
144
|
const { transactionHash: _, ...intent } = input
|
|
135
145
|
const first = await SponsoredTransactions.upsert(db, intent)
|
|
136
146
|
|
|
@@ -143,8 +153,7 @@ describe('upsert', () => {
|
|
|
143
153
|
})
|
|
144
154
|
|
|
145
155
|
test('behavior: a raw submission reopens a failed fill intent', async () => {
|
|
146
|
-
const db =
|
|
147
|
-
await db.migrate()
|
|
156
|
+
const db = TestApp.database()
|
|
148
157
|
const { transactionHash: _, ...intent } = input
|
|
149
158
|
const first = await SponsoredTransactions.upsert(db, intent)
|
|
150
159
|
await SponsoredTransactions.fail(db, first.id, '2026-01-01T00:00:00.000Z')
|
|
@@ -162,8 +171,7 @@ describe('upsert', () => {
|
|
|
162
171
|
})
|
|
163
172
|
|
|
164
173
|
test('behavior: a duplicate intent never clears a known hash', async () => {
|
|
165
|
-
const db =
|
|
166
|
-
await db.migrate()
|
|
174
|
+
const db = TestApp.database()
|
|
167
175
|
const first = await SponsoredTransactions.upsert(db, input)
|
|
168
176
|
const { transactionHash: _, ...intent } = input
|
|
169
177
|
const second = await SponsoredTransactions.upsert(db, intent)
|
|
@@ -174,12 +182,50 @@ describe('upsert', () => {
|
|
|
174
182
|
)
|
|
175
183
|
await db.close()
|
|
176
184
|
})
|
|
185
|
+
|
|
186
|
+
test('behavior: a raw retry never replaces a reconciled hash', async () => {
|
|
187
|
+
const db = TestApp.database()
|
|
188
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
189
|
+
const reconciledHash = `0x${'ab'.repeat(32)}`
|
|
190
|
+
await SponsoredTransactions.assignTransactionHash(db, record.id, reconciledHash)
|
|
191
|
+
|
|
192
|
+
const pending = await SponsoredTransactions.upsert(db, input)
|
|
193
|
+
expect(pending.transactionHash).toBe(reconciledHash)
|
|
194
|
+
expect(pending.transactionHashReconciled).toBe(true)
|
|
195
|
+
await SponsoredTransactions.finalize(db, record.id, {
|
|
196
|
+
feeAmount: '1',
|
|
197
|
+
finalizedAt: new Date().toISOString(),
|
|
198
|
+
transactionHash: reconciledHash,
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
expect((await SponsoredTransactions.upsert(db, input)).transactionHash).toBe(reconciledHash)
|
|
202
|
+
await db.close()
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('behavior: a raw retry never replaces a legacy finalized hash', async () => {
|
|
206
|
+
const db = TestApp.database()
|
|
207
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
208
|
+
await SponsoredTransactions.finalize(db, record.id, {
|
|
209
|
+
feeAmount: '1',
|
|
210
|
+
finalizedAt: new Date().toISOString(),
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
const retried = await SponsoredTransactions.upsert(db, {
|
|
214
|
+
...input,
|
|
215
|
+
transactionHash: `0x${'ab'.repeat(32)}`,
|
|
216
|
+
})
|
|
217
|
+
expect(retried).toMatchObject({
|
|
218
|
+
status: 'finalized',
|
|
219
|
+
transactionHash: input.transactionHash,
|
|
220
|
+
transactionHashReconciled: false,
|
|
221
|
+
})
|
|
222
|
+
await db.close()
|
|
223
|
+
})
|
|
177
224
|
})
|
|
178
225
|
|
|
179
226
|
describe('listPending', () => {
|
|
180
227
|
test('behavior: returns only pending rows, capped by limit', async () => {
|
|
181
|
-
const db =
|
|
182
|
-
await db.migrate()
|
|
228
|
+
const db = TestApp.database()
|
|
183
229
|
await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b1'.repeat(32)}`, transactionHash: `0x${'a1'.repeat(32)}` }) // prettier-ignore
|
|
184
230
|
const second = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b2'.repeat(32)}`, transactionHash: `0x${'a2'.repeat(32)}` }) // prettier-ignore
|
|
185
231
|
await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b3'.repeat(32)}`, transactionHash: `0x${'a3'.repeat(32)}` }) // prettier-ignore
|
|
@@ -204,8 +250,7 @@ describe('listPending', () => {
|
|
|
204
250
|
|
|
205
251
|
describe('claimPending', () => {
|
|
206
252
|
test('behavior: rotates through a bounded backlog before retrying rows', async () => {
|
|
207
|
-
const db =
|
|
208
|
-
await db.migrate()
|
|
253
|
+
const db = TestApp.database()
|
|
209
254
|
for (let index = 1; index <= 5; index++)
|
|
210
255
|
await SponsoredTransactions.upsert(db, {
|
|
211
256
|
...input,
|
|
@@ -234,10 +279,9 @@ describe('claimPending', () => {
|
|
|
234
279
|
})
|
|
235
280
|
})
|
|
236
281
|
|
|
237
|
-
describe('
|
|
238
|
-
test('behavior: returns
|
|
239
|
-
const db =
|
|
240
|
-
await db.migrate()
|
|
282
|
+
describe('listReconciliationCandidates', () => {
|
|
283
|
+
test('behavior: returns pending sponsorships without failed rows', async () => {
|
|
284
|
+
const db = TestApp.database()
|
|
241
285
|
const { transactionHash: _, ...intent } = input
|
|
242
286
|
const failed = await SponsoredTransactions.upsert(db, intent)
|
|
243
287
|
await SponsoredTransactions.fail(db, failed.id, new Date().toISOString())
|
|
@@ -245,18 +289,33 @@ describe('listIntents', () => {
|
|
|
245
289
|
...intent,
|
|
246
290
|
signPayload: `0x${'bc'.repeat(32)}`,
|
|
247
291
|
})
|
|
292
|
+
const submitted = await SponsoredTransactions.upsert(db, {
|
|
293
|
+
...input,
|
|
294
|
+
signPayload: `0x${'bd'.repeat(32)}`,
|
|
295
|
+
})
|
|
296
|
+
const confirmed = await SponsoredTransactions.upsert(db, {
|
|
297
|
+
...input,
|
|
298
|
+
signPayload: `0x${'be'.repeat(32)}`,
|
|
299
|
+
})
|
|
300
|
+
await SponsoredTransactions.assignTransactionHash(db, confirmed.id, input.transactionHash)
|
|
248
301
|
|
|
249
|
-
expect(
|
|
250
|
-
|
|
251
|
-
|
|
302
|
+
expect(
|
|
303
|
+
(await SponsoredTransactions.listReconciliationCandidates(db))
|
|
304
|
+
.map((record) => record.id)
|
|
305
|
+
.sort(),
|
|
306
|
+
).toStrictEqual([pending.id, submitted.id].sort())
|
|
307
|
+
expect(
|
|
308
|
+
(await SponsoredTransactions.listReconciliationCandidates(db, { limit: 1 })).map(
|
|
309
|
+
(record) => record.transactionHash === null,
|
|
310
|
+
),
|
|
311
|
+
).toStrictEqual([true, false])
|
|
252
312
|
await db.close()
|
|
253
313
|
})
|
|
254
314
|
})
|
|
255
315
|
|
|
256
316
|
describe('listRecoveryWindows', () => {
|
|
257
317
|
test('behavior: returns each chain with its oldest eligible failed intent', async () => {
|
|
258
|
-
const db =
|
|
259
|
-
await db.migrate()
|
|
318
|
+
const db = TestApp.database()
|
|
260
319
|
const { transactionHash: _, ...intent } = input
|
|
261
320
|
vi.useFakeTimers({ now: new Date('2026-01-01T00:00:00.000Z') })
|
|
262
321
|
try {
|
|
@@ -293,12 +352,24 @@ describe('listRecoveryWindows', () => {
|
|
|
293
352
|
await db.close()
|
|
294
353
|
}
|
|
295
354
|
})
|
|
355
|
+
|
|
356
|
+
test('behavior: includes recently failed sponsorships with recorded hashes', async () => {
|
|
357
|
+
const db = TestApp.database()
|
|
358
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
359
|
+
await SponsoredTransactions.fail(db, record.id, '2026-01-02T00:00:00.000Z')
|
|
360
|
+
|
|
361
|
+
expect(
|
|
362
|
+
await SponsoredTransactions.listRecoveryWindows(db, {
|
|
363
|
+
failedSince: '2026-01-01T12:00:00.000Z',
|
|
364
|
+
}),
|
|
365
|
+
).toMatchObject([{ chainId: input.chainId }])
|
|
366
|
+
await db.close()
|
|
367
|
+
})
|
|
296
368
|
})
|
|
297
369
|
|
|
298
370
|
describe('listRecoverableIntents', () => {
|
|
299
371
|
test('behavior: returns pending and eligible failed intents matching candidate payloads', async () => {
|
|
300
|
-
const db =
|
|
301
|
-
await db.migrate()
|
|
372
|
+
const db = TestApp.database()
|
|
302
373
|
const { transactionHash: _, ...intent } = input
|
|
303
374
|
const pending = await SponsoredTransactions.upsert(db, {
|
|
304
375
|
...intent,
|
|
@@ -324,12 +395,25 @@ describe('listRecoverableIntents', () => {
|
|
|
324
395
|
).toStrictEqual([eligible.id, pending.id].sort())
|
|
325
396
|
await db.close()
|
|
326
397
|
})
|
|
398
|
+
|
|
399
|
+
test('behavior: returns eligible failed sponsorships with recorded hashes', async () => {
|
|
400
|
+
const db = TestApp.database()
|
|
401
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
402
|
+
await SponsoredTransactions.fail(db, record.id, '2026-01-02T00:00:00.000Z')
|
|
403
|
+
|
|
404
|
+
expect(
|
|
405
|
+
await SponsoredTransactions.listRecoverableIntents(db, {
|
|
406
|
+
failedSince: '2026-01-01T12:00:00.000Z',
|
|
407
|
+
signPayloads: [record.signPayload],
|
|
408
|
+
}),
|
|
409
|
+
).toMatchObject([{ id: record.id, transactionHash: input.transactionHash }])
|
|
410
|
+
await db.close()
|
|
411
|
+
})
|
|
327
412
|
})
|
|
328
413
|
|
|
329
414
|
describe('assignTransactionHash', () => {
|
|
330
415
|
test('behavior: reopens a failed intent when reconciliation finds its hash', async () => {
|
|
331
|
-
const db =
|
|
332
|
-
await db.migrate()
|
|
416
|
+
const db = TestApp.database()
|
|
333
417
|
await Organizations.create(db, { id: 'org_1', name: 'One' })
|
|
334
418
|
const { transactionHash: _, ...intent } = input
|
|
335
419
|
const record = await SponsoredTransactions.upsert(db, intent)
|
|
@@ -346,9 +430,24 @@ describe('assignTransactionHash', () => {
|
|
|
346
430
|
await db.close()
|
|
347
431
|
})
|
|
348
432
|
|
|
433
|
+
test('behavior: reopens a failed sponsorship under its mined replacement hash', async () => {
|
|
434
|
+
const db = TestApp.database()
|
|
435
|
+
await Organizations.create(db, { id: 'org_1', name: 'One' })
|
|
436
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
437
|
+
await SponsoredTransactions.fail(db, record.id, new Date().toISOString())
|
|
438
|
+
const replacementHash = `0x${'ab'.repeat(32)}`
|
|
439
|
+
|
|
440
|
+
await SponsoredTransactions.assignTransactionHash(db, record.id, replacementHash)
|
|
441
|
+
|
|
442
|
+
expect(await SponsoredTransactions.get(db, record.id)).toMatchObject({
|
|
443
|
+
status: 'pending',
|
|
444
|
+
transactionHash: replacementHash,
|
|
445
|
+
})
|
|
446
|
+
await db.close()
|
|
447
|
+
})
|
|
448
|
+
|
|
349
449
|
test('behavior: does not reopen failed intents after the recovery window', async () => {
|
|
350
|
-
const db =
|
|
351
|
-
await db.migrate()
|
|
450
|
+
const db = TestApp.database()
|
|
352
451
|
await Organizations.create(db, { id: 'org_1', name: 'One' })
|
|
353
452
|
const { transactionHash: _, ...intent } = input
|
|
354
453
|
const record = await SponsoredTransactions.upsert(db, intent)
|
|
@@ -367,8 +466,7 @@ describe('assignTransactionHash', () => {
|
|
|
367
466
|
})
|
|
368
467
|
|
|
369
468
|
test('behavior: does not reopen failed intents for deleted orgs', async () => {
|
|
370
|
-
const db =
|
|
371
|
-
await db.migrate()
|
|
469
|
+
const db = TestApp.database()
|
|
372
470
|
const { transactionHash: _, ...intent } = input
|
|
373
471
|
const record = await SponsoredTransactions.upsert(db, intent)
|
|
374
472
|
await SponsoredTransactions.fail(db, record.id, new Date().toISOString())
|
|
@@ -382,8 +480,7 @@ describe('assignTransactionHash', () => {
|
|
|
382
480
|
})
|
|
383
481
|
|
|
384
482
|
test('behavior: keeps an over-limit failed intent retryable across a period rollover', async () => {
|
|
385
|
-
const db =
|
|
386
|
-
await db.migrate()
|
|
483
|
+
const db = TestApp.database()
|
|
387
484
|
await Organizations.create(db, { id: 'org_1', name: 'One' })
|
|
388
485
|
const { transactionHash: _, ...intent } = input
|
|
389
486
|
vi.useFakeTimers({ now: new Date('2026-01-31T23:59:00.000Z') })
|
|
@@ -427,8 +524,7 @@ describe('assignTransactionHash', () => {
|
|
|
427
524
|
|
|
428
525
|
describe('finalize', () => {
|
|
429
526
|
test('behavior: transitions pending → finalized with the actual fee', async () => {
|
|
430
|
-
const db =
|
|
431
|
-
await db.migrate()
|
|
527
|
+
const db = TestApp.database()
|
|
432
528
|
const record = await SponsoredTransactions.upsert(db, input)
|
|
433
529
|
await SponsoredTransactions.finalize(db, record.id, {
|
|
434
530
|
feeAmount: '21000',
|
|
@@ -441,9 +537,58 @@ describe('finalize', () => {
|
|
|
441
537
|
await db.close()
|
|
442
538
|
})
|
|
443
539
|
|
|
540
|
+
test('behavior: stale finalization cannot settle or fail a reconciled hash', async () => {
|
|
541
|
+
const db = TestApp.database()
|
|
542
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
543
|
+
const reconciledHash = `0x${'ab'.repeat(32)}`
|
|
544
|
+
await SponsoredTransactions.assignTransactionHash(db, record.id, reconciledHash)
|
|
545
|
+
|
|
546
|
+
await SponsoredTransactions.finalize(db, record.id, {
|
|
547
|
+
feeAmount: '1',
|
|
548
|
+
finalizedAt: new Date().toISOString(),
|
|
549
|
+
transactionHash: input.transactionHash,
|
|
550
|
+
})
|
|
551
|
+
await SponsoredTransactions.fail(db, record.id, new Date().toISOString(), {
|
|
552
|
+
transactionHash: input.transactionHash,
|
|
553
|
+
})
|
|
554
|
+
expect(await SponsoredTransactions.get(db, record.id)).toMatchObject({
|
|
555
|
+
status: 'pending',
|
|
556
|
+
transactionHash: reconciledHash,
|
|
557
|
+
transactionHashReconciled: true,
|
|
558
|
+
})
|
|
559
|
+
|
|
560
|
+
await SponsoredTransactions.finalize(db, record.id, {
|
|
561
|
+
feeAmount: '1',
|
|
562
|
+
finalizedAt: new Date().toISOString(),
|
|
563
|
+
transactionHash: reconciledHash,
|
|
564
|
+
})
|
|
565
|
+
expect((await SponsoredTransactions.get(db, record.id))?.status).toBe('finalized')
|
|
566
|
+
await db.close()
|
|
567
|
+
})
|
|
568
|
+
|
|
569
|
+
test('behavior: a receipt-fenced finalization preserves its hash against raw retries', async () => {
|
|
570
|
+
const db = TestApp.database()
|
|
571
|
+
const record = await SponsoredTransactions.upsert(db, input)
|
|
572
|
+
await SponsoredTransactions.finalize(db, record.id, {
|
|
573
|
+
feeAmount: '1',
|
|
574
|
+
finalizedAt: new Date().toISOString(),
|
|
575
|
+
transactionHash: input.transactionHash,
|
|
576
|
+
})
|
|
577
|
+
|
|
578
|
+
const retried = await SponsoredTransactions.upsert(db, {
|
|
579
|
+
...input,
|
|
580
|
+
transactionHash: `0x${'ab'.repeat(32)}`,
|
|
581
|
+
})
|
|
582
|
+
expect(retried).toMatchObject({
|
|
583
|
+
status: 'finalized',
|
|
584
|
+
transactionHash: input.transactionHash,
|
|
585
|
+
transactionHashReconciled: true,
|
|
586
|
+
})
|
|
587
|
+
await db.close()
|
|
588
|
+
})
|
|
589
|
+
|
|
444
590
|
test('behavior: no-op on rows that are no longer pending', async () => {
|
|
445
|
-
const db =
|
|
446
|
-
await db.migrate()
|
|
591
|
+
const db = TestApp.database()
|
|
447
592
|
const record = await SponsoredTransactions.upsert(db, input)
|
|
448
593
|
await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
|
|
449
594
|
await SponsoredTransactions.finalize(db, record.id, {
|
|
@@ -459,8 +604,7 @@ describe('finalize', () => {
|
|
|
459
604
|
|
|
460
605
|
describe('fail', () => {
|
|
461
606
|
test('behavior: transitions pending → failed without a fee', async () => {
|
|
462
|
-
const db =
|
|
463
|
-
await db.migrate()
|
|
607
|
+
const db = TestApp.database()
|
|
464
608
|
const record = await SponsoredTransactions.upsert(db, input)
|
|
465
609
|
await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
|
|
466
610
|
const failed = await SponsoredTransactions.get(db, record.id)
|
|
@@ -473,7 +617,7 @@ describe('fail', () => {
|
|
|
473
617
|
|
|
474
618
|
describe('migration 0032', () => {
|
|
475
619
|
test('behavior: rescales legacy attodollar fee amounts idempotently', async () => {
|
|
476
|
-
const db =
|
|
620
|
+
const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema: `t_${nanoid()}` })
|
|
477
621
|
await db.migrate()
|
|
478
622
|
// A pre-scaling row stored raw attodollars: 2.1e18 + 1, non-divisible so
|
|
479
623
|
// the rescale must round up.
|
|
@@ -502,8 +646,7 @@ describe('migration 0032', () => {
|
|
|
502
646
|
|
|
503
647
|
describe('spend', () => {
|
|
504
648
|
test('behavior: sums finalized fees plus pending caps within scope', async () => {
|
|
505
|
-
const db =
|
|
506
|
-
await db.migrate()
|
|
649
|
+
const db = TestApp.database()
|
|
507
650
|
const chainIds = [input.chainId]
|
|
508
651
|
// Finalized in scope: counts its actual fee, never its cap.
|
|
509
652
|
const finalized = await SponsoredTransactions.upsert(db, { ...input, feeMax: '900000', signPayload: `0x${'01'.repeat(32)}` }) // prettier-ignore
|
|
@@ -529,8 +672,7 @@ describe('spend', () => {
|
|
|
529
672
|
})
|
|
530
673
|
|
|
531
674
|
test('behavior: rows created before the window start are out of scope', async () => {
|
|
532
|
-
const db =
|
|
533
|
-
await db.migrate()
|
|
675
|
+
const db = TestApp.database()
|
|
534
676
|
await SponsoredTransactions.upsert(db, { ...input, feeMax: '250000', signPayload: `0x${'08'.repeat(32)}` }) // prettier-ignore
|
|
535
677
|
const future = new Date(Date.now() + 60_000).toISOString()
|
|
536
678
|
expect(await SponsoredTransactions.spend(db, { chainIds: [input.chainId], orgId: 'org_1', since: future })).toBe(0n) // prettier-ignore
|
|
@@ -538,8 +680,7 @@ describe('spend', () => {
|
|
|
538
680
|
})
|
|
539
681
|
|
|
540
682
|
test('behavior: promotional spend is isolated by project', async () => {
|
|
541
|
-
const db =
|
|
542
|
-
await db.migrate()
|
|
683
|
+
const db = TestApp.database()
|
|
543
684
|
await SponsoredTransactions.upsert(db, {
|
|
544
685
|
...input,
|
|
545
686
|
billable: false,
|
|
@@ -570,8 +711,7 @@ describe('spend', () => {
|
|
|
570
711
|
|
|
571
712
|
describe('reserve', () => {
|
|
572
713
|
test('behavior: enforces promotional limits independently per project', async () => {
|
|
573
|
-
const db =
|
|
574
|
-
await db.migrate()
|
|
714
|
+
const db = TestApp.database()
|
|
575
715
|
const limit = {
|
|
576
716
|
billable: false,
|
|
577
717
|
chainIds: [input.chainId],
|
|
@@ -627,8 +767,7 @@ describe('reservePromotion', () => {
|
|
|
627
767
|
}
|
|
628
768
|
|
|
629
769
|
test('behavior: atomically records the first sponsorship and immutable window', async () => {
|
|
630
|
-
const db =
|
|
631
|
-
await db.migrate()
|
|
770
|
+
const db = TestApp.database()
|
|
632
771
|
await configure(db, '0.000001')
|
|
633
772
|
const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
|
|
634
773
|
const attribution = await SponsorshipAttributions.resolveProject(db, {
|
|
@@ -668,8 +807,7 @@ describe('reservePromotion', () => {
|
|
|
668
807
|
})
|
|
669
808
|
|
|
670
809
|
test('behavior: records an uncapped promotion', async () => {
|
|
671
|
-
const db =
|
|
672
|
-
await db.migrate()
|
|
810
|
+
const db = TestApp.database()
|
|
673
811
|
await configure(db, null)
|
|
674
812
|
const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
|
|
675
813
|
const attribution = await SponsorshipAttributions.resolveProject(db, {
|
|
@@ -720,8 +858,7 @@ describe('reservePromotion', () => {
|
|
|
720
858
|
})
|
|
721
859
|
|
|
722
860
|
test('behavior: reads the current organization policy when activating', async () => {
|
|
723
|
-
const db =
|
|
724
|
-
await db.migrate()
|
|
861
|
+
const db = TestApp.database()
|
|
725
862
|
await configure(db, '0.000001')
|
|
726
863
|
const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
|
|
727
864
|
const attribution = await SponsorshipAttributions.resolveProject(db, {
|
|
@@ -756,8 +893,7 @@ describe('reservePromotion', () => {
|
|
|
756
893
|
})
|
|
757
894
|
|
|
758
895
|
test('behavior: conflicting envelopes do not activate another project', async () => {
|
|
759
|
-
const db =
|
|
760
|
-
await db.migrate()
|
|
896
|
+
const db = TestApp.database()
|
|
761
897
|
await configure(db, null)
|
|
762
898
|
const first = await Projects.create(db, { name: 'First', orgId: 'org_1' })
|
|
763
899
|
const second = await Projects.create(db, { name: 'Second', orgId: 'org_1' })
|
|
@@ -790,8 +926,7 @@ describe('reservePromotion', () => {
|
|
|
790
926
|
})
|
|
791
927
|
|
|
792
928
|
test('behavior: policy changes preserve unattributed retry snapshots', async () => {
|
|
793
|
-
const db =
|
|
794
|
-
await db.migrate()
|
|
929
|
+
const db = TestApp.database()
|
|
795
930
|
await configure(db, null)
|
|
796
931
|
const existing = await SponsoredTransactions.upsert(db, { ...input, billable: true })
|
|
797
932
|
const attribution = await SponsorshipAttributions.resolveExternal(db, {
|
|
@@ -826,8 +961,7 @@ describe('reservePromotion', () => {
|
|
|
826
961
|
})
|
|
827
962
|
|
|
828
963
|
test('behavior: later policy changes cannot raise an activated project cap', async () => {
|
|
829
|
-
const db =
|
|
830
|
-
await db.migrate()
|
|
964
|
+
const db = TestApp.database()
|
|
831
965
|
await configure(db, '0.000001')
|
|
832
966
|
const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
|
|
833
967
|
const attribution = await SponsorshipAttributions.resolveProject(db, {
|
|
@@ -873,8 +1007,7 @@ describe('reservePromotion', () => {
|
|
|
873
1007
|
})
|
|
874
1008
|
|
|
875
1009
|
test('behavior: preserves activation when the first sponsorship exceeds the cap', async () => {
|
|
876
|
-
const db =
|
|
877
|
-
await db.migrate()
|
|
1010
|
+
const db = TestApp.database()
|
|
878
1011
|
await configure(db, '0')
|
|
879
1012
|
const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
|
|
880
1013
|
const attribution = await SponsorshipAttributions.resolveProject(db, {
|
|
@@ -950,8 +1083,7 @@ describe('reservePromotion', () => {
|
|
|
950
1083
|
|
|
951
1084
|
describe('listUnreported', () => {
|
|
952
1085
|
test('behavior: lists finalized billable in-scope rows, oldest first', async () => {
|
|
953
|
-
const db =
|
|
954
|
-
await db.migrate()
|
|
1086
|
+
const db = TestApp.database()
|
|
955
1087
|
const chainIds = [input.chainId]
|
|
956
1088
|
const first = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'11'.repeat(32)}` }) // prettier-ignore
|
|
957
1089
|
await SponsoredTransactions.finalize(db, first.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
|
|
@@ -980,10 +1112,98 @@ describe('listUnreported', () => {
|
|
|
980
1112
|
})
|
|
981
1113
|
})
|
|
982
1114
|
|
|
1115
|
+
describe('claimUnreported', () => {
|
|
1116
|
+
test('reserves retry capacity while untouched sponsorships keep progressing', async () => {
|
|
1117
|
+
const db = TestApp.database()
|
|
1118
|
+
const rows = []
|
|
1119
|
+
for (const [seed, day] of [
|
|
1120
|
+
['31', 1],
|
|
1121
|
+
['32', 2],
|
|
1122
|
+
['33', 3],
|
|
1123
|
+
['34', 4],
|
|
1124
|
+
] as const) {
|
|
1125
|
+
const row = await SponsoredTransactions.upsert(db, {
|
|
1126
|
+
...input,
|
|
1127
|
+
signPayload: `0x${seed.repeat(32)}`,
|
|
1128
|
+
})
|
|
1129
|
+
await SponsoredTransactions.finalize(db, row.id, {
|
|
1130
|
+
feeAmount: '100',
|
|
1131
|
+
finalizedAt: `2026-01-0${day}T00:00:00.000Z`,
|
|
1132
|
+
})
|
|
1133
|
+
rows.push(row)
|
|
1134
|
+
}
|
|
1135
|
+
await SponsoredTransactions.beginMeterEvent(db, rows[0]!.id, '2026-01-02T00:00:00.000Z')
|
|
1136
|
+
|
|
1137
|
+
const first = await SponsoredTransactions.claimUnreported(db, {
|
|
1138
|
+
attemptedAt: '2026-01-03T00:00:00.000Z',
|
|
1139
|
+
limit: 2,
|
|
1140
|
+
})
|
|
1141
|
+
expect(first.map((row) => row.id)).toStrictEqual([rows[0]!.id, rows[1]!.id])
|
|
1142
|
+
const second = await SponsoredTransactions.claimUnreported(db, {
|
|
1143
|
+
attemptedAt: '2026-01-04T00:00:00.000Z',
|
|
1144
|
+
limit: 2,
|
|
1145
|
+
})
|
|
1146
|
+
expect(second.map((row) => row.id)).toStrictEqual([rows[0]!.id, rows[2]!.id])
|
|
1147
|
+
await db.close()
|
|
1148
|
+
})
|
|
1149
|
+
|
|
1150
|
+
test('rotates failed claims behind untouched rows across historical chains', async () => {
|
|
1151
|
+
const db = TestApp.database()
|
|
1152
|
+
const rows = []
|
|
1153
|
+
for (const [seed, chainId, finalizedAt] of [
|
|
1154
|
+
['21', input.chainId, '2026-01-01T00:00:00.000Z'],
|
|
1155
|
+
['22', 421700099, '2026-01-02T00:00:00.000Z'],
|
|
1156
|
+
['23', input.chainId, '2026-01-03T00:00:00.000Z'],
|
|
1157
|
+
] as const) {
|
|
1158
|
+
const row = await SponsoredTransactions.upsert(db, {
|
|
1159
|
+
...input,
|
|
1160
|
+
chainId,
|
|
1161
|
+
signPayload: `0x${seed.repeat(32)}`,
|
|
1162
|
+
})
|
|
1163
|
+
await SponsoredTransactions.finalize(db, row.id, { feeAmount: '100', finalizedAt })
|
|
1164
|
+
rows.push(row)
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
for (const [day, expected] of [
|
|
1168
|
+
[4, rows[0]],
|
|
1169
|
+
[5, rows[1]],
|
|
1170
|
+
[6, rows[2]],
|
|
1171
|
+
[7, rows[0]],
|
|
1172
|
+
] as const) {
|
|
1173
|
+
const attemptedAt = `2026-01-0${day}T00:00:00.000Z`
|
|
1174
|
+
const claimed = await SponsoredTransactions.claimUnreported(db, { attemptedAt, limit: 1 })
|
|
1175
|
+
expect(claimed.map((row) => row.id)).toStrictEqual([expected!.id])
|
|
1176
|
+
expect(claimed[0]?.meterReportAttemptedAt).toBe(attemptedAt)
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
await SponsoredTransactions.markReported(db, rows[0]!.id, '2026-01-08T00:00:00.000Z')
|
|
1180
|
+
const remaining = await SponsoredTransactions.claimUnreported(db, {
|
|
1181
|
+
attemptedAt: '2026-01-08T00:00:00.000Z',
|
|
1182
|
+
limit: 1,
|
|
1183
|
+
})
|
|
1184
|
+
expect(remaining.map((row) => row.id)).toStrictEqual([rows[1]!.id])
|
|
1185
|
+
await db.close()
|
|
1186
|
+
})
|
|
1187
|
+
})
|
|
1188
|
+
|
|
983
1189
|
describe('markReported', () => {
|
|
1190
|
+
test.each(['pending', 'failed'] as const)(
|
|
1191
|
+
'behavior: cannot discharge a %s commitment',
|
|
1192
|
+
async (status) => {
|
|
1193
|
+
const db = TestApp.database()
|
|
1194
|
+
const row = await SponsoredTransactions.upsert(db, input)
|
|
1195
|
+
if (status === 'failed')
|
|
1196
|
+
await SponsoredTransactions.fail(db, row.id, new Date().toISOString())
|
|
1197
|
+
|
|
1198
|
+
await SponsoredTransactions.markReported(db, row.id, new Date().toISOString())
|
|
1199
|
+
|
|
1200
|
+
expect((await SponsoredTransactions.get(db, row.id))?.meterReportedAt).toBeNull()
|
|
1201
|
+
await db.close()
|
|
1202
|
+
},
|
|
1203
|
+
)
|
|
1204
|
+
|
|
984
1205
|
test('behavior: marks once; re-marking never overwrites the first timestamp', async () => {
|
|
985
|
-
const db =
|
|
986
|
-
await db.migrate()
|
|
1206
|
+
const db = TestApp.database()
|
|
987
1207
|
const record = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'15'.repeat(32)}` }) // prettier-ignore
|
|
988
1208
|
await SponsoredTransactions.finalize(db, record.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
|
|
989
1209
|
await SponsoredTransactions.markReported(db, record.id, '2026-01-02T00:00:00.000Z')
|
|
@@ -993,3 +1213,58 @@ describe('markReported', () => {
|
|
|
993
1213
|
await db.close()
|
|
994
1214
|
})
|
|
995
1215
|
})
|
|
1216
|
+
|
|
1217
|
+
describe.each(['upsert', 'reserve', 'reservePromotion'] as const)('%s deletion fence', (method) => {
|
|
1218
|
+
test('behavior: waits for deletion to commit and rejects the late commitment', async () => {
|
|
1219
|
+
const schema = `t_${nanoid()}`
|
|
1220
|
+
const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
|
|
1221
|
+
const concurrent = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
|
|
1222
|
+
await db.migrate()
|
|
1223
|
+
const locked = Promise.withResolvers<void>()
|
|
1224
|
+
const release = Promise.withResolvers<void>()
|
|
1225
|
+
const deletion = db.transaction(async (tx) => {
|
|
1226
|
+
await ApiKeyOwnerTombstones.markDeleted(tx, { orgId: input.orgId })
|
|
1227
|
+
locked.resolve()
|
|
1228
|
+
await release.promise
|
|
1229
|
+
})
|
|
1230
|
+
await locked.promise
|
|
1231
|
+
const reservation = (() => {
|
|
1232
|
+
if (method === 'reserve')
|
|
1233
|
+
return SponsoredTransactions.reserve(concurrent, input, {
|
|
1234
|
+
chainIds: [input.chainId],
|
|
1235
|
+
max: 1_000n,
|
|
1236
|
+
since: '2026-01-01T00:00:00.000Z',
|
|
1237
|
+
})
|
|
1238
|
+
if (method === 'reservePromotion')
|
|
1239
|
+
return SponsoredTransactions.reservePromotion(
|
|
1240
|
+
concurrent,
|
|
1241
|
+
{
|
|
1242
|
+
...input,
|
|
1243
|
+
sponsorshipAttributionId: 'sat_1',
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
at: new Date().toISOString(),
|
|
1247
|
+
chainIds: [input.chainId],
|
|
1248
|
+
},
|
|
1249
|
+
)
|
|
1250
|
+
return SponsoredTransactions.upsert(concurrent, input)
|
|
1251
|
+
})()
|
|
1252
|
+
try {
|
|
1253
|
+
expect(
|
|
1254
|
+
await Promise.race([
|
|
1255
|
+
reservation.then(
|
|
1256
|
+
() => 'recorded',
|
|
1257
|
+
() => 'rejected',
|
|
1258
|
+
),
|
|
1259
|
+
new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)),
|
|
1260
|
+
]),
|
|
1261
|
+
).toBe('waiting')
|
|
1262
|
+
} finally {
|
|
1263
|
+
release.resolve()
|
|
1264
|
+
}
|
|
1265
|
+
await deletion
|
|
1266
|
+
await expect(reservation).rejects.toThrow(SponsoredTransactions.OrganizationDeletedError)
|
|
1267
|
+
expect(await SponsoredTransactions.listPending(db)).toEqual([])
|
|
1268
|
+
await Promise.all([db.close(), concurrent.close()])
|
|
1269
|
+
})
|
|
1270
|
+
})
|