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
|
@@ -185,7 +185,7 @@ describe('POST /v1/earn/rewards/eligibility', () => {
|
|
|
185
185
|
vaultAddress: `0x${'Aa'.repeat(20)}`,
|
|
186
186
|
walletAddress: `0x${'Bb'.repeat(20)}`,
|
|
187
187
|
}
|
|
188
|
-
const
|
|
188
|
+
const scopedKey = {
|
|
189
189
|
id: 'key_rewards_writer',
|
|
190
190
|
orgId: 'org_test',
|
|
191
191
|
scopes: ['rewards:write'],
|
|
@@ -223,20 +223,62 @@ describe('POST /v1/earn/rewards/eligibility', () => {
|
|
|
223
223
|
expect(response.status).toBe(403)
|
|
224
224
|
})
|
|
225
225
|
|
|
226
|
-
test('
|
|
227
|
-
const response = await TestApp.create({ auth: { keys: [
|
|
226
|
+
test('accepts a rewards writer key', async () => {
|
|
227
|
+
const response = await TestApp.create({ auth: { keys: [scopedKey] } }).request(
|
|
228
228
|
'/v1/earn/rewards/eligibility',
|
|
229
229
|
{
|
|
230
230
|
body: JSON.stringify(body),
|
|
231
231
|
headers: {
|
|
232
|
-
authorization: `Bearer ${
|
|
232
|
+
authorization: `Bearer ${scopedKey.token}`,
|
|
233
233
|
'content-type': 'application/json',
|
|
234
234
|
},
|
|
235
235
|
method: 'POST',
|
|
236
236
|
},
|
|
237
237
|
)
|
|
238
238
|
|
|
239
|
-
expect(response.status).toBe(
|
|
239
|
+
expect(response.status).toBe(200)
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
test('uses the body chain for sandbox authorization', async () => {
|
|
243
|
+
const sandbox = { ...scopedKey, environment: 'sandbox' } satisfies TestApp.kvStore.Key
|
|
244
|
+
const app = TestApp.create({ auth: { keys: [sandbox] } })
|
|
245
|
+
const request = (chainId: number) =>
|
|
246
|
+
app.request('/v1/earn/rewards/eligibility', {
|
|
247
|
+
body: JSON.stringify({ ...body, chainId }),
|
|
248
|
+
headers: {
|
|
249
|
+
authorization: `Bearer ${sandbox.token}`,
|
|
250
|
+
'content-type': 'application/json',
|
|
251
|
+
},
|
|
252
|
+
method: 'POST',
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
expect([
|
|
256
|
+
(await request(Viem.chainId.testnet)).status,
|
|
257
|
+
(await request(Viem.chainId.mainnet)).status,
|
|
258
|
+
]).toEqual([200, 403])
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
test('rejects Zone chain IDs for rewards registration', async () => {
|
|
262
|
+
const zone = TestApp.zone({ chainId: 421_700_001, rpcUrl: 'https://zone.example' })
|
|
263
|
+
const response = await TestApp.create({ auth: { keys: [scopedKey] }, zones: [zone] }).request(
|
|
264
|
+
'/v1/earn/rewards/eligibility',
|
|
265
|
+
{
|
|
266
|
+
body: JSON.stringify({ ...body, chainId: zone.id }),
|
|
267
|
+
headers: {
|
|
268
|
+
authorization: `Bearer ${scopedKey.token}`,
|
|
269
|
+
'content-type': 'application/json',
|
|
270
|
+
},
|
|
271
|
+
method: 'POST',
|
|
272
|
+
},
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
expect(response.status).toBe(400)
|
|
276
|
+
expect(await response.json()).toMatchObject({
|
|
277
|
+
error: {
|
|
278
|
+
code: 'chain_id_unsupported',
|
|
279
|
+
message: `Zone chain ID ${zone.id} is not supported for rewards registration.`,
|
|
280
|
+
},
|
|
281
|
+
})
|
|
240
282
|
})
|
|
241
283
|
|
|
242
284
|
test('accepts a provisioned wildcard key', async () => {
|
|
@@ -337,7 +379,7 @@ describe('POST /v1/earn/rewards/eligibility', () => {
|
|
|
337
379
|
expect(response.status).toBe(200)
|
|
338
380
|
})
|
|
339
381
|
|
|
340
|
-
test('
|
|
382
|
+
test('rejects configured Zones for super admins', async () => {
|
|
341
383
|
const zone = TestApp.zone({
|
|
342
384
|
chainId: 421_700_001,
|
|
343
385
|
rpcUrl: 'https://zone.example',
|
|
@@ -352,7 +394,13 @@ describe('POST /v1/earn/rewards/eligibility', () => {
|
|
|
352
394
|
method: 'POST',
|
|
353
395
|
})
|
|
354
396
|
|
|
355
|
-
expect(response.status).toBe(
|
|
397
|
+
expect(response.status).toBe(400)
|
|
398
|
+
expect(await response.json()).toMatchObject({
|
|
399
|
+
error: {
|
|
400
|
+
code: 'chain_id_unsupported',
|
|
401
|
+
message: `Zone chain ID ${zone.id} is not supported for rewards registration.`,
|
|
402
|
+
},
|
|
403
|
+
})
|
|
356
404
|
})
|
|
357
405
|
|
|
358
406
|
test('surfaces database failures as operational errors', async () => {
|
|
@@ -674,6 +722,11 @@ describe('schema.getEarnVaultEarnings.Response', () => {
|
|
|
674
722
|
currentValue: '1000000',
|
|
675
723
|
id: TestEarn.earningsAddress,
|
|
676
724
|
}
|
|
725
|
+
const window = {
|
|
726
|
+
...response,
|
|
727
|
+
end: '2026-09-18T00:00:00.000Z',
|
|
728
|
+
start: '2026-09-11T00:00:00.000Z',
|
|
729
|
+
}
|
|
677
730
|
|
|
678
731
|
expect({
|
|
679
732
|
active: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
@@ -699,7 +752,7 @@ describe('schema.getEarnVaultEarnings.Response', () => {
|
|
|
699
752
|
status: 'incomplete_cost_basis',
|
|
700
753
|
}).success,
|
|
701
754
|
incompleteWindow: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
702
|
-
...
|
|
755
|
+
...window,
|
|
703
756
|
period: '30d',
|
|
704
757
|
status: 'incomplete_cost_basis',
|
|
705
758
|
}).success,
|
|
@@ -728,7 +781,7 @@ describe('schema.getEarnVaultEarnings.Response', () => {
|
|
|
728
781
|
status: 'pending_redemption',
|
|
729
782
|
}).success,
|
|
730
783
|
pendingWindow: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
731
|
-
...
|
|
784
|
+
...window,
|
|
732
785
|
period: '30d',
|
|
733
786
|
status: 'pending_redemption',
|
|
734
787
|
}).success,
|
|
@@ -740,19 +793,19 @@ describe('schema.getEarnVaultEarnings.Response', () => {
|
|
|
740
793
|
totalWithdrawn: '500000',
|
|
741
794
|
}).success,
|
|
742
795
|
window: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
743
|
-
...
|
|
796
|
+
...window,
|
|
744
797
|
period: '30d',
|
|
745
798
|
status: 'complete',
|
|
746
799
|
windowEarnings: '0',
|
|
747
800
|
}).success,
|
|
748
801
|
windowWithActiveEarnings: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
749
|
-
...
|
|
802
|
+
...window,
|
|
750
803
|
activeEarnings: '0',
|
|
751
804
|
period: '30d',
|
|
752
805
|
status: 'complete',
|
|
753
806
|
}).success,
|
|
754
807
|
windowWithoutEarnings: Earn.schema.getEarnVaultEarnings.Response.safeParse({
|
|
755
|
-
...
|
|
808
|
+
...window,
|
|
756
809
|
period: '30d',
|
|
757
810
|
status: 'complete',
|
|
758
811
|
}).success,
|
|
@@ -972,9 +1025,38 @@ describe('schema.getEarnVaultEarnings.Query', () => {
|
|
|
972
1025
|
test('defaults to lifetime and accepts active and trailing earnings', () => {
|
|
973
1026
|
expect([
|
|
974
1027
|
Earn.schema.getEarnVaultEarnings.Query.parse({}).period,
|
|
1028
|
+
Earn.schema.getEarnVaultEarnings.Query.parse({ period: '7d' }).period,
|
|
975
1029
|
Earn.schema.getEarnVaultEarnings.Query.parse({ period: '30d' }).period,
|
|
976
1030
|
Earn.schema.getEarnVaultEarnings.Query.parse({ period: 'active' }).period,
|
|
977
|
-
]).toStrictEqual(['lifetime', '30d', 'active'])
|
|
1031
|
+
]).toStrictEqual(['lifetime', '7d', '30d', 'active'])
|
|
1032
|
+
})
|
|
1033
|
+
|
|
1034
|
+
test('requires an ordered explicit interval only for custom periods', () => {
|
|
1035
|
+
const start = '2026-09-11T00:00:00.000Z'
|
|
1036
|
+
const end = '2026-09-18T00:00:00.000Z'
|
|
1037
|
+
expect(Earn.schema.getEarnVaultEarnings.Query.parse({ end, period: 'custom', start }))
|
|
1038
|
+
.toMatchInlineSnapshot(`
|
|
1039
|
+
{
|
|
1040
|
+
"end": "2026-09-18T00:00:00.000Z",
|
|
1041
|
+
"period": "custom",
|
|
1042
|
+
"start": "2026-09-11T00:00:00.000Z",
|
|
1043
|
+
}
|
|
1044
|
+
`)
|
|
1045
|
+
for (const query of [
|
|
1046
|
+
{ period: 'custom' },
|
|
1047
|
+
{ period: 'custom', start },
|
|
1048
|
+
{ end, period: 'custom' },
|
|
1049
|
+
{ end: start, period: 'custom', start },
|
|
1050
|
+
{ end: start, period: 'custom', start: end },
|
|
1051
|
+
{ end, period: 'custom', start: '2026-02-30T00:00:00Z' },
|
|
1052
|
+
{ end, period: 'custom', start: '2026-09-11T00:00:00' },
|
|
1053
|
+
{ end, start },
|
|
1054
|
+
{ end, period: '7d', start },
|
|
1055
|
+
{ end, period: 'lifetime', start },
|
|
1056
|
+
// The local dates look ordered, but their UTC instants are reversed.
|
|
1057
|
+
{ end: '2026-09-18T01:00:00+02:00', period: 'custom', start: '2026-09-18T00:00:00Z' },
|
|
1058
|
+
])
|
|
1059
|
+
expect(Earn.schema.getEarnVaultEarnings.Query.safeParse(query).success).toBe(false)
|
|
978
1060
|
})
|
|
979
1061
|
})
|
|
980
1062
|
|
|
@@ -1146,110 +1228,6 @@ describe('GET /v1/earn/vaults/verified', () => {
|
|
|
1146
1228
|
})
|
|
1147
1229
|
})
|
|
1148
1230
|
|
|
1149
|
-
test.runIf(Runtime.get().mode === 'testnet')(
|
|
1150
|
-
'folds scoped Zone routes into vault capabilities',
|
|
1151
|
-
async () => {
|
|
1152
|
-
const db = TestApp.database()
|
|
1153
|
-
await core_EarnVaults.upsert(db, TestEarn.zoneVerifiedVault)
|
|
1154
|
-
const otherZoneId = TestEarn.zone.id + 1
|
|
1155
|
-
const scopedKey = {
|
|
1156
|
-
...TestApp.key,
|
|
1157
|
-
id: 'key_earn_zones',
|
|
1158
|
-
scopes: ['data:read', `zone:${otherZoneId}:read`, `zone:${TestEarn.zone.id}:read`],
|
|
1159
|
-
token: 'secret_earn_zones',
|
|
1160
|
-
} satisfies TestApp.kvStore.Key
|
|
1161
|
-
const unrelatedKey = {
|
|
1162
|
-
...TestApp.key,
|
|
1163
|
-
id: 'key_earn_other_zone',
|
|
1164
|
-
scopes: ['data:read', `zone:${otherZoneId}:read`],
|
|
1165
|
-
token: 'secret_earn_other_zone',
|
|
1166
|
-
} satisfies TestApp.kvStore.Key
|
|
1167
|
-
const writeOnlyKey = {
|
|
1168
|
-
...TestApp.key,
|
|
1169
|
-
id: 'key_earn_write_zone',
|
|
1170
|
-
scopes: ['data:read', `zone:${TestEarn.zone.id}:write`],
|
|
1171
|
-
token: 'secret_earn_write_zone',
|
|
1172
|
-
} satisfies TestApp.kvStore.Key
|
|
1173
|
-
const wildcardKey = {
|
|
1174
|
-
...TestApp.key,
|
|
1175
|
-
id: 'key_earn_all_zones',
|
|
1176
|
-
scopes: ['*'],
|
|
1177
|
-
token: 'secret_earn_all_zones',
|
|
1178
|
-
} satisfies TestApp.kvStore.Key
|
|
1179
|
-
const app = TestApp.create({
|
|
1180
|
-
auth: { keys: [scopedKey, unrelatedKey, wildcardKey, writeOnlyKey] },
|
|
1181
|
-
cache,
|
|
1182
|
-
db,
|
|
1183
|
-
zones: [TestEarn.zone],
|
|
1184
|
-
})
|
|
1185
|
-
const base = `/v1/earn/vaults/verified?chainId=${TestEarn.chain.id}&limit=5`
|
|
1186
|
-
const included = `${base}&include=capabilities,zone,zones`
|
|
1187
|
-
const filtered = `${included}&capability=privateRouting`
|
|
1188
|
-
// Fill the query-credential cache entry before checking callers without its Zone scope.
|
|
1189
|
-
const scopedResponse = await app.request(`${filtered}&key=${scopedKey.token}`)
|
|
1190
|
-
const [
|
|
1191
|
-
defaultResponse,
|
|
1192
|
-
unrelatedResponse,
|
|
1193
|
-
publicResponse,
|
|
1194
|
-
wildcardResponse,
|
|
1195
|
-
writeOnlyResponse,
|
|
1196
|
-
] = await Promise.all([
|
|
1197
|
-
app.request(base, { headers: { 'tempo-api-key': scopedKey.token } }),
|
|
1198
|
-
app.request(included, { headers: { 'tempo-api-key': unrelatedKey.token } }),
|
|
1199
|
-
app.request(filtered),
|
|
1200
|
-
app.request(filtered, { headers: { 'tempo-api-key': wildcardKey.token } }),
|
|
1201
|
-
app.request(filtered, { headers: { 'tempo-api-key': writeOnlyKey.token } }),
|
|
1202
|
-
])
|
|
1203
|
-
|
|
1204
|
-
expect([
|
|
1205
|
-
defaultResponse.status,
|
|
1206
|
-
scopedResponse.status,
|
|
1207
|
-
unrelatedResponse.status,
|
|
1208
|
-
publicResponse.status,
|
|
1209
|
-
wildcardResponse.status,
|
|
1210
|
-
writeOnlyResponse.status,
|
|
1211
|
-
]).toStrictEqual([200, 200, 200, 200, 200, 200])
|
|
1212
|
-
const [defaultBody, scopedBody, unrelatedBody, publicBody, wildcardBody, writeOnlyBody] =
|
|
1213
|
-
await Promise.all([
|
|
1214
|
-
TestApp.json(defaultResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1215
|
-
TestApp.json(scopedResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1216
|
-
TestApp.json(unrelatedResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1217
|
-
TestApp.json(publicResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1218
|
-
TestApp.json(wildcardResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1219
|
-
TestApp.json(writeOnlyResponse, Earn.schema.getVerifiedEarnVaults.Response),
|
|
1220
|
-
])
|
|
1221
|
-
expect(defaultBody.data[0]).not.toHaveProperty('zone')
|
|
1222
|
-
expect(defaultBody.data[0]).not.toHaveProperty('zones')
|
|
1223
|
-
expect(unrelatedBody.data[0]).toMatchObject({
|
|
1224
|
-
capabilities: { privateRouting: true, routerSwaps: true },
|
|
1225
|
-
zone: null,
|
|
1226
|
-
zones: [],
|
|
1227
|
-
})
|
|
1228
|
-
expect(publicBody.data[0]).toMatchObject({
|
|
1229
|
-
capabilities: { privateRouting: true, routerSwaps: true },
|
|
1230
|
-
zone: null,
|
|
1231
|
-
zones: [],
|
|
1232
|
-
})
|
|
1233
|
-
expect(writeOnlyBody.data[0]).toMatchObject({ zone: null, zones: [] })
|
|
1234
|
-
const vault = scopedBody.data[0]
|
|
1235
|
-
expect(vault?.capabilities).toMatchObject({ privateRouting: true, routerSwaps: true })
|
|
1236
|
-
expect(vault?.zones).toHaveLength(1)
|
|
1237
|
-
expect(vault?.zones?.[0]).toMatchObject(TestEarn.zoneRoute)
|
|
1238
|
-
expect(vault?.zone).toStrictEqual(
|
|
1239
|
-
vault?.zones?.[0]
|
|
1240
|
-
? {
|
|
1241
|
-
chainId: vault.zones[0].chainId,
|
|
1242
|
-
inputTokens: vault.zones[0].inputTokens,
|
|
1243
|
-
name: vault.zones[0].name,
|
|
1244
|
-
outputTokens: vault.zones[0].outputTokens,
|
|
1245
|
-
}
|
|
1246
|
-
: null,
|
|
1247
|
-
)
|
|
1248
|
-
expect(wildcardBody.data[0]).toStrictEqual(vault)
|
|
1249
|
-
},
|
|
1250
|
-
90_000,
|
|
1251
|
-
)
|
|
1252
|
-
|
|
1253
1231
|
test.runIf(Runtime.get().mode === 'testnet')(
|
|
1254
1232
|
'returns null for an inaccessible legacy Zone route',
|
|
1255
1233
|
async () => {
|
|
@@ -2305,6 +2283,13 @@ describe('GET /v1/earn/vaults/:vaultId/share-prices', () => {
|
|
|
2305
2283
|
})
|
|
2306
2284
|
|
|
2307
2285
|
describe('GET /v1/earn/vaults/:vaultId/positions/:address', () => {
|
|
2286
|
+
const zoneKey = {
|
|
2287
|
+
...TestApp.key,
|
|
2288
|
+
id: 'key_earn_zone_vault_position',
|
|
2289
|
+
scopes: ['data:read', `zone:${TestEarn.zone.id}:read`],
|
|
2290
|
+
token: 'secret_earn_zone_vault_position',
|
|
2291
|
+
} satisfies TestApp.kvStore.Key
|
|
2292
|
+
|
|
2308
2293
|
test('accepts and validates the wallet APY include', () => {
|
|
2309
2294
|
expect(Earn.schema.getEarnVaultPosition.Query.safeParse({ include: ['apy'] }).success).toBe(
|
|
2310
2295
|
true,
|
|
@@ -2354,6 +2339,26 @@ describe('GET /v1/earn/vaults/:vaultId/positions/:address', () => {
|
|
|
2354
2339
|
})
|
|
2355
2340
|
})
|
|
2356
2341
|
|
|
2342
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
2343
|
+
'returns not found for an incompatible public parent vault selected through a Zone',
|
|
2344
|
+
async () => {
|
|
2345
|
+
const response = await TestApp.create({
|
|
2346
|
+
auth: { keys: [zoneKey] },
|
|
2347
|
+
cache,
|
|
2348
|
+
zones: [TestEarn.zone],
|
|
2349
|
+
}).request(
|
|
2350
|
+
`/v1/earn/vaults/${TestEarn.assetTokenAddress}/positions/${TestEarn.positionAddress}?chainId=${TestEarn.zone.id}`,
|
|
2351
|
+
{ headers: { 'tempo-api-key': zoneKey.token } },
|
|
2352
|
+
)
|
|
2353
|
+
|
|
2354
|
+
expect(response.status).toBe(404)
|
|
2355
|
+
expect(await TestApp.json(response, Schema.ErrorResponse)).toMatchObject({
|
|
2356
|
+
error: { code: 'earn_vault_not_found' },
|
|
2357
|
+
})
|
|
2358
|
+
},
|
|
2359
|
+
60_000,
|
|
2360
|
+
)
|
|
2361
|
+
|
|
2357
2362
|
test('rejects invalid as-of timestamps', async () => {
|
|
2358
2363
|
const app = TestApp.create({ auth: false, cache })
|
|
2359
2364
|
const [malformed, unix] = await Promise.all([
|
|
@@ -2631,6 +2636,26 @@ describe('GET /v1/earn/vaults/:vaultId/positions/:address', () => {
|
|
|
2631
2636
|
now: startsAt - 1,
|
|
2632
2637
|
vaultAddress: TestEarn.vaultAddress,
|
|
2633
2638
|
})
|
|
2639
|
+
await RewardEligibilityAssociations.upsert(db, {
|
|
2640
|
+
chainId: TestEarn.chain.id,
|
|
2641
|
+
vaultAddress: TestEarn.vaultAddress,
|
|
2642
|
+
walletAddress: TestEarn.positionAddress,
|
|
2643
|
+
})
|
|
2644
|
+
const freshResponse = await TestApp.create({ auth: false, cache, db }).request(
|
|
2645
|
+
`/v1/earn/vaults/${TestEarn.vaultAddress}/positions/${TestEarn.positionAddress}?chainId=${TestEarn.chain.id}&include=apy`,
|
|
2646
|
+
)
|
|
2647
|
+
expect(freshResponse.status).toBe(200)
|
|
2648
|
+
const fresh = await TestApp.json(freshResponse, Earn.schema.getEarnVaultPosition.Response)
|
|
2649
|
+
expect(fresh.apy?.breakdown).toMatchObject([
|
|
2650
|
+
{
|
|
2651
|
+
assetAmount: { baseUnits: '0', decimals: 6, formatted: '0' },
|
|
2652
|
+
net: '0.0700',
|
|
2653
|
+
type: 'boost',
|
|
2654
|
+
},
|
|
2655
|
+
{ assetAmount: { baseUnits: fresh.value }, type: 'base' },
|
|
2656
|
+
])
|
|
2657
|
+
expect(Number(fresh.apy?.net)).toBe(Number(fresh.apy?.breakdown[1]?.net))
|
|
2658
|
+
|
|
2634
2659
|
await RewardAccounts.replace(db, {
|
|
2635
2660
|
accounts: [
|
|
2636
2661
|
{
|
|
@@ -2791,7 +2816,95 @@ describe('GET /v1/earn/vaults/:vaultId/positions/:address', () => {
|
|
|
2791
2816
|
|
|
2792
2817
|
describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
2793
2818
|
test.runIf(Runtime.get().mode === 'testnet')(
|
|
2794
|
-
'
|
|
2819
|
+
'recognizes card withdrawals with only incoming rewards configured and no campaign',
|
|
2820
|
+
async () => {
|
|
2821
|
+
const account = '0x504a128461f2ee15b52a9d33812769e8cc31bc0d'
|
|
2822
|
+
const vaultAddress = '0xd730394f3bb85a4828e35fc5e361dcc9f894fa4f'
|
|
2823
|
+
const chainId = Viem.chainId.mainnet
|
|
2824
|
+
const db = TestApp.database()
|
|
2825
|
+
const tidx = {
|
|
2826
|
+
auth: process.env.TIDX_AUTH,
|
|
2827
|
+
baseUrl: Viem.resolveUrl(process.env.TIDX_URL, chainId) ?? Tidx.url[chainId],
|
|
2828
|
+
}
|
|
2829
|
+
const errors: Error[] = []
|
|
2830
|
+
const app = TestApp.create({
|
|
2831
|
+
auth: false,
|
|
2832
|
+
cache,
|
|
2833
|
+
db,
|
|
2834
|
+
logger: (_, error) => {
|
|
2835
|
+
if (error) errors.push(error)
|
|
2836
|
+
},
|
|
2837
|
+
tidx,
|
|
2838
|
+
})
|
|
2839
|
+
const input = {
|
|
2840
|
+
chainId,
|
|
2841
|
+
description: null,
|
|
2842
|
+
label: 'Tempo Cash',
|
|
2843
|
+
privateInputTokens: [],
|
|
2844
|
+
privateOutputTokens: [],
|
|
2845
|
+
vaultAddress,
|
|
2846
|
+
zones: [],
|
|
2847
|
+
} as const
|
|
2848
|
+
const read = async (period: '30d' | 'lifetime' | 'active') => {
|
|
2849
|
+
const response = await app.request(
|
|
2850
|
+
`/v1/earn/vaults/${vaultAddress}/earnings/${account}?chainId=${chainId}&period=${period}`,
|
|
2851
|
+
{ headers: { 'cache-control': 'no-store' } },
|
|
2852
|
+
)
|
|
2853
|
+
expect(response.status, errors.map((error) => error.message).join('\n')).toBe(200)
|
|
2854
|
+
return TestApp.json(response, Earn.schema.getEarnVaultEarnings.Response)
|
|
2855
|
+
}
|
|
2856
|
+
await core_EarnVaults.upsert(db, {
|
|
2857
|
+
...input,
|
|
2858
|
+
earnings: { rewardDistributors: [] },
|
|
2859
|
+
})
|
|
2860
|
+
// Lifetime history retains the known rewards after they leave the trailing window.
|
|
2861
|
+
expect((await read('lifetime')).status).toBe('incomplete_cost_basis')
|
|
2862
|
+
await core_EarnVaults.upsert(db, {
|
|
2863
|
+
...input,
|
|
2864
|
+
earnings: {
|
|
2865
|
+
rewardDistributors: ['0xa65c6ed737b52543123817977d8d2c0e554bfc2d'],
|
|
2866
|
+
},
|
|
2867
|
+
})
|
|
2868
|
+
expect((await read('30d')).status).toBe('complete')
|
|
2869
|
+
expect((await read('active')).status).toBe('complete')
|
|
2870
|
+
// Sample direct exits before lifetime earnings so later activity cannot increase only the baseline.
|
|
2871
|
+
const direct = await Tidx.getClient({ chainId, tidx }).fetch({
|
|
2872
|
+
engine: 'clickhouse',
|
|
2873
|
+
query: `SELECT toString(sum(toUInt256(assets))) AS assets FROM (
|
|
2874
|
+
SELECT assets FROM Redeemed WHERE address = '${vaultAddress}' AND caller = '${account}'
|
|
2875
|
+
UNION ALL SELECT assets FROM WithdrewExact WHERE address = '${vaultAddress}' AND caller = '${account}'
|
|
2876
|
+
)`,
|
|
2877
|
+
signatures: [
|
|
2878
|
+
'event Redeemed(address indexed caller,address indexed receiver,uint256 earnShares,uint256 assets)',
|
|
2879
|
+
'event WithdrewExact(address indexed caller,address indexed receiver,uint256 assets,uint256 earnSharesBurned)',
|
|
2880
|
+
],
|
|
2881
|
+
})
|
|
2882
|
+
const lifetime = await read('lifetime')
|
|
2883
|
+
if (lifetime.status !== 'complete' || lifetime.period !== 'lifetime')
|
|
2884
|
+
throw new Error('Expected complete lifetime earnings.')
|
|
2885
|
+
// This live wallet can spend again; EarnWithdrawals.read's fixed-block regression proves the captured $1 is counted exactly once.
|
|
2886
|
+
expect(
|
|
2887
|
+
BigInt(lifetime.totalWithdrawn) - BigInt(String(direct.rows[0]?.['assets'])),
|
|
2888
|
+
).toBeGreaterThanOrEqual(1_000_000n)
|
|
2889
|
+
const positions = await app.request(
|
|
2890
|
+
`/v1/earn/addresses/${account}/positions?chainId=${chainId}&include=earnings&verified=true`,
|
|
2891
|
+
{ headers: { 'cache-control': 'no-store' } },
|
|
2892
|
+
)
|
|
2893
|
+
expect(positions.status).toBe(200)
|
|
2894
|
+
const body = await TestApp.json(positions, Earn.schema.getEarnAddressPositions.Response)
|
|
2895
|
+
expect(
|
|
2896
|
+
body.data.find((position) => position.vaultAddress === vaultAddress)?.lifetimeCashFlows,
|
|
2897
|
+
).toEqual({
|
|
2898
|
+
status: 'complete',
|
|
2899
|
+
totalDeposited: lifetime.totalDeposited,
|
|
2900
|
+
totalWithdrawn: lifetime.totalWithdrawn,
|
|
2901
|
+
})
|
|
2902
|
+
},
|
|
2903
|
+
180_000,
|
|
2904
|
+
)
|
|
2905
|
+
|
|
2906
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
2907
|
+
'combines additional distributors with campaign history without erasing past rewards',
|
|
2795
2908
|
async () => {
|
|
2796
2909
|
const account = '0xa3b9eb50b9d1a3f584fbe1122a7bc82084eaae2f'
|
|
2797
2910
|
const chainId = Viem.chainId.mainnet
|
|
@@ -2815,6 +2928,7 @@ describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
|
2815
2928
|
const read = async (period: 'lifetime' | '30d' | 'active') => {
|
|
2816
2929
|
const response = await app.request(
|
|
2817
2930
|
`/v1/earn/vaults/${vaultAddress}/earnings/${account}?chainId=${chainId}&period=${period}`,
|
|
2931
|
+
{ headers: { 'cache-control': 'no-store' } },
|
|
2818
2932
|
)
|
|
2819
2933
|
expect(response.status, errors.map((error) => error.message).join('\n')).toBe(200)
|
|
2820
2934
|
return TestApp.json(response, Earn.schema.getEarnVaultEarnings.Response)
|
|
@@ -2822,7 +2936,7 @@ describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
|
2822
2936
|
|
|
2823
2937
|
// This account's indexed share receipts include both vault mints and distributor payouts.
|
|
2824
2938
|
expect((await read('lifetime')).status).toBe('incomplete_cost_basis')
|
|
2825
|
-
await core_EarnVaults.upsert(db, {
|
|
2939
|
+
const vault = await core_EarnVaults.upsert(db, {
|
|
2826
2940
|
chainId,
|
|
2827
2941
|
description: null,
|
|
2828
2942
|
label: 'Tempo Cash',
|
|
@@ -2859,8 +2973,19 @@ describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
|
2859
2973
|
distributorAddress: previousDistributorAddress,
|
|
2860
2974
|
vaultAddress,
|
|
2861
2975
|
})
|
|
2976
|
+
// Neither the old campaign distributor nor the extra alone covers this account's receipts.
|
|
2977
|
+
expect((await read('lifetime')).status).toBe('incomplete_cost_basis')
|
|
2978
|
+
await core_EarnVaults.upsert(db, {
|
|
2979
|
+
...vault,
|
|
2980
|
+
earnings: { rewardDistributors: [distributorAddress] },
|
|
2981
|
+
})
|
|
2982
|
+
for (const period of ['lifetime', '30d', 'active'] as const)
|
|
2983
|
+
expect((await read(period)).status).toBe('complete')
|
|
2984
|
+
|
|
2985
|
+
// Recording a future campaign binding keeps its history even after clearing the extra list.
|
|
2862
2986
|
await RewardCampaigns.setBindings(db, { chainId, distributorAddress, vaultAddress })
|
|
2863
2987
|
await RewardCampaigns.setPaused(db, { chainId, paused: true, vaultAddress })
|
|
2988
|
+
await core_EarnVaults.upsert(db, { ...vault, earnings: { rewardDistributors: [] } })
|
|
2864
2989
|
|
|
2865
2990
|
// Pausing new rewards must not erase the cost-basis treatment of already paid rewards.
|
|
2866
2991
|
const earnings = await Promise.all((['lifetime', '30d', 'active'] as const).map(read))
|
|
@@ -2888,8 +3013,10 @@ describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
|
2888
3013
|
BigInt(lifetime.totalWithdrawn) -
|
|
2889
3014
|
BigInt(lifetime.totalDeposited),
|
|
2890
3015
|
)
|
|
3016
|
+
await core_EarnVaults.upsert(db, { ...vault, earnings: null })
|
|
3017
|
+
expect((await read('lifetime')).status).toBe('complete')
|
|
2891
3018
|
},
|
|
2892
|
-
|
|
3019
|
+
180_000,
|
|
2893
3020
|
)
|
|
2894
3021
|
|
|
2895
3022
|
test('returns chain selection errors', async () => {
|
|
@@ -2991,6 +3118,148 @@ describe('GET /v1/earn/vaults/:vaultId/earnings/:address', () => {
|
|
|
2991
3118
|
60_000,
|
|
2992
3119
|
)
|
|
2993
3120
|
|
|
3121
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
3122
|
+
'matches weekly and explicit windows and preserves historical cash-flow boundaries',
|
|
3123
|
+
async () => {
|
|
3124
|
+
const account = '0x504a128461f2ee15b52a9d33812769e8cc31bc0d'
|
|
3125
|
+
const vaultAddress = '0xd730394f3bb85a4828e35fc5e361dcc9f894fa4f'
|
|
3126
|
+
const chainId = Viem.chainId.mainnet
|
|
3127
|
+
const db = TestApp.database()
|
|
3128
|
+
await core_EarnVaults.upsert(db, {
|
|
3129
|
+
chainId,
|
|
3130
|
+
description: null,
|
|
3131
|
+
earnings: { rewardDistributors: ['0xa65c6ed737b52543123817977d8d2c0e554bfc2d'] },
|
|
3132
|
+
label: 'Tempo Cash',
|
|
3133
|
+
privateInputTokens: [],
|
|
3134
|
+
privateOutputTokens: [],
|
|
3135
|
+
vaultAddress,
|
|
3136
|
+
zones: [],
|
|
3137
|
+
})
|
|
3138
|
+
const errors: Error[] = []
|
|
3139
|
+
const app = TestApp.create({
|
|
3140
|
+
auth: false,
|
|
3141
|
+
cache,
|
|
3142
|
+
db,
|
|
3143
|
+
logger: (_, error) => {
|
|
3144
|
+
if (error) errors.push(error)
|
|
3145
|
+
},
|
|
3146
|
+
tidx: {
|
|
3147
|
+
auth: process.env.TIDX_AUTH,
|
|
3148
|
+
baseUrl: Viem.resolveUrl(process.env.TIDX_URL, chainId) ?? Tidx.url[chainId],
|
|
3149
|
+
},
|
|
3150
|
+
})
|
|
3151
|
+
const path = `/v1/earn/vaults/${vaultAddress}/earnings/${account}`
|
|
3152
|
+
const read = async (query: Record<string, string>) => {
|
|
3153
|
+
const response = await app.request(
|
|
3154
|
+
`${path}?${new URLSearchParams({ chainId: String(chainId), ...query })}`,
|
|
3155
|
+
{ headers: { 'cache-control': 'no-store' } },
|
|
3156
|
+
)
|
|
3157
|
+
expect(response.status, errors.map((error) => error.stack).join('\n')).toBe(200)
|
|
3158
|
+
const body = await TestApp.json(response, Earn.schema.getEarnVaultEarnings.Response)
|
|
3159
|
+
if (body.status !== 'complete' || !('windowEarnings' in body))
|
|
3160
|
+
throw new Error('Expected complete window earnings.')
|
|
3161
|
+
return body
|
|
3162
|
+
}
|
|
3163
|
+
const week = await read({ period: '7d' })
|
|
3164
|
+
expect(Date.parse(week.end) - Date.parse(week.start)).toBe(7 * 24 * 60 * 60 * 1000)
|
|
3165
|
+
const explicit = await read({ end: week.end, period: 'custom', start: week.start })
|
|
3166
|
+
expect(explicit).toEqual({ ...week, period: 'custom' })
|
|
3167
|
+
|
|
3168
|
+
// This fixed historical interval includes deposits, rewards and card exits.
|
|
3169
|
+
const start = '2026-09-11T00:00:00.000Z'
|
|
3170
|
+
const middle = '2026-09-15T00:00:00.000Z'
|
|
3171
|
+
const end = '2026-09-18T00:00:00.000Z'
|
|
3172
|
+
const full = await read({ end, period: 'custom', start })
|
|
3173
|
+
const left = await read({ end: middle, period: 'custom', start })
|
|
3174
|
+
const right = await read({ end, period: 'custom', start: middle })
|
|
3175
|
+
expect(BigInt(full.windowEarnings)).toBeGreaterThan(0n)
|
|
3176
|
+
expect(BigInt(left.windowEarnings) + BigInt(right.windowEarnings)).toBe(
|
|
3177
|
+
BigInt(full.windowEarnings),
|
|
3178
|
+
)
|
|
3179
|
+
expect(left.currentValue).not.toBe(full.currentValue)
|
|
3180
|
+
expect(right.currentValue).toBe(full.currentValue)
|
|
3181
|
+
const historical = await app.request(
|
|
3182
|
+
`/v1/earn/vaults/${vaultAddress}/positions/${account}?${new URLSearchParams({
|
|
3183
|
+
asOf: end,
|
|
3184
|
+
chainId: String(chainId),
|
|
3185
|
+
})}`,
|
|
3186
|
+
)
|
|
3187
|
+
expect(historical.status).toBe(200)
|
|
3188
|
+
expect(
|
|
3189
|
+
(await TestApp.json(historical, Earn.schema.getEarnVaultPosition.Response)).value,
|
|
3190
|
+
).toBe(full.currentValue)
|
|
3191
|
+
const offset = await read({
|
|
3192
|
+
end: '2026-09-18T02:00:00+02:00',
|
|
3193
|
+
period: 'custom',
|
|
3194
|
+
start: '2026-09-10T19:00:00-05:00',
|
|
3195
|
+
})
|
|
3196
|
+
expect(offset).toEqual(full)
|
|
3197
|
+
},
|
|
3198
|
+
180_000,
|
|
3199
|
+
)
|
|
3200
|
+
|
|
3201
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
3202
|
+
'rejects earnings windows beyond indexed coverage',
|
|
3203
|
+
async () => {
|
|
3204
|
+
const end = new Date(Date.now() + Ttl.days(365)).toISOString()
|
|
3205
|
+
const response = await TestApp.create({ auth: false, cache }).request(
|
|
3206
|
+
`/v1/earn/vaults/${TestEarn.vaultAddress}/earnings/${TestEarn.earningsAddress}?${new URLSearchParams(
|
|
3207
|
+
{
|
|
3208
|
+
chainId: String(TestEarn.chain.id),
|
|
3209
|
+
end,
|
|
3210
|
+
period: 'custom',
|
|
3211
|
+
start: '2026-09-11T00:00:00.000Z',
|
|
3212
|
+
},
|
|
3213
|
+
)}`,
|
|
3214
|
+
)
|
|
3215
|
+
expect(response.status).toBe(400)
|
|
3216
|
+
expect(await TestApp.json(response, Schema.ErrorResponse)).toMatchObject({
|
|
3217
|
+
error: { code: 'query_invalid', message: `Indexed history does not yet cover ${end}.` },
|
|
3218
|
+
})
|
|
3219
|
+
expect(response.headers.get('cache-control')).toBe('no-store')
|
|
3220
|
+
},
|
|
3221
|
+
60_000,
|
|
3222
|
+
)
|
|
3223
|
+
|
|
3224
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
3225
|
+
'reports historical earnings dependency failures through request alerts',
|
|
3226
|
+
async () => {
|
|
3227
|
+
const entries: Log.Entry[] = []
|
|
3228
|
+
const errors: Error[] = []
|
|
3229
|
+
const app = TestApp.create({
|
|
3230
|
+
auth: false,
|
|
3231
|
+
cache,
|
|
3232
|
+
logger: (entry, error) => {
|
|
3233
|
+
entries.push(entry)
|
|
3234
|
+
if (error) errors.push(error)
|
|
3235
|
+
},
|
|
3236
|
+
tidx: { baseUrl: 'http://127.0.0.1:1' },
|
|
3237
|
+
})
|
|
3238
|
+
const response = await app.request(
|
|
3239
|
+
`/v1/earn/vaults/${TestEarn.vaultAddress}/earnings/${TestEarn.earningsAddress}?${new URLSearchParams(
|
|
3240
|
+
{
|
|
3241
|
+
chainId: String(TestEarn.chain.id),
|
|
3242
|
+
end: '2026-09-18T00:00:00.000Z',
|
|
3243
|
+
period: 'custom',
|
|
3244
|
+
start: '2026-09-11T00:00:00.000Z',
|
|
3245
|
+
},
|
|
3246
|
+
)}`,
|
|
3247
|
+
)
|
|
3248
|
+
expect(response.status).toBe(502)
|
|
3249
|
+
expect(await TestApp.json(response, Schema.ErrorResponse)).toMatchObject({
|
|
3250
|
+
error: { code: 'upstream_error' },
|
|
3251
|
+
})
|
|
3252
|
+
expect(errors).toHaveLength(1)
|
|
3253
|
+
expect(entries[0]).toMatchObject({
|
|
3254
|
+
errorCode: 'upstream_error',
|
|
3255
|
+
route: '/v1/earn/vaults/:vaultId/earnings/:address',
|
|
3256
|
+
status: 502,
|
|
3257
|
+
})
|
|
3258
|
+
expect(response.headers.get('cache-control')).toBe('no-store')
|
|
3259
|
+
},
|
|
3260
|
+
60_000,
|
|
3261
|
+
)
|
|
3262
|
+
|
|
2994
3263
|
test.runIf(Runtime.get().mode === 'testnet')(
|
|
2995
3264
|
'omits lifetime earnings when venue shares make the cost basis incomplete',
|
|
2996
3265
|
async () => {
|
|
@@ -3367,7 +3636,9 @@ describe('OpenAPI', () => {
|
|
|
3367
3636
|
expect(asOf?.description).toContain('latest indexed block at or before')
|
|
3368
3637
|
expect(asOf?.schema?.examples).toStrictEqual(['2026-07-21T09:00:00.000Z'])
|
|
3369
3638
|
expect(response).toContain('Indexed block used for a historical Earn position observation')
|
|
3370
|
-
expect(response).toContain('
|
|
3639
|
+
expect(response).toContain('Public vault assets held by this account at the observation block')
|
|
3640
|
+
expect(response).toContain('Private Zone assets held by this account at the observation block')
|
|
3641
|
+
expect(response).toContain('TIP-20 private asset used by the validated Zone route')
|
|
3371
3642
|
expect(response).toContain('Earn shares held by this account at the observation block')
|
|
3372
3643
|
expect(response).toContain('Asset value of this account’s earn shares at the observation block')
|
|
3373
3644
|
expect(response).toContain('TIP-20 asset denominating `value`')
|
|
@@ -3442,17 +3713,24 @@ describe('OpenAPI', () => {
|
|
|
3442
3713
|
const period = operation?.parameters?.find((parameter) => parameter.name === 'period')
|
|
3443
3714
|
const response = JSON.stringify(resolveSchema(spec, successSchema(operation)))
|
|
3444
3715
|
|
|
3445
|
-
expect(operation?.description).toContain('
|
|
3446
|
-
expect(period?.description).toContain('trailing 30 days')
|
|
3447
|
-
expect(period?.schema?.enum).toStrictEqual(['30d', 'active', 'lifetime'])
|
|
3716
|
+
expect(operation?.description).toContain('rolling or custom time window')
|
|
3717
|
+
expect(period?.description).toContain('trailing 7 or 30 days')
|
|
3718
|
+
expect(period?.schema?.enum).toStrictEqual(['7d', '30d', 'active', 'custom', 'lifetime'])
|
|
3448
3719
|
expect(period?.schema?.examples).toStrictEqual(['lifetime'])
|
|
3720
|
+
for (const name of ['start', 'end']) {
|
|
3721
|
+
const parameter = operation?.parameters?.find((parameter) => parameter.name === name)
|
|
3722
|
+
expect(parameter?.description).toContain('Required with period=custom')
|
|
3723
|
+
expect(parameter?.schema?.examples).toHaveLength(1)
|
|
3724
|
+
}
|
|
3449
3725
|
expect(errors).toContain('"earn_vault_not_found"')
|
|
3450
3726
|
expect(response).toContain('Stable resource ID for these vault earnings')
|
|
3451
|
-
expect(response).toContain(
|
|
3727
|
+
expect(response).toContain(
|
|
3728
|
+
'Current share value plus withdrawals, including outgoing shares valued when transferred',
|
|
3729
|
+
)
|
|
3452
3730
|
expect(response).toContain('Assets deposited with this account as receiver')
|
|
3453
|
-
expect(response).toContain('
|
|
3731
|
+
expect(response).toContain('regardless of recipient or spender')
|
|
3454
3732
|
expect(response).toContain('weighted-average asset cost basis')
|
|
3455
|
-
expect(response).toContain('Ending share value plus
|
|
3733
|
+
expect(response).toContain('Ending share value plus withdrawals')
|
|
3456
3734
|
expect(response).toContain('cannot reconstruct the asset cost basis for the requested period')
|
|
3457
3735
|
expect(response).toContain('"active"')
|
|
3458
3736
|
expect(response).toContain('"30d"')
|