tapimo 0.15.0 → 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 +896 -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 +33 -33
- 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 +454 -1
- 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 +10 -4
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +24 -4
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- 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 +99 -103
- 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 +5 -5
- 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/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 +1 -19
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +93 -56
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +10 -10
- package/dist/apps/data/routes/rpc.d.ts +30 -30
- package/dist/apps/data/routes/rpc.js +45 -11
- package/dist/apps/data/routes/rpc.js.map +1 -1
- 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 +12 -12
- package/dist/apps/data/routes/valuation.d.ts +30 -30
- package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
- package/dist/apps/data/routes/webhooks.d.ts +1 -1
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +18 -11
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +3 -3
- package/dist/apps/management/App.d.ts +3043 -2198
- 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 +16 -4
- 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 +24 -24
- package/dist/apps/management/routes/invite-links.d.ts +66 -66
- package/dist/apps/management/routes/members.d.ts +16 -16
- package/dist/apps/management/routes/orgs.d.ts +20 -20
- 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 +76 -76
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/verified-token-requests.d.ts +42 -42
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +7 -9
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +119 -119
- package/dist/apps/mcp.d.ts.map +1 -1
- package/dist/apps/mcp.js +16 -3
- package/dist/apps/mcp.js.map +1 -1
- 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/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 +90 -0
- 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 +187 -135
- 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 +418 -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/db/tables/verifiedTokenRequests.d.ts +21 -4
- package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -1
- package/dist/db/tables/verifiedTokenRequests.js +65 -44
- package/dist/db/tables/verifiedTokenRequests.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 +73 -6
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +212 -85
- 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 +4 -1
- package/dist/internal/routes/providers/relay.d.ts.map +1 -1
- package/dist/internal/routes/providers/relay.js +353 -42
- 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/apps/verified-tokens.test.ts +32 -0
- package/src/admin/apps/verified-tokens.ts +30 -4
- 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/lib/verified-tokens.ts +24 -9
- package/src/admin/ui/src/routeTree.gen.ts +21 -0
- package/src/admin/ui/src/routes/__root.tsx +1 -1
- 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 +35 -4
- 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 +65 -20
- package/src/admin/ui.generated.ts +99 -104
- 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/App.test.ts +26 -0
- 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 +153 -2
- package/src/apps/data/routes/fee-amm.ts +132 -62
- package/src/apps/data/routes/receipts.test.ts +21 -18
- package/src/apps/data/routes/rpc.test.ts +34 -2
- package/src/apps/data/routes/rpc.ts +47 -10
- 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.scan.test.ts +29 -0
- package/src/apps/data/routes/webhooks.test.ts +18 -3
- package/src/apps/data/routes/webhooks.ts +27 -13
- 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/management/routes/verified-token-requests.test.ts +16 -2
- package/src/apps/management/routes/verified-token-requests.ts +7 -10
- package/src/apps/mcp.test.ts +108 -25
- package/src/apps/mcp.ts +15 -3
- 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 +507 -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 +133 -0
- 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/db/tables/verifiedTokenRequests.test.ts +39 -20
- package/src/db/tables/verifiedTokenRequests.ts +80 -44
- 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 +383 -8
- package/src/internal/Auth.ts +272 -99
- 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 +1299 -18
- package/src/internal/routes/providers/relay.ts +424 -39
- 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"')
|