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
|
@@ -6,6 +6,7 @@ import * as Fees from '../../internal/Fees.js'
|
|
|
6
6
|
import * as Id from '../../internal/Id.js'
|
|
7
7
|
import type * as Db from '../Db.js'
|
|
8
8
|
import type * as db_Schema from '../Schema.js'
|
|
9
|
+
import * as ApiKeyOwnerTombstones from './apiKeyOwnerTombstones.js'
|
|
9
10
|
import * as SponsorshipAttributions from './sponsorshipAttributions.js'
|
|
10
11
|
|
|
11
12
|
/** Columns of the `sponsored_transactions` table, derived from `Schema.SponsoredTransaction`. */
|
|
@@ -29,6 +30,8 @@ export const failedIntentRecoveryTtlMs = 86_400_000
|
|
|
29
30
|
* @returns The stored record.
|
|
30
31
|
*/
|
|
31
32
|
export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
|
|
33
|
+
if (!db.kysely.isTransaction) return db.transaction((tx) => upsert(tx, input))
|
|
34
|
+
await lockOrganization(db, input.orgId)
|
|
32
35
|
const record: Record = {
|
|
33
36
|
apiKeyId: input.apiKeyId,
|
|
34
37
|
sponsorshipAttributionId: input.sponsorshipAttributionId ?? null,
|
|
@@ -43,6 +46,8 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
|
|
|
43
46
|
finalizationAttemptedAt: null,
|
|
44
47
|
finalizedAt: null,
|
|
45
48
|
id: Id.generate('stx'),
|
|
49
|
+
meterEventFirstAttemptedAt: null,
|
|
50
|
+
meterReportAttemptedAt: null,
|
|
46
51
|
meterReportedAt: null,
|
|
47
52
|
orgId: input.orgId,
|
|
48
53
|
projectId: input.projectId ?? null,
|
|
@@ -50,6 +55,7 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
|
|
|
50
55
|
status: 'pending',
|
|
51
56
|
transaction: input.transaction,
|
|
52
57
|
transactionHash: input.transactionHash ?? null,
|
|
58
|
+
transactionHashReconciled: false,
|
|
53
59
|
}
|
|
54
60
|
const stored = await db.kysely
|
|
55
61
|
.insertInto('sponsored_transactions')
|
|
@@ -64,12 +70,9 @@ export async function upsert(db: Db.Db, input: upsert.Input): Promise<Record> {
|
|
|
64
70
|
eb.ref('sponsored_transactions.feeMax'),
|
|
65
71
|
eb.ref('excluded.feeMax'),
|
|
66
72
|
),
|
|
67
|
-
// A raw submission fills
|
|
68
|
-
//
|
|
69
|
-
transactionHash: eb.
|
|
70
|
-
eb.ref('excluded.transactionHash'),
|
|
71
|
-
eb.ref('sponsored_transactions.transactionHash'),
|
|
72
|
-
),
|
|
73
|
+
// A raw submission fills an intent or refreshes a submitted hash,
|
|
74
|
+
// but never replaces a finalized or reconciled hash.
|
|
75
|
+
transactionHash: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'finalized' OR ${eb.ref('sponsored_transactions.transactionHashReconciled')} THEN ${eb.ref('sponsored_transactions.transactionHash')} ELSE coalesce(${eb.ref('excluded.transactionHash')}, ${eb.ref('sponsored_transactions.transactionHash')}) END`,
|
|
73
76
|
createdAt: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN ${eb.ref('excluded.createdAt')} ELSE ${eb.ref('sponsored_transactions.createdAt')} END`,
|
|
74
77
|
finalizedAt: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN NULL ELSE ${eb.ref('sponsored_transactions.finalizedAt')} END`,
|
|
75
78
|
status: sql`CASE WHEN ${eb.ref('sponsored_transactions.status')} = 'failed' THEN 'pending' ELSE ${eb.ref('sponsored_transactions.status')} END`,
|
|
@@ -227,30 +230,51 @@ export declare namespace claimPending {
|
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
/**
|
|
230
|
-
* Lists
|
|
233
|
+
* Lists pending sponsorships, oldest first, for sign-payload reconciliation.
|
|
231
234
|
*
|
|
232
235
|
* @param db - The database.
|
|
233
236
|
* @param options - Paging options.
|
|
234
|
-
* @returns The
|
|
237
|
+
* @returns The reconciliation candidates.
|
|
235
238
|
*/
|
|
236
|
-
export function
|
|
237
|
-
|
|
239
|
+
export async function listReconciliationCandidates(
|
|
240
|
+
db: Db.Db,
|
|
241
|
+
options: listReconciliationCandidates.Options = {},
|
|
242
|
+
): Promise<Record[]> {
|
|
243
|
+
let intents = db.kysely
|
|
238
244
|
.selectFrom('sponsored_transactions')
|
|
239
245
|
.selectAll()
|
|
240
246
|
.where('status', '=', 'pending')
|
|
241
247
|
.where('transactionHash', 'is', null)
|
|
242
248
|
.orderBy('createdAt', 'asc')
|
|
243
249
|
.orderBy('id', 'asc')
|
|
244
|
-
|
|
245
|
-
|
|
250
|
+
let submitted = db.kysely
|
|
251
|
+
.selectFrom('sponsored_transactions')
|
|
252
|
+
.selectAll()
|
|
253
|
+
.where('status', '=', 'pending')
|
|
254
|
+
.where('transactionHash', 'is not', null)
|
|
255
|
+
.where('transactionHashReconciled', '=', false)
|
|
256
|
+
.orderBy('createdAt', 'asc')
|
|
257
|
+
.orderBy('id', 'asc')
|
|
258
|
+
if (options.limit !== undefined) {
|
|
259
|
+
intents = intents.limit(options.limit)
|
|
260
|
+
submitted = submitted.limit(options.limit)
|
|
261
|
+
}
|
|
262
|
+
const [records_intent, records_submitted] = await Promise.all([
|
|
263
|
+
intents.execute(),
|
|
264
|
+
submitted.execute(),
|
|
265
|
+
])
|
|
266
|
+
return [...records_intent, ...records_submitted]
|
|
246
267
|
}
|
|
247
268
|
|
|
248
|
-
export declare namespace
|
|
249
|
-
/** Options for {@link
|
|
250
|
-
type Options =
|
|
269
|
+
export declare namespace listReconciliationCandidates {
|
|
270
|
+
/** Options for {@link listReconciliationCandidates}. */
|
|
271
|
+
type Options = {
|
|
272
|
+
/** Maximum rows per transaction-hash state. */
|
|
273
|
+
limit?: number | undefined
|
|
274
|
+
}
|
|
251
275
|
}
|
|
252
276
|
|
|
253
|
-
/** Lists the oldest recoverable failed
|
|
277
|
+
/** Lists the oldest recoverable failed sponsorship timestamp for each chain. */
|
|
254
278
|
export function listRecoveryWindows(
|
|
255
279
|
db: Db.Db,
|
|
256
280
|
options: listRecoveryWindows.Options,
|
|
@@ -261,7 +285,6 @@ export function listRecoveryWindows(
|
|
|
261
285
|
.select((eb) => eb.fn.min<string>('createdAt').as('createdAt'))
|
|
262
286
|
.where('finalizedAt', '>=', options.failedSince)
|
|
263
287
|
.where('status', '=', 'failed')
|
|
264
|
-
.where('transactionHash', 'is', null)
|
|
265
288
|
.groupBy('chainId')
|
|
266
289
|
.execute()
|
|
267
290
|
}
|
|
@@ -282,7 +305,7 @@ export declare namespace listRecoveryWindows {
|
|
|
282
305
|
}
|
|
283
306
|
}
|
|
284
307
|
|
|
285
|
-
/** Lists pending and recoverable failed
|
|
308
|
+
/** Lists pending intents and recoverable failed sponsorships matching candidate sign payloads. */
|
|
286
309
|
export function listRecoverableIntents(
|
|
287
310
|
db: Db.Db,
|
|
288
311
|
options: listRecoverableIntents.Options,
|
|
@@ -294,11 +317,10 @@ export function listRecoverableIntents(
|
|
|
294
317
|
.where('signPayload', 'in', [...options.signPayloads])
|
|
295
318
|
.where((eb) =>
|
|
296
319
|
eb.or([
|
|
297
|
-
eb('status', '=', 'pending'),
|
|
320
|
+
eb.and([eb('status', '=', 'pending'), eb('transactionHash', 'is', null)]),
|
|
298
321
|
eb.and([eb('finalizedAt', '>=', options.failedSince), eb('status', '=', 'failed')]),
|
|
299
322
|
]),
|
|
300
323
|
)
|
|
301
|
-
.where('transactionHash', 'is', null)
|
|
302
324
|
.execute()
|
|
303
325
|
}
|
|
304
326
|
|
|
@@ -313,12 +335,12 @@ export declare namespace listRecoverableIntents {
|
|
|
313
335
|
}
|
|
314
336
|
|
|
315
337
|
/**
|
|
316
|
-
*
|
|
317
|
-
* A no-op once another pass
|
|
338
|
+
* Assigns a reconciled transaction hash and reopens failed sponsorships.
|
|
339
|
+
* A no-op once another pass resolved an active sponsorship.
|
|
318
340
|
*
|
|
319
341
|
* @param db - The database.
|
|
320
342
|
* @param id - The sponsored-transaction id (`stx_…`).
|
|
321
|
-
* @param transactionHash - The matched on-chain transaction hash.
|
|
343
|
+
* @param transactionHash - The matched on-chain transaction hash, which may replace an unmined hash.
|
|
322
344
|
* @param limit - The active period spend limit, when enforced.
|
|
323
345
|
*/
|
|
324
346
|
export async function assignTransactionHash(
|
|
@@ -330,12 +352,7 @@ export async function assignTransactionHash(
|
|
|
330
352
|
try {
|
|
331
353
|
await db.transaction(async (tx) => {
|
|
332
354
|
const record = await get(tx, id)
|
|
333
|
-
if (
|
|
334
|
-
!record ||
|
|
335
|
-
record.transactionHash !== null ||
|
|
336
|
-
!['failed', 'pending'].includes(record.status)
|
|
337
|
-
)
|
|
338
|
-
return
|
|
355
|
+
if (!record || !['failed', 'pending'].includes(record.status)) return
|
|
339
356
|
const failedSince = new Date(Date.now() - failedIntentRecoveryTtlMs).toISOString()
|
|
340
357
|
if (
|
|
341
358
|
record.status === 'failed' &&
|
|
@@ -360,10 +377,14 @@ export async function assignTransactionHash(
|
|
|
360
377
|
finalizedAt: null,
|
|
361
378
|
status: 'pending',
|
|
362
379
|
transactionHash,
|
|
380
|
+
transactionHashReconciled: true,
|
|
363
381
|
})
|
|
364
382
|
.where('id', '=', id)
|
|
365
383
|
.where('status', '=', record.status)
|
|
366
|
-
|
|
384
|
+
query =
|
|
385
|
+
record.transactionHash === null
|
|
386
|
+
? query.where('transactionHash', 'is', null)
|
|
387
|
+
: query.where('transactionHash', '=', record.transactionHash)
|
|
367
388
|
if (record.status === 'failed')
|
|
368
389
|
query = query.where((eb) =>
|
|
369
390
|
eb.exists(
|
|
@@ -397,7 +418,6 @@ export async function assignTransactionHash(
|
|
|
397
418
|
.set({ finalizedAt: new Date().toISOString() })
|
|
398
419
|
.where('id', '=', id)
|
|
399
420
|
.where('status', '=', 'failed')
|
|
400
|
-
.where('transactionHash', 'is', null)
|
|
401
421
|
.execute()
|
|
402
422
|
throw error
|
|
403
423
|
}
|
|
@@ -412,12 +432,19 @@ export async function assignTransactionHash(
|
|
|
412
432
|
* @param input - The finalized fee facts.
|
|
413
433
|
*/
|
|
414
434
|
export async function finalize(db: Db.Db, id: string, input: finalize.Input): Promise<void> {
|
|
415
|
-
|
|
435
|
+
let query = db.kysely
|
|
416
436
|
.updateTable('sponsored_transactions')
|
|
417
|
-
.set({
|
|
437
|
+
.set({
|
|
438
|
+
feeAmount: input.feeAmount,
|
|
439
|
+
finalizedAt: input.finalizedAt,
|
|
440
|
+
status: 'finalized',
|
|
441
|
+
...(input.transactionHash === undefined ? {} : { transactionHashReconciled: true }),
|
|
442
|
+
})
|
|
418
443
|
.where('id', '=', id)
|
|
419
444
|
.where('status', '=', 'pending')
|
|
420
|
-
|
|
445
|
+
if (input.transactionHash !== undefined)
|
|
446
|
+
query = query.where('transactionHash', '=', input.transactionHash)
|
|
447
|
+
await query.execute()
|
|
421
448
|
}
|
|
422
449
|
|
|
423
450
|
export declare namespace finalize {
|
|
@@ -427,6 +454,8 @@ export declare namespace finalize {
|
|
|
427
454
|
feeAmount: string
|
|
428
455
|
/** When the sponsorship finalized (ISO 8601). */
|
|
429
456
|
finalizedAt: string
|
|
457
|
+
/** Transaction hash whose receipt produced the fee, when fencing concurrent reconciliation. */
|
|
458
|
+
transactionHash?: string | undefined
|
|
430
459
|
}
|
|
431
460
|
}
|
|
432
461
|
|
|
@@ -437,14 +466,33 @@ export declare namespace finalize {
|
|
|
437
466
|
* @param db - The database.
|
|
438
467
|
* @param id - The sponsored-transaction id (`stx_…`).
|
|
439
468
|
* @param finalizedAt - When the sponsorship was marked failed (ISO 8601).
|
|
469
|
+
* @param options - Optional claimed-hash fence.
|
|
440
470
|
*/
|
|
441
|
-
export async function fail(
|
|
442
|
-
|
|
471
|
+
export async function fail(
|
|
472
|
+
db: Db.Db,
|
|
473
|
+
id: string,
|
|
474
|
+
finalizedAt: string,
|
|
475
|
+
options: fail.Options = {},
|
|
476
|
+
): Promise<void> {
|
|
477
|
+
let query = db.kysely
|
|
443
478
|
.updateTable('sponsored_transactions')
|
|
444
479
|
.set({ finalizedAt, status: 'failed' })
|
|
445
480
|
.where('id', '=', id)
|
|
446
481
|
.where('status', '=', 'pending')
|
|
447
|
-
|
|
482
|
+
if (options.transactionHash !== undefined)
|
|
483
|
+
query =
|
|
484
|
+
options.transactionHash === null
|
|
485
|
+
? query.where('transactionHash', 'is', null)
|
|
486
|
+
: query.where('transactionHash', '=', options.transactionHash)
|
|
487
|
+
await query.execute()
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export declare namespace fail {
|
|
491
|
+
/** Optional compare-and-set fence for a claimed sponsorship. */
|
|
492
|
+
type Options = {
|
|
493
|
+
/** Transaction hash observed when finalization claimed the row. */
|
|
494
|
+
transactionHash?: string | null | undefined
|
|
495
|
+
}
|
|
448
496
|
}
|
|
449
497
|
|
|
450
498
|
/**
|
|
@@ -465,6 +513,7 @@ export async function reserve(
|
|
|
465
513
|
limit: reserve.Limit,
|
|
466
514
|
): Promise<Record> {
|
|
467
515
|
return db.transaction(async (tx) => {
|
|
516
|
+
await lockOrganization(tx, input.orgId)
|
|
468
517
|
// `hashtext` maps the org id into the advisory-lock keyspace; the class
|
|
469
518
|
// namespaces it against other advisory-lock users. Released at tx end.
|
|
470
519
|
const scope = limit.sponsorshipAttributionId
|
|
@@ -524,6 +573,7 @@ export function reservePromotion(
|
|
|
524
573
|
options: reservePromotion.Options,
|
|
525
574
|
): Promise<reservePromotion.Result> {
|
|
526
575
|
return db.transaction(async (tx) => {
|
|
576
|
+
await lockOrganization(tx, input.orgId)
|
|
527
577
|
const scope = `${input.orgId}:${input.sponsorshipAttributionId}`
|
|
528
578
|
await sql`select pg_advisory_xact_lock(${billingLockClass}, hashtext(${scope}))`.execute(tx.kysely) // prettier-ignore
|
|
529
579
|
const existing = await tx.kysely
|
|
@@ -813,7 +863,7 @@ export declare namespace usage {
|
|
|
813
863
|
|
|
814
864
|
/**
|
|
815
865
|
* Lists finalized billable rows not yet reported to the billing meter, oldest
|
|
816
|
-
* first,
|
|
866
|
+
* first, optionally scoped to chains.
|
|
817
867
|
*
|
|
818
868
|
* @param db - The database.
|
|
819
869
|
* @param options - Reporting scope.
|
|
@@ -834,6 +884,89 @@ export function listUnreported(db: Db.Db, options: listUnreported.Options): Prom
|
|
|
834
884
|
return query.execute()
|
|
835
885
|
}
|
|
836
886
|
|
|
887
|
+
/** Claims unreported sponsorships, reserving capacity for Stripe retries and unsent rows. */
|
|
888
|
+
export function claimUnreported(db: Db.Db, options: claimUnreported.Options): Promise<Record[]> {
|
|
889
|
+
return db.transaction(async (tx) => {
|
|
890
|
+
const retries =
|
|
891
|
+
options.limit > 1
|
|
892
|
+
? await tx.kysely
|
|
893
|
+
.selectFrom('sponsored_transactions')
|
|
894
|
+
.selectAll()
|
|
895
|
+
.where('status', '=', 'finalized')
|
|
896
|
+
.where('billable', '=', true)
|
|
897
|
+
.where('meterReportedAt', 'is', null)
|
|
898
|
+
.where('meterEventFirstAttemptedAt', 'is not', null)
|
|
899
|
+
.orderBy('meterReportAttemptedAt', 'asc')
|
|
900
|
+
.orderBy('finalizedAt', 'asc')
|
|
901
|
+
.orderBy('id', 'asc')
|
|
902
|
+
.limit(Math.floor(options.limit / 2))
|
|
903
|
+
.forUpdate()
|
|
904
|
+
.skipLocked()
|
|
905
|
+
.execute()
|
|
906
|
+
: []
|
|
907
|
+
const fresh = await tx.kysely
|
|
908
|
+
.selectFrom('sponsored_transactions')
|
|
909
|
+
.selectAll()
|
|
910
|
+
.where('status', '=', 'finalized')
|
|
911
|
+
.where('billable', '=', true)
|
|
912
|
+
.where('meterReportedAt', 'is', null)
|
|
913
|
+
.$if(options.limit > 1, (query) => query.where('meterEventFirstAttemptedAt', 'is', null))
|
|
914
|
+
.orderBy(sql`meter_report_attempted_at nulls first`)
|
|
915
|
+
.orderBy('finalizedAt', 'asc')
|
|
916
|
+
.orderBy('id', 'asc')
|
|
917
|
+
.limit(options.limit - retries.length)
|
|
918
|
+
.forUpdate()
|
|
919
|
+
.skipLocked()
|
|
920
|
+
.execute()
|
|
921
|
+
const rows = [...retries, ...fresh]
|
|
922
|
+
if (rows.length === 0) return []
|
|
923
|
+
await tx.kysely
|
|
924
|
+
.updateTable('sponsored_transactions')
|
|
925
|
+
.set({ meterReportAttemptedAt: options.attemptedAt })
|
|
926
|
+
.where(
|
|
927
|
+
'id',
|
|
928
|
+
'in',
|
|
929
|
+
rows.map((row) => row.id),
|
|
930
|
+
)
|
|
931
|
+
.execute()
|
|
932
|
+
return rows.map((row) => ({ ...row, meterReportAttemptedAt: options.attemptedAt }))
|
|
933
|
+
})
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/** Persists the first possible Stripe submission before any network request. */
|
|
937
|
+
export async function beginMeterEvent(db: Db.Db, id: string, at: string): Promise<string> {
|
|
938
|
+
const row = await db.kysely
|
|
939
|
+
.updateTable('sponsored_transactions')
|
|
940
|
+
.set({ meterEventFirstAttemptedAt: sql`coalesce(meter_event_first_attempted_at, ${at})` })
|
|
941
|
+
.where('id', '=', id)
|
|
942
|
+
.where('status', '=', 'finalized')
|
|
943
|
+
.where('meterReportedAt', 'is', null)
|
|
944
|
+
.returning('meterEventFirstAttemptedAt')
|
|
945
|
+
.executeTakeFirstOrThrow()
|
|
946
|
+
return row.meterEventFirstAttemptedAt!
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/** Clears the retry clock only after Stripe explicitly rejected the event. */
|
|
950
|
+
export async function clearRejectedMeterEventAttempt(db: Db.Db, id: string): Promise<void> {
|
|
951
|
+
await db.kysely
|
|
952
|
+
.updateTable('sponsored_transactions')
|
|
953
|
+
.set({ meterEventFirstAttemptedAt: null })
|
|
954
|
+
.where('id', '=', id)
|
|
955
|
+
.where('status', '=', 'finalized')
|
|
956
|
+
.where('meterReportedAt', 'is', null)
|
|
957
|
+
.execute()
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
export declare namespace claimUnreported {
|
|
961
|
+
/** One bounded reporting pass. */
|
|
962
|
+
type Options = {
|
|
963
|
+
/** Time recorded for each claimed row (ISO 8601). */
|
|
964
|
+
attemptedAt: string
|
|
965
|
+
/** Maximum sponsorships claimed by this pass. */
|
|
966
|
+
limit: number
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
837
970
|
export declare namespace listUnreported {
|
|
838
971
|
/** Options for {@link listUnreported}. */
|
|
839
972
|
type Options = {
|
|
@@ -857,10 +990,21 @@ export async function markReported(db: Db.Db, id: string, at: string): Promise<v
|
|
|
857
990
|
.updateTable('sponsored_transactions')
|
|
858
991
|
.set({ meterReportedAt: at })
|
|
859
992
|
.where('id', '=', id)
|
|
993
|
+
.where('status', '=', 'finalized')
|
|
860
994
|
.where('meterReportedAt', 'is', null)
|
|
861
995
|
.execute()
|
|
862
996
|
}
|
|
863
997
|
|
|
998
|
+
/** Holds the deletion fence before any sponsorship row, budget, or policy locks. */
|
|
999
|
+
async function lockOrganization(db: Db.Db, orgId: string): Promise<void> {
|
|
1000
|
+
if (!(await ApiKeyOwnerTombstones.lockActive(db, { orgId }))) throw new OrganizationDeletedError()
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/** A deleted organization cannot acquire or reopen sponsorship commitments. */
|
|
1004
|
+
export class OrganizationDeletedError extends Error {
|
|
1005
|
+
override name = 'SponsoredTransactions.OrganizationDeletedError'
|
|
1006
|
+
}
|
|
1007
|
+
|
|
864
1008
|
/** Thrown by {@link reserve} when recording would exceed the org's period spend limit. */
|
|
865
1009
|
export class PeriodSpendLimitError extends Error {
|
|
866
1010
|
override name = 'SponsoredTransactions.PeriodSpendLimitError'
|
|
@@ -10,6 +10,8 @@ describe('getByEmail', () => {
|
|
|
10
10
|
try {
|
|
11
11
|
const first = await Users.upsertByAddress(db, { address: `0x${'11'.repeat(20)}` })
|
|
12
12
|
const second = await Users.upsertByAddress(db, { address: `0x${'22'.repeat(20)}` })
|
|
13
|
+
expect(first.termsSharedAt).toBeNull()
|
|
14
|
+
expect(second.termsSharedAt).toBeNull()
|
|
13
15
|
await db.kysely
|
|
14
16
|
.updateTable('users')
|
|
15
17
|
.set({ createdAt: '2026-01-01T00:00:00.000Z' })
|
|
@@ -49,6 +51,7 @@ describe('auth field migration compatibility', () => {
|
|
|
49
51
|
await expect(Users.get(db, 'usr_legacy_worker')).resolves.toMatchObject({
|
|
50
52
|
emailVerified: false,
|
|
51
53
|
name: '',
|
|
54
|
+
termsSharedAt: null,
|
|
52
55
|
})
|
|
53
56
|
} finally {
|
|
54
57
|
await db.close()
|
|
@@ -56,6 +59,54 @@ describe('auth field migration compatibility', () => {
|
|
|
56
59
|
})
|
|
57
60
|
})
|
|
58
61
|
|
|
62
|
+
describe('recordTermsShared', () => {
|
|
63
|
+
test('records an older user once after sign-in', async () => {
|
|
64
|
+
const db = TestApp.database()
|
|
65
|
+
try {
|
|
66
|
+
const now = new Date().toISOString()
|
|
67
|
+
await db.kysely
|
|
68
|
+
.insertInto('users')
|
|
69
|
+
.values([
|
|
70
|
+
{
|
|
71
|
+
address: null,
|
|
72
|
+
createdAt: now,
|
|
73
|
+
email: 'developer@example.com',
|
|
74
|
+
emailVerified: true,
|
|
75
|
+
id: 'usr_older_terms',
|
|
76
|
+
image: null,
|
|
77
|
+
name: 'Developer',
|
|
78
|
+
updatedAt: now,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
address: null,
|
|
82
|
+
createdAt: now,
|
|
83
|
+
email: 'other@example.com',
|
|
84
|
+
emailVerified: true,
|
|
85
|
+
id: 'usr_other_terms',
|
|
86
|
+
image: null,
|
|
87
|
+
name: 'Other',
|
|
88
|
+
updatedAt: now,
|
|
89
|
+
},
|
|
90
|
+
])
|
|
91
|
+
.execute()
|
|
92
|
+
|
|
93
|
+
await Users.recordTermsShared(db, 'usr_older_terms')
|
|
94
|
+
const first = await Users.get(db, 'usr_older_terms')
|
|
95
|
+
expect(first).toMatchObject({
|
|
96
|
+
termsSharedAt: expect.any(String),
|
|
97
|
+
})
|
|
98
|
+
expect(await Users.get(db, 'usr_other_terms')).toMatchObject({
|
|
99
|
+
termsSharedAt: null,
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
await Users.recordTermsShared(db, 'usr_older_terms')
|
|
103
|
+
expect((await Users.get(db, 'usr_older_terms'))?.termsSharedAt).toBe(first?.termsSharedAt)
|
|
104
|
+
} finally {
|
|
105
|
+
await db.close()
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
59
110
|
describe('email migration precondition', () => {
|
|
60
111
|
test('rejects a blank email', async () => {
|
|
61
112
|
const db = TestApp.database()
|
package/src/db/tables/users.ts
CHANGED
|
@@ -51,6 +51,7 @@ export function getByEmail(db: Db.Db, email: string): Promise<Record | undefined
|
|
|
51
51
|
.where(sql<string>`lower(btrim(email))`, '=', email.trim().toLowerCase())
|
|
52
52
|
.orderBy('createdAt', 'asc')
|
|
53
53
|
.orderBy('id', 'asc')
|
|
54
|
+
.limit(1)
|
|
54
55
|
.executeTakeFirst()
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -119,6 +120,17 @@ export async function upsertByAddress(db: Db.Db, input: upsertByAddress.Input):
|
|
|
119
120
|
.executeTakeFirstOrThrow()
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
/** Records the first successful sign-in response that includes terms links. */
|
|
124
|
+
export async function recordTermsShared(db: Db.Db, id: string): Promise<void> {
|
|
125
|
+
const now = new Date().toISOString()
|
|
126
|
+
await db.kysely
|
|
127
|
+
.updateTable('users')
|
|
128
|
+
.set({ termsSharedAt: now, updatedAt: now })
|
|
129
|
+
.where('id', '=', id)
|
|
130
|
+
.where('termsSharedAt', 'is', null)
|
|
131
|
+
.execute()
|
|
132
|
+
}
|
|
133
|
+
|
|
122
134
|
export declare namespace upsertByAddress {
|
|
123
135
|
/** Fields accepted when ensuring a user. */
|
|
124
136
|
type Input = {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Hex } from 'ox'
|
|
2
|
+
import { createClient, http } from 'viem'
|
|
3
|
+
import { tempoLocalnet } from 'viem/tempo/chains'
|
|
4
|
+
|
|
5
|
+
import * as Handler from '../../Handler.js'
|
|
6
|
+
import * as Log from '../../internal/Log.js'
|
|
7
|
+
import * as StateStore from '../../internal/Store.js'
|
|
8
|
+
import * as Multisig from './multisig.js'
|
|
9
|
+
|
|
10
|
+
describe('fromStore', () => {
|
|
11
|
+
test('requires atomic state', () => {
|
|
12
|
+
const { swap: _, ...state } = StateStore.memory()
|
|
13
|
+
expect(() => Multisig.fromStore(state)).toThrowErrorMatchingInlineSnapshot(
|
|
14
|
+
`[Error: Multisig coordination requires an atomic state store.]`,
|
|
15
|
+
)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('preserves concurrent compare-and-set', async () => {
|
|
19
|
+
const state = StateStore.memory()
|
|
20
|
+
const a = Multisig.fromStore(state)
|
|
21
|
+
const results = await Promise.all([
|
|
22
|
+
a.compareAndSet('operation', null, 'a'),
|
|
23
|
+
a.compareAndSet('operation', null, 'b'),
|
|
24
|
+
])
|
|
25
|
+
expect({ results }).toMatchInlineSnapshot(`
|
|
26
|
+
{
|
|
27
|
+
"results": [
|
|
28
|
+
true,
|
|
29
|
+
false,
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
`)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('honors absolute expiration', async () => {
|
|
36
|
+
vi.useFakeTimers()
|
|
37
|
+
try {
|
|
38
|
+
const store = Multisig.fromStore(StateStore.memory())
|
|
39
|
+
await store.compareAndSet('lease', null, 'a', { expiresAt: Date.now() + 100 })
|
|
40
|
+
await vi.advanceTimersByTimeAsync(101)
|
|
41
|
+
expect(await store.getItem('lease')).toBeNull()
|
|
42
|
+
expect(await store.compareAndSet('lease', null, 'b')).toBe(true)
|
|
43
|
+
} finally {
|
|
44
|
+
vi.useRealTimers()
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('relay', () => {
|
|
50
|
+
const client = createClient({ chain: tempoLocalnet, transport: http() })
|
|
51
|
+
|
|
52
|
+
test('serves unknown operations without forwarding them to the node', async () => {
|
|
53
|
+
const handler = Handler.relay({
|
|
54
|
+
getClient: () => client,
|
|
55
|
+
multisig: { store: StateStore.memory() },
|
|
56
|
+
})
|
|
57
|
+
const response = await handler.fetch(
|
|
58
|
+
new Request('http://relay/', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
id: 42,
|
|
62
|
+
jsonrpc: '2.0',
|
|
63
|
+
method: 'multisig_getOperation',
|
|
64
|
+
params: [Hex.random(32)],
|
|
65
|
+
}),
|
|
66
|
+
}),
|
|
67
|
+
)
|
|
68
|
+
expect(await response.json()).toMatchInlineSnapshot(`
|
|
69
|
+
{
|
|
70
|
+
"id": 42,
|
|
71
|
+
"jsonrpc": "2.0",
|
|
72
|
+
"result": null,
|
|
73
|
+
}
|
|
74
|
+
`)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('rejects invalid parameters across the five methods', async () => {
|
|
78
|
+
const handler = Handler.relay({
|
|
79
|
+
getClient: () => client,
|
|
80
|
+
multisig: { store: StateStore.memory() },
|
|
81
|
+
})
|
|
82
|
+
for (const method of [
|
|
83
|
+
'multisig_approveRawTransaction',
|
|
84
|
+
'multisig_approveRawTransactionSync',
|
|
85
|
+
'multisig_approveKeyAuthorization',
|
|
86
|
+
'multisig_getConfig',
|
|
87
|
+
'multisig_getOperation',
|
|
88
|
+
]) {
|
|
89
|
+
const response = await handler.fetch(
|
|
90
|
+
new Request('http://relay/', {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
body: JSON.stringify({ id: 1, jsonrpc: '2.0', method, params: [] }),
|
|
93
|
+
}),
|
|
94
|
+
)
|
|
95
|
+
expect(await response.json()).toMatchObject({ error: { code: -32602 } })
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('reports corrupt coordinator state through RPC server-error observability', async () => {
|
|
100
|
+
const state = StateStore.memory()
|
|
101
|
+
const hash = Hex.random(32)
|
|
102
|
+
// Operation lookup keys are part of the persisted Viem coordinator format.
|
|
103
|
+
await state.put(`multisig:v2:multisig:operation:${hash}`, 'invalid')
|
|
104
|
+
const handler = Handler.relay({ getClient: () => client, multisig: { store: state } })
|
|
105
|
+
const response = await handler.fetch(
|
|
106
|
+
new Request('http://relay/', {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
body: JSON.stringify({
|
|
109
|
+
id: 1,
|
|
110
|
+
jsonrpc: '2.0',
|
|
111
|
+
method: 'multisig_getOperation',
|
|
112
|
+
params: [hash],
|
|
113
|
+
}),
|
|
114
|
+
}),
|
|
115
|
+
)
|
|
116
|
+
const body: unknown = await response.json()
|
|
117
|
+
expect(body).toMatchObject({ error: { code: -32603 } })
|
|
118
|
+
expect(Log.rpcErrors(body)).toMatchObject({ serverErrors: 1 })
|
|
119
|
+
})
|
|
120
|
+
})
|