tapimo 0.14.0 → 0.15.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 +7 -4
- package/dist/ApiKey.js +1 -1
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +95 -14
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +360 -49
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12457 -10365
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +300 -22
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +2 -1
- package/dist/Assets.js.map +1 -1
- package/dist/Handler.d.ts +0 -1
- package/dist/Handler.d.ts.map +1 -1
- package/dist/Handler.js +0 -1
- package/dist/Handler.js.map +1 -1
- package/dist/Scope.d.ts +13 -5
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +16 -5
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.js +1 -1
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +3057 -549
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +26 -5
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +159 -7
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +95 -43
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +1398 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +463 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +267 -15
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +241 -25
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/routes-support.d.ts +95 -0
- package/dist/admin/apps/routes-support.d.ts.map +1 -0
- package/dist/admin/apps/routes-support.js +151 -0
- package/dist/admin/apps/routes-support.js.map +1 -0
- package/dist/admin/apps/routes.d.ts +2764 -0
- package/dist/admin/apps/routes.d.ts.map +1 -0
- package/dist/admin/apps/routes.js +728 -0
- package/dist/admin/apps/routes.js.map +1 -0
- package/dist/admin/apps/subsidies.d.ts +501 -0
- package/dist/admin/apps/subsidies.d.ts.map +1 -0
- package/dist/admin/apps/subsidies.js +384 -0
- package/dist/admin/apps/subsidies.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +88 -88
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +3 -3
- package/dist/admin/apps/verified-tokens.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 +129 -69
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +5 -2
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +31 -1
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +2 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +10 -1
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/analytics/tables/routesLifecycleIntervals.d.ts +72 -0
- package/dist/analytics/tables/routesLifecycleIntervals.d.ts.map +1 -0
- package/dist/analytics/tables/routesLifecycleIntervals.js +56 -0
- package/dist/analytics/tables/routesLifecycleIntervals.js.map +1 -0
- package/dist/apps/Zones.d.ts +21 -12526
- package/dist/apps/Zones.d.ts.map +1 -1
- package/dist/apps/Zones.js +37 -5
- package/dist/apps/Zones.js.map +1 -1
- package/dist/apps/data/App.d.ts +3971 -2595
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +76 -21
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +364 -34
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +495 -190
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +72 -0
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +37 -37
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
- package/dist/apps/data/routes/coingecko.js +47 -21
- package/dist/apps/data/routes/coingecko.js.map +1 -1
- package/dist/apps/data/routes/earn.d.ts +1450 -337
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +1226 -144
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +5 -0
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +31 -19
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +125 -0
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +83 -27
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +507 -33
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +266 -156
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +47 -15
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +68 -11
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +2 -0
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +26 -14
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +28 -12
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +9 -7
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +30 -30
- package/dist/apps/data/routes/verified-tokens.d.ts +9 -9
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +64 -20
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +613 -176
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +291 -195
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts.map +1 -1
- package/dist/apps/data/routes/zones.js +20 -12
- package/dist/apps/data/routes/zones.js.map +1 -1
- package/dist/apps/docs/reference.js +2 -2
- package/dist/apps/docs/reference.js.map +1 -1
- package/dist/apps/index.d.ts +1 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +1 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +3763 -3385
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +5 -14
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/Billing.d.ts +48 -7
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +204 -25
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +106 -4
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +43 -15
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +290 -4
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +274 -49
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/faucet.js +1 -1
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +77 -2
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +117 -13
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +4 -4
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +6 -2
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +30 -30
- package/dist/apps/management/routes/orgs.d.ts +18 -2
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +52 -12
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +4 -4
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +6 -1
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/scopes.d.ts.map +1 -1
- package/dist/apps/management/routes/scopes.js +4 -1
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +24 -24
- package/dist/apps/management/routes/usage.js +21 -4
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +2 -2
- package/dist/apps/management/routes/webhooks.d.ts +280 -214
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +58 -12
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mcp.d.ts +1 -1
- package/dist/apps/mcp.js +7 -7
- package/dist/apps/mcp.js.map +1 -1
- package/dist/apps/mpp/App.d.ts.map +1 -1
- package/dist/apps/mpp/App.js +35 -7
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +2 -0
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +30 -1
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/apps/mpp/internal/Policy.d.ts +22 -4
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Policy.js +24 -6
- package/dist/apps/mpp/internal/Policy.js.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.d.ts +3 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Sponsorship.js +6 -3
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
- package/dist/apps/relay/App.d.ts +2 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +134 -75
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +5 -3
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +209 -28
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/apps/{funding → routes}/Access.d.ts +4 -4
- package/dist/apps/routes/Access.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/Access.js +4 -4
- package/dist/apps/routes/Access.js.map +1 -0
- package/dist/apps/{funding → routes}/App.d.ts +418 -124
- package/dist/apps/{funding → routes}/App.d.ts.map +1 -1
- package/dist/apps/{funding → routes}/App.js +16 -16
- package/dist/apps/routes/App.js.map +1 -0
- package/dist/apps/routes/Inventory.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/Inventory.js +2 -2
- package/dist/apps/routes/Inventory.js.map +1 -0
- package/dist/apps/routes/index.d.ts +2 -0
- package/dist/apps/routes/index.d.ts.map +1 -0
- package/dist/apps/routes/index.js +2 -0
- package/dist/apps/routes/index.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/chains.d.ts +7 -7
- package/dist/apps/routes/routes/chains.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/chains.js +25 -25
- package/dist/apps/routes/routes/chains.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/deposit-addresses.d.ts +107 -43
- package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/deposit-addresses.js +497 -222
- package/dist/apps/routes/routes/deposit-addresses.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/providers.d.ts +8 -8
- package/dist/apps/routes/routes/providers.d.ts.map +1 -0
- package/dist/apps/routes/routes/providers.js +57 -0
- package/dist/apps/routes/routes/providers.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/quotes.d.ts +19 -16
- package/dist/apps/routes/routes/quotes.d.ts.map +1 -0
- package/dist/apps/{funding → routes}/routes/quotes.js +55 -38
- package/dist/apps/routes/routes/quotes.js.map +1 -0
- package/dist/apps/{funding → routes}/routes/transfers.d.ts +379 -74
- package/dist/apps/routes/routes/transfers.d.ts.map +1 -0
- package/dist/apps/routes/routes/transfers.js +1140 -0
- package/dist/apps/routes/routes/transfers.js.map +1 -0
- package/dist/cli/Cli.d.ts +30 -0
- package/dist/cli/Cli.d.ts.map +1 -1
- package/dist/cli/commands/admin.d.ts +36 -0
- package/dist/cli/commands/admin.d.ts.map +1 -1
- package/dist/cli/commands/admin.js +273 -0
- package/dist/cli/commands/admin.js.map +1 -1
- package/dist/cloudflare.d.ts +16 -14
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +26 -21
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +63 -21
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +1030 -15
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +780 -133
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +575 -162
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts +4 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts.map +1 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.js +2 -0
- package/dist/db/tables/apiKeyAdmissionBootstraps.js.map +1 -0
- package/dist/db/tables/apiKeyAdmissions.d.ts +73 -0
- package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -0
- package/dist/db/tables/apiKeyAdmissions.js +142 -0
- package/dist/db/tables/apiKeyAdmissions.js.map +1 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.d.ts +4 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.d.ts.map +1 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.js +2 -0
- package/dist/db/tables/apiKeyOwnerAdmissions.js.map +1 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts +20 -0
- package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -0
- package/dist/db/tables/apiKeyOwnerTombstones.js +57 -0
- package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -0
- package/dist/db/tables/apiKeyRevocations.d.ts +21 -0
- package/dist/db/tables/apiKeyRevocations.d.ts.map +1 -0
- package/dist/db/tables/apiKeyRevocations.js +98 -0
- package/dist/db/tables/apiKeyRevocations.js.map +1 -0
- package/dist/db/tables/authAccounts.d.ts +47 -0
- package/dist/db/tables/authAccounts.d.ts.map +1 -0
- package/dist/db/tables/authAccounts.js +72 -0
- package/dist/db/tables/authAccounts.js.map +1 -0
- package/dist/db/tables/authSessions.d.ts +12 -0
- package/dist/db/tables/authSessions.d.ts.map +1 -0
- package/dist/db/tables/authSessions.js +2 -0
- package/dist/db/tables/authSessions.js.map +1 -0
- package/dist/db/tables/authVerifications.d.ts +12 -0
- package/dist/db/tables/authVerifications.d.ts.map +1 -0
- package/dist/db/tables/authVerifications.js +2 -0
- package/dist/db/tables/authVerifications.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +17 -1
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +123 -43
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/memberships.d.ts +8 -0
- package/dist/db/tables/memberships.d.ts.map +1 -1
- package/dist/db/tables/memberships.js +51 -2
- package/dist/db/tables/memberships.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +32 -10
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +110 -49
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +2 -0
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +12 -3
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/rewardAccounts.d.ts +86 -0
- package/dist/db/tables/rewardAccounts.d.ts.map +1 -0
- package/dist/db/tables/rewardAccounts.js +88 -0
- package/dist/db/tables/rewardAccounts.js.map +1 -0
- package/dist/db/tables/rewardCampaignDistributors.d.ts +36 -0
- package/dist/db/tables/rewardCampaignDistributors.d.ts.map +1 -0
- package/dist/db/tables/rewardCampaignDistributors.js +30 -0
- package/dist/db/tables/rewardCampaignDistributors.js.map +1 -0
- package/dist/db/tables/rewardCampaigns.d.ts +171 -0
- package/dist/db/tables/rewardCampaigns.d.ts.map +1 -0
- package/dist/db/tables/rewardCampaigns.js +392 -0
- package/dist/db/tables/rewardCampaigns.js.map +1 -0
- package/dist/db/tables/rewardCredits.d.ts +53 -0
- package/dist/db/tables/rewardCredits.d.ts.map +1 -0
- package/dist/db/tables/rewardCredits.js +63 -0
- package/dist/db/tables/rewardCredits.js.map +1 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts +61 -0
- package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -0
- package/dist/db/tables/rewardEligibilityAssociations.js +103 -0
- package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -0
- package/dist/db/tables/rewardRuns.d.ts +188 -0
- package/dist/db/tables/rewardRuns.d.ts.map +1 -0
- package/dist/db/tables/rewardRuns.js +278 -0
- package/dist/db/tables/rewardRuns.js.map +1 -0
- package/dist/db/tables/rewardTransactionAttempts.d.ts +100 -0
- package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -0
- package/dist/db/tables/rewardTransactionAttempts.js +163 -0
- package/dist/db/tables/rewardTransactionAttempts.js.map +1 -0
- package/dist/db/tables/routesCatalog.d.ts +58 -0
- package/dist/db/tables/routesCatalog.d.ts.map +1 -0
- package/dist/db/tables/{fundingCatalog.js → routesCatalog.js} +19 -19
- package/dist/db/tables/routesCatalog.js.map +1 -0
- package/dist/db/tables/routesDepositAddresses.d.ts +476 -0
- package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -0
- package/dist/db/tables/routesDepositAddresses.js +587 -0
- package/dist/db/tables/routesDepositAddresses.js.map +1 -0
- package/dist/db/tables/{fundingDepositRequestObservations.d.ts → routesDepositRequestObservations.d.ts} +6 -6
- package/dist/db/tables/routesDepositRequestObservations.d.ts.map +1 -0
- package/dist/db/tables/{fundingDepositRequestObservations.js → routesDepositRequestObservations.js} +6 -6
- package/dist/db/tables/routesDepositRequestObservations.js.map +1 -0
- package/dist/db/tables/{fundingDeposits.d.ts → routesDeposits.d.ts} +210 -22
- package/dist/db/tables/routesDeposits.d.ts.map +1 -0
- package/dist/db/tables/routesDeposits.js +576 -0
- package/dist/db/tables/routesDeposits.js.map +1 -0
- package/dist/db/tables/routesIdempotency.d.ts +166 -0
- package/dist/db/tables/routesIdempotency.d.ts.map +1 -0
- package/dist/db/tables/routesIdempotency.js +330 -0
- package/dist/db/tables/routesIdempotency.js.map +1 -0
- package/dist/db/tables/routesSubsidies.d.ts +27 -0
- package/dist/db/tables/routesSubsidies.d.ts.map +1 -0
- package/dist/db/tables/routesSubsidies.js +45 -0
- package/dist/db/tables/routesSubsidies.js.map +1 -0
- package/dist/db/tables/{fundingTransferEvents.d.ts → routesTransferEvents.d.ts} +3 -3
- package/dist/db/tables/routesTransferEvents.d.ts.map +1 -0
- package/dist/db/tables/{fundingTransferEvents.js → routesTransferEvents.js} +3 -3
- package/dist/db/tables/routesTransferEvents.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts +19 -0
- package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -0
- package/dist/db/tables/routesTransferSubsidies.js +17 -0
- package/dist/db/tables/routesTransferSubsidies.js.map +1 -0
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts +51 -0
- package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -0
- package/dist/db/tables/routesTransferSubsidyNonces.js +82 -0
- package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -0
- package/dist/db/tables/routesTransferTransactions.d.ts +77 -0
- package/dist/db/tables/routesTransferTransactions.d.ts.map +1 -0
- package/dist/db/tables/{fundingTransferTransactions.js → routesTransferTransactions.js} +31 -13
- package/dist/db/tables/routesTransferTransactions.js.map +1 -0
- package/dist/db/tables/routesTransfers.d.ts +319 -0
- package/dist/db/tables/routesTransfers.d.ts.map +1 -0
- package/dist/db/tables/routesTransfers.js +372 -0
- package/dist/db/tables/routesTransfers.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +75 -20
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +124 -54
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/sponsorshipAttributions.d.ts +69 -0
- package/dist/db/tables/sponsorshipAttributions.d.ts.map +1 -0
- package/dist/db/tables/sponsorshipAttributions.js +77 -0
- package/dist/db/tables/sponsorshipAttributions.js.map +1 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.d.ts +22 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.d.ts.map +1 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.js +45 -0
- package/dist/db/tables/sponsorshipReconciliationCursors.js.map +1 -0
- package/dist/db/tables/stripeCustomers.d.ts +11 -0
- package/dist/db/tables/stripeCustomers.d.ts.map +1 -1
- package/dist/db/tables/stripeCustomers.js +13 -0
- package/dist/db/tables/stripeCustomers.js.map +1 -1
- package/dist/db/tables/users.d.ts +17 -1
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +47 -2
- package/dist/db/tables/users.js.map +1 -1
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +5 -1
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +19 -11
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +45 -13
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/executionError.d.ts +2 -2
- package/dist/handlers/internal/executionError.d.ts.map +1 -1
- package/dist/handlers/internal/executionError.js +1 -2
- package/dist/handlers/internal/executionError.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +4 -232
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +11 -537
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/internal/sponsorship.d.ts +19 -8
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
- package/dist/handlers/internal/sponsorship.js +13 -9
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/relay.d.ts +9 -12
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +81 -85
- package/dist/handlers/relay.js.map +1 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +1 -1
- package/dist/internal/AssetResponse.d.ts +12 -0
- package/dist/internal/AssetResponse.d.ts.map +1 -0
- package/dist/internal/AssetResponse.js +21 -0
- package/dist/internal/AssetResponse.js.map +1 -0
- package/dist/internal/Auth.d.ts +48 -12
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +603 -175
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/BetterAuth.d.ts +1488 -0
- package/dist/internal/BetterAuth.d.ts.map +1 -0
- package/dist/internal/BetterAuth.js +253 -0
- package/dist/internal/BetterAuth.js.map +1 -0
- package/dist/internal/Cache.d.ts +2 -0
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +2 -0
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnRates.d.ts +26 -3
- package/dist/internal/EarnRates.d.ts.map +1 -1
- package/dist/internal/EarnRates.js +84 -19
- package/dist/internal/EarnRates.js.map +1 -1
- package/dist/internal/EarnSharePrices.d.ts +120 -0
- package/dist/internal/EarnSharePrices.d.ts.map +1 -0
- package/dist/internal/EarnSharePrices.js +179 -0
- package/dist/internal/EarnSharePrices.js.map +1 -0
- package/dist/internal/EarnVaults.d.ts +4 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +27 -10
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Email.d.ts +37 -0
- package/dist/internal/Email.d.ts.map +1 -0
- package/dist/internal/Email.js +16 -0
- package/dist/internal/Email.js.map +1 -0
- package/dist/internal/Log.d.ts +32 -28
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +18 -11
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts +3 -0
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +67 -8
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/Mpp.d.ts.map +1 -1
- package/dist/internal/Mpp.js +20 -25
- package/dist/internal/Mpp.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +26 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +25 -10
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Provider.d.ts +1 -1
- package/dist/internal/Provider.d.ts.map +1 -1
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +13 -1
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +59 -8
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +9 -2
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +78 -11
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timing.d.ts +26 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +63 -5
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/VercelOidc.d.ts +94 -0
- package/dist/internal/VercelOidc.d.ts.map +1 -0
- package/dist/internal/VercelOidc.js +128 -0
- package/dist/internal/VercelOidc.js.map +1 -0
- package/dist/internal/VerifiedTokens.d.ts +2 -8
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +24 -24
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Viem.d.ts +30 -2067
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +167 -17
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +12 -4
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +9 -3
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/ZoneRpc.d.ts +7 -0
- package/dist/internal/ZoneRpc.d.ts.map +1 -0
- package/dist/internal/ZoneRpc.js +49 -0
- package/dist/internal/ZoneRpc.js.map +1 -0
- package/dist/internal/index.d.ts +3 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +3 -1
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/rewards/Audit.d.ts +88 -0
- package/dist/internal/rewards/Audit.d.ts.map +1 -0
- package/dist/internal/rewards/Audit.js +134 -0
- package/dist/internal/rewards/Audit.js.map +1 -0
- package/dist/internal/rewards/Campaigns.d.ts +572 -0
- package/dist/internal/rewards/Campaigns.d.ts.map +1 -0
- package/dist/internal/rewards/Campaigns.js +531 -0
- package/dist/internal/rewards/Campaigns.js.map +1 -0
- package/dist/internal/rewards/Credits.d.ts +76 -0
- package/dist/internal/rewards/Credits.d.ts.map +1 -0
- package/dist/internal/rewards/Credits.js +95 -0
- package/dist/internal/rewards/Credits.js.map +1 -0
- package/dist/internal/rewards/Events.d.ts +100 -0
- package/dist/internal/rewards/Events.d.ts.map +1 -0
- package/dist/internal/rewards/Events.js +340 -0
- package/dist/internal/rewards/Events.js.map +1 -0
- package/dist/internal/rewards/Projection.d.ts +237 -0
- package/dist/internal/rewards/Projection.d.ts.map +1 -0
- package/dist/internal/rewards/Projection.js +616 -0
- package/dist/internal/rewards/Projection.js.map +1 -0
- package/dist/internal/rewards/Rates.d.ts +44 -0
- package/dist/internal/rewards/Rates.d.ts.map +1 -0
- package/dist/internal/rewards/Rates.js +60 -0
- package/dist/internal/rewards/Rates.js.map +1 -0
- package/dist/internal/rewards/Read.d.ts +158 -0
- package/dist/internal/rewards/Read.d.ts.map +1 -0
- package/dist/internal/rewards/Read.js +292 -0
- package/dist/internal/rewards/Read.js.map +1 -0
- package/dist/internal/rewards/Runner.d.ts +164 -0
- package/dist/internal/rewards/Runner.d.ts.map +1 -0
- package/dist/internal/rewards/Runner.js +1778 -0
- package/dist/internal/rewards/Runner.js.map +1 -0
- package/dist/internal/rewards/Signer.d.ts +224 -0
- package/dist/internal/rewards/Signer.d.ts.map +1 -0
- package/dist/internal/rewards/Signer.js +135 -0
- package/dist/internal/rewards/Signer.js.map +1 -0
- package/dist/internal/rewards/index.d.ts +15 -0
- package/dist/internal/rewards/index.d.ts.map +1 -0
- package/dist/internal/rewards/index.js +15 -0
- package/dist/internal/rewards/index.js.map +1 -0
- package/dist/internal/{funding → routes}/Action.d.ts +12 -1
- package/dist/internal/routes/Action.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Action.js +17 -9
- package/dist/internal/routes/Action.js.map +1 -0
- package/dist/internal/{funding → routes}/Catalog.d.ts +20 -20
- package/dist/internal/routes/Catalog.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Catalog.js +29 -29
- package/dist/internal/routes/Catalog.js.map +1 -0
- package/dist/internal/{funding → routes}/Chain.d.ts +10 -10
- package/dist/internal/routes/Chain.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Chain.js +3 -3
- package/dist/internal/routes/Chain.js.map +1 -0
- package/dist/internal/{funding → routes}/Deposit.d.ts +45 -23
- package/dist/internal/routes/Deposit.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Deposit.js +60 -27
- package/dist/internal/routes/Deposit.js.map +1 -0
- package/dist/internal/{funding → routes}/DepositAddress.d.ts +56 -27
- package/dist/internal/routes/DepositAddress.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/DepositAddress.js +95 -33
- package/dist/internal/routes/DepositAddress.js.map +1 -0
- package/dist/internal/{funding → routes}/DepositWebhook.d.ts +4 -4
- package/dist/internal/routes/DepositWebhook.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/DepositWebhook.js +4 -4
- package/dist/internal/routes/DepositWebhook.js.map +1 -0
- package/dist/internal/routes/Economics.d.ts +25 -0
- package/dist/internal/routes/Economics.d.ts.map +1 -0
- package/dist/internal/routes/Economics.js +28 -0
- package/dist/internal/routes/Economics.js.map +1 -0
- package/dist/internal/{funding → routes}/Evidence.d.ts +3 -3
- package/dist/internal/routes/Evidence.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Evidence.js +7 -7
- package/dist/internal/routes/Evidence.js.map +1 -0
- package/dist/internal/routes/Observability.d.ts +154 -0
- package/dist/internal/routes/Observability.d.ts.map +1 -0
- package/dist/internal/routes/Observability.js +389 -0
- package/dist/internal/routes/Observability.js.map +1 -0
- package/dist/internal/{funding → routes}/Provider.d.ts +311 -105
- package/dist/internal/routes/Provider.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Provider.js +229 -98
- package/dist/internal/routes/Provider.js.map +1 -0
- package/dist/internal/{funding → routes}/Reconciliation.d.ts +11 -6
- package/dist/internal/routes/Reconciliation.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Reconciliation.js +408 -158
- package/dist/internal/routes/Reconciliation.js.map +1 -0
- package/dist/internal/routes/Route.d.ts +21 -0
- package/dist/internal/routes/Route.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Route.js +1 -1
- package/dist/internal/routes/Route.js.map +1 -0
- package/dist/internal/{funding → routes}/SourceObservation.d.ts +6 -6
- package/dist/internal/routes/SourceObservation.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/SourceObservation.js +8 -8
- package/dist/internal/routes/SourceObservation.js.map +1 -0
- package/dist/internal/{funding → routes}/Subsidy.d.ts +48 -3
- package/dist/internal/routes/Subsidy.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Subsidy.js +43 -3
- package/dist/internal/routes/Subsidy.js.map +1 -0
- package/dist/internal/{funding → routes}/Token.d.ts +4 -4
- package/dist/internal/routes/Token.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/Token.js +3 -3
- package/dist/internal/routes/Token.js.map +1 -0
- package/dist/internal/{funding → routes}/Transfer.d.ts +241 -46
- package/dist/internal/routes/Transfer.d.ts.map +1 -0
- package/dist/internal/routes/Transfer.js +728 -0
- package/dist/internal/routes/Transfer.js.map +1 -0
- package/dist/internal/{funding → routes}/TransferReconciliation.d.ts +13 -10
- package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -0
- package/dist/internal/routes/TransferReconciliation.js +422 -0
- package/dist/internal/routes/TransferReconciliation.js.map +1 -0
- package/dist/internal/routes/TransferSubsidy.d.ts +201 -0
- package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -0
- package/dist/internal/routes/TransferSubsidy.js +256 -0
- package/dist/internal/routes/TransferSubsidy.js.map +1 -0
- package/dist/internal/{funding → routes}/TransferWebhook.d.ts +5 -5
- package/dist/internal/routes/TransferWebhook.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/TransferWebhook.js +3 -3
- package/dist/internal/routes/TransferWebhook.js.map +1 -0
- package/dist/internal/{funding → routes}/index.d.ts +2 -0
- package/dist/internal/routes/index.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/index.js +2 -0
- package/dist/internal/routes/index.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/across.d.ts +4 -4
- package/dist/internal/routes/providers/across.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/across.js +13 -13
- package/dist/internal/routes/providers/across.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/relay.d.ts +21 -12
- package/dist/internal/routes/providers/relay.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/relay.js +194 -110
- package/dist/internal/routes/providers/relay.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/rhino.d.ts +4 -4
- package/dist/internal/routes/providers/rhino.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/rhino.js +10 -10
- package/dist/internal/routes/providers/rhino.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/squid.d.ts +4 -4
- package/dist/internal/routes/providers/squid.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/squid.js +14 -14
- package/dist/internal/routes/providers/squid.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/stargate.d.ts +46 -18
- package/dist/internal/routes/providers/stargate.d.ts.map +1 -0
- package/dist/internal/routes/providers/stargate.js +898 -0
- package/dist/internal/routes/providers/stargate.js.map +1 -0
- package/dist/internal/{funding → routes}/providers/symbiosis.d.ts +4 -4
- package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -0
- package/dist/internal/{funding → routes}/providers/symbiosis.js +30 -20
- package/dist/internal/routes/providers/symbiosis.js.map +1 -0
- package/dist/internal/webhookDestinations/slack.js +12 -12
- package/dist/internal/webhookDestinations/slack.js.map +1 -1
- package/dist/providers/index.d.ts +12 -12
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +12 -12
- package/dist/providers/index.js.map +1 -1
- package/dist/server.d.ts +19 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +19 -0
- package/dist/server.js.map +1 -0
- package/package.json +15 -4
- package/src/ApiKey.ts +1 -1
- package/src/ApiKeys.test.ts +1033 -3
- package/src/ApiKeys.ts +489 -48
- package/src/App.test-d.ts +1 -1
- package/src/App.test.ts +216 -25
- package/src/App.ts +334 -31
- package/src/Assets.test.ts +2 -2
- package/src/Assets.ts +3 -1
- package/src/Auth.test-d.ts +1 -1
- package/src/Client.test-d.ts +539 -110
- package/src/Handler.ts +0 -1
- package/src/OpenApi.contract.test.ts +195 -0
- package/src/Scope.ts +17 -5
- package/src/Webhooks.ts +1 -1
- package/src/admin/App.test.ts +30 -2
- package/src/admin/App.ts +42 -6
- package/src/admin/apps/api-keys.test.ts +267 -5
- package/src/admin/apps/api-keys.ts +100 -50
- package/src/admin/apps/earn-vaults.test.ts +158 -0
- package/src/admin/apps/earn-vaults.ts +679 -6
- package/src/admin/apps/organizations.test.ts +306 -17
- package/src/admin/apps/organizations.ts +299 -24
- package/src/admin/apps/routes-support.test.ts +200 -0
- package/src/admin/apps/routes-support.ts +201 -0
- package/src/admin/apps/routes.test.ts +450 -0
- package/src/admin/apps/routes.ts +896 -0
- package/src/admin/apps/scopes.test.ts +15 -5
- package/src/admin/apps/subsidies.test.ts +306 -0
- package/src/admin/apps/subsidies.ts +457 -0
- package/src/admin/apps/verified-tokens.test.ts +8 -3
- package/src/admin/apps/verified-tokens.ts +3 -3
- package/src/admin/ui/plugin.ts +1 -2
- package/src/admin/ui/src/components/RewardCampaignForm.tsx +1009 -0
- package/src/admin/ui/src/lib/config.ts +11 -2
- package/src/admin/ui/src/lib/earn-vaults.ts +2 -2
- package/src/admin/ui/src/lib/organizations.test.ts +83 -50
- package/src/admin/ui/src/lib/organizations.ts +106 -25
- package/src/admin/ui/src/lib/query-client.ts +1 -1
- package/src/admin/ui/src/lib/reward-campaigns.ts +136 -0
- package/src/admin/ui/src/lib/routes.test.ts +88 -0
- package/src/admin/ui/src/lib/routes.ts +304 -0
- package/src/admin/ui/src/lib/subsidies.ts +75 -0
- package/src/admin/ui/src/routeTree.gen.ts +63 -0
- package/src/admin/ui/src/routes/__root.tsx +12 -1
- package/src/admin/ui/src/routes/api-keys.tsx +196 -84
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +105 -70
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +239 -23
- package/src/admin/ui/src/routes/routes.tsx +1615 -0
- package/src/admin/ui/src/routes/routes_.support.tsx +248 -0
- package/src/admin/ui/src/routes/subsidies.tsx +799 -0
- package/src/admin/ui.generated.ts +144 -69
- package/src/analytics/Analytics.test.ts +108 -18
- package/src/analytics/Analytics.ts +38 -6
- package/src/analytics/tables/requestEvents.test.ts +100 -0
- package/src/analytics/tables/requestEvents.ts +10 -1
- package/src/analytics/tables/routesLifecycleIntervals.ts +140 -0
- package/src/apps/Zones.test.ts +15 -0
- package/src/apps/Zones.ts +52 -5
- package/src/apps/composition.test.ts +68 -60
- package/src/apps/data/App.test.ts +154 -2
- package/src/apps/data/App.ts +88 -28
- package/src/apps/data/routes/activities.test.ts +419 -7
- package/src/apps/data/routes/activities.ts +683 -216
- package/src/apps/data/routes/balances.test.ts +2 -2
- package/src/apps/data/routes/blocks.test.ts +46 -1
- package/src/apps/data/routes/coingecko.test.ts +419 -1
- package/src/apps/data/routes/coingecko.ts +309 -253
- package/src/apps/data/routes/earn.discovery.test.ts +274 -0
- package/src/apps/data/routes/earn.test.ts +1294 -17
- package/src/apps/data/routes/earn.ts +1838 -321
- package/src/apps/data/routes/exchanges.test.ts +12 -15
- package/src/apps/data/routes/fee-amm.test.ts +224 -0
- package/src/apps/data/routes/fee-amm.ts +191 -160
- package/src/apps/data/routes/indexer.test.ts +389 -0
- package/src/apps/data/routes/indexer.ts +165 -69
- package/src/apps/data/routes/receipts.test.ts +1 -1
- package/src/apps/data/routes/rpc.test.ts +352 -8
- package/src/apps/data/routes/rpc.ts +407 -219
- package/src/apps/data/routes/rpc.zone.test.ts +340 -0
- package/src/apps/data/routes/tokenlist.test.ts +285 -0
- package/src/apps/data/routes/tokenlist.ts +173 -88
- package/src/apps/data/routes/tokens.test.ts +93 -3
- package/src/apps/data/routes/tokens.ts +39 -23
- package/src/apps/data/routes/transactions.test.ts +1 -1
- package/src/apps/data/routes/transfers.test.ts +56 -24
- package/src/apps/data/routes/transfers.ts +19 -8
- package/src/apps/data/routes/valuation.test.ts +1 -1
- package/src/apps/data/routes/verified-tokens.test.ts +345 -0
- package/src/apps/data/routes/verified-tokens.ts +99 -29
- package/src/apps/data/routes/webhooks.test.ts +645 -83
- package/src/apps/data/routes/webhooks.ts +1089 -857
- package/src/apps/data/routes/zones.test.ts +148 -71
- package/src/apps/data/routes/zones.ts +71 -55
- package/src/apps/docs/reference.ts +2 -2
- package/src/apps/index.ts +1 -1
- package/src/apps/management/App.ts +9 -51
- package/src/apps/management/Billing.test.ts +375 -14
- package/src/apps/management/Billing.ts +265 -29
- package/src/apps/management/routes/api-keys.test.ts +269 -7
- package/src/apps/management/routes/api-keys.ts +61 -20
- package/src/apps/management/routes/billing.test.ts +477 -15
- package/src/apps/management/routes/billing.ts +377 -50
- package/src/apps/management/routes/faucet.test.ts +1 -1
- package/src/apps/management/routes/faucet.ts +1 -1
- package/src/apps/management/routes/invitations.test.ts +270 -3
- package/src/apps/management/routes/invitations.ts +185 -15
- package/src/apps/management/routes/invoicePreview.test.ts +549 -0
- package/src/apps/management/routes/me.test.ts +246 -5
- package/src/apps/management/routes/me.ts +7 -2
- package/src/apps/management/routes/members.test.ts +108 -0
- package/src/apps/management/routes/orgs.test.ts +191 -3
- package/src/apps/management/routes/orgs.ts +58 -11
- package/src/apps/management/routes/projects.test.ts +33 -3
- package/src/apps/management/routes/projects.ts +6 -1
- package/src/apps/management/routes/scopes.test.ts +30 -2
- package/src/apps/management/routes/scopes.ts +4 -1
- package/src/apps/management/routes/usage.test.ts +32 -0
- package/src/apps/management/routes/usage.ts +22 -4
- package/src/apps/management/routes/webhooks.test.ts +49 -26
- package/src/apps/management/routes/webhooks.ts +78 -22
- package/src/apps/mcp.test.ts +6 -6
- package/src/apps/mcp.ts +7 -7
- package/src/apps/mpp/App.ts +37 -7
- package/src/apps/mpp/Mpp.test.ts +49 -8
- package/src/apps/mpp/Mpp.zone.test.ts +219 -0
- package/src/apps/mpp/internal/Adapter.ts +34 -0
- package/src/apps/mpp/internal/Policy.test.ts +86 -31
- package/src/apps/mpp/internal/Policy.ts +49 -7
- package/src/apps/mpp/internal/Sponsorship.test.ts +207 -0
- package/src/apps/mpp/internal/Sponsorship.ts +9 -3
- package/src/apps/relay/App.test.ts +839 -64
- package/src/apps/relay/App.ts +148 -81
- package/src/apps/relay/App.zone-billing.test.ts +257 -0
- package/src/apps/relay/Sponsorships.test.ts +67 -4
- package/src/apps/relay/Sponsorships.ts +233 -32
- package/src/apps/relay/Sponsorships.zone.test.ts +102 -0
- package/src/apps/{funding → routes}/Access.ts +6 -6
- package/src/apps/routes/App.test.ts +165 -0
- package/src/apps/routes/App.ts +96 -0
- package/src/apps/{funding → routes}/Inventory.ts +2 -2
- package/src/apps/routes/index.ts +1 -0
- package/src/apps/{funding → routes}/routes/chains.test.ts +66 -66
- package/src/apps/{funding → routes}/routes/chains.ts +23 -23
- package/src/apps/{funding → routes}/routes/deposit-addresses.test.ts +1358 -458
- package/src/apps/{funding → routes}/routes/deposit-addresses.ts +566 -246
- package/src/apps/{funding → routes}/routes/providers.test.ts +27 -33
- package/src/apps/{funding → routes}/routes/providers.ts +23 -23
- package/src/apps/{funding → routes}/routes/quotes.test.ts +298 -41
- package/src/apps/{funding → routes}/routes/quotes.ts +57 -40
- package/src/apps/{funding → routes}/routes/transfers.test.ts +1100 -353
- package/src/apps/routes/routes/transfers.ts +1332 -0
- package/src/cli/Cli.test.ts +1 -1
- package/src/cli/commands/admin.test.ts +748 -1
- package/src/cli/commands/admin.ts +278 -0
- package/src/cloudflare.ts +52 -47
- package/src/db/Db.test.ts +245 -2
- package/src/db/Db.ts +1476 -34
- package/src/db/Schema.ts +729 -228
- package/src/db/tables/apiKeyAdmissionBootstraps.ts +4 -0
- package/src/db/tables/apiKeyAdmissions.ts +218 -0
- package/src/db/tables/apiKeyOwnerAdmissions.ts +4 -0
- package/src/db/tables/apiKeyOwnerTombstones.ts +81 -0
- package/src/db/tables/apiKeyRevocations.test.ts +74 -0
- package/src/db/tables/apiKeyRevocations.ts +121 -0
- package/src/db/tables/authAccounts.ts +105 -0
- package/src/db/tables/authSessions.ts +13 -0
- package/src/db/tables/authVerifications.ts +13 -0
- package/src/db/tables/invitations.ts +142 -45
- package/src/db/tables/memberships.ts +79 -3
- package/src/db/tables/organizations.test.ts +690 -13
- package/src/db/tables/organizations.ts +139 -55
- package/src/db/tables/projects.test.ts +16 -0
- package/src/db/tables/projects.ts +13 -3
- package/src/db/tables/requestUsage.ts +4 -1
- package/src/db/tables/rewardAccounts.ts +178 -0
- package/src/db/tables/rewardCampaignDistributors.ts +68 -0
- package/src/db/tables/rewardCampaigns.test.ts +1388 -0
- package/src/db/tables/rewardCampaigns.ts +647 -0
- package/src/db/tables/rewardCredits.ts +110 -0
- package/src/db/tables/rewardEligibilityAssociations.test.ts +271 -0
- package/src/db/tables/rewardEligibilityAssociations.ts +184 -0
- package/src/db/tables/rewardRuns.ts +514 -0
- package/src/db/tables/rewardTransactionAttempts.ts +272 -0
- package/src/db/tables/routesCatalog.test.ts +185 -0
- package/src/db/tables/routesCatalog.ts +163 -0
- package/src/db/tables/routesDepositAddresses.test.ts +1048 -0
- package/src/db/tables/routesDepositAddresses.ts +1008 -0
- package/src/db/tables/{fundingDepositRequestObservations.test.ts → routesDepositRequestObservations.test.ts} +13 -14
- package/src/db/tables/{fundingDepositRequestObservations.ts → routesDepositRequestObservations.ts} +10 -10
- package/src/db/tables/{fundingDeposits.test.ts → routesDeposits.test.ts} +316 -46
- package/src/db/tables/routesDeposits.ts +1062 -0
- package/src/db/tables/routesIdempotency.test.ts +796 -0
- package/src/db/tables/routesIdempotency.ts +496 -0
- package/src/db/tables/routesSubsidies.test.ts +120 -0
- package/src/db/tables/routesSubsidies.ts +71 -0
- package/src/db/tables/{fundingTransferEvents.ts → routesTransferEvents.ts} +4 -4
- package/src/db/tables/routesTransferSubsidies.ts +38 -0
- package/src/db/tables/routesTransferSubsidyNonces.ts +124 -0
- package/src/db/tables/routesTransferTransactions.test.ts +195 -0
- package/src/db/tables/{fundingTransferTransactions.ts → routesTransferTransactions.ts} +63 -18
- package/src/db/tables/routesTransfers.test.ts +338 -0
- package/src/db/tables/routesTransfers.ts +662 -0
- package/src/db/tables/sponsoredTransactions.test.ts +269 -45
- package/src/db/tables/sponsoredTransactions.ts +225 -65
- package/src/db/tables/sponsorshipAttributions.test.ts +160 -0
- package/src/db/tables/sponsorshipAttributions.ts +168 -0
- package/src/db/tables/sponsorshipReconciliationCursors.test.ts +115 -0
- package/src/db/tables/sponsorshipReconciliationCursors.ts +67 -0
- package/src/db/tables/stripeCustomers.test.ts +85 -0
- package/src/db/tables/stripeCustomers.ts +24 -0
- package/src/db/tables/users.test.ts +129 -0
- package/src/db/tables/users.ts +49 -3
- package/src/db/tables/webhookQueueEvents.ts +8 -1
- package/src/db/tables/webhookSubscriptions.ts +95 -20
- package/src/handlers/internal/executionError.ts +3 -4
- package/src/handlers/internal/multisig.ts +13 -816
- package/src/handlers/internal/sponsorship.ts +26 -10
- package/src/handlers/relay.test-d.ts +9 -1
- package/src/handlers/relay.test.ts +823 -3
- package/src/handlers/relay.ts +127 -107
- package/src/index.test-d.ts +7 -0
- package/src/index.ts +0 -17
- package/src/internal/AssetResponse.ts +26 -0
- package/src/internal/Auth.test.ts +1564 -9
- package/src/internal/Auth.ts +833 -239
- package/src/internal/BetterAuth.test.ts +242 -0
- package/src/internal/BetterAuth.ts +349 -0
- package/src/internal/Cache.ts +2 -0
- package/src/internal/EarnRates.test.ts +17 -0
- package/src/internal/EarnRates.ts +124 -31
- package/src/internal/EarnSharePrices.test.ts +182 -0
- package/src/internal/EarnSharePrices.ts +313 -0
- package/src/internal/EarnVaults.test.ts +21 -0
- package/src/internal/EarnVaults.ts +33 -11
- package/src/internal/Email.ts +54 -0
- package/src/internal/Idempotency.test.ts +2 -2
- package/src/internal/Log.test-d.ts +8 -7
- package/src/internal/Log.test.ts +114 -16
- package/src/internal/Log.ts +53 -40
- package/src/internal/MetricSink.test.ts +313 -26
- package/src/internal/MetricSink.ts +73 -8
- package/src/internal/Mpp.test.ts +31 -0
- package/src/internal/Mpp.ts +21 -24
- package/src/internal/OpenApi.ts +45 -12
- package/src/internal/Provider.test.ts +1 -1
- package/src/internal/Provider.ts +1 -1
- package/src/internal/RateLimit.test.ts +21 -3
- package/src/internal/RateLimit.ts +12 -1
- package/src/internal/Store.test-d.ts +1 -1
- package/src/internal/Store.test.ts +151 -8
- package/src/internal/Store.ts +76 -9
- package/src/internal/Tidx.test.ts +59 -8
- package/src/internal/Tidx.ts +86 -14
- package/src/internal/Timing.test.ts +77 -0
- package/src/internal/Timing.ts +83 -6
- package/src/internal/VercelOidc.test.ts +188 -0
- package/src/internal/VercelOidc.ts +193 -0
- package/src/internal/VerifiedTokens.test.ts +60 -6
- package/src/internal/VerifiedTokens.ts +21 -24
- package/src/internal/Viem.batch.test.ts +80 -0
- package/src/internal/Viem.test.ts +201 -2
- package/src/internal/Viem.ts +221 -25
- package/src/internal/Webhooks.test.ts +85 -6
- package/src/internal/Webhooks.ts +22 -4
- package/src/internal/ZoneRpc.ts +50 -0
- package/src/internal/exchange/Provider.test.ts +2 -2
- package/src/internal/index.test.ts +3 -1
- package/src/internal/index.ts +3 -1
- package/src/internal/rewards/Audit.ts +231 -0
- package/src/internal/rewards/Campaigns.test.ts +1234 -0
- package/src/internal/rewards/Campaigns.ts +1205 -0
- package/src/internal/rewards/Credits.ts +165 -0
- package/src/internal/rewards/Events.local.test.ts +113 -0
- package/src/internal/rewards/Events.test.ts +152 -0
- package/src/internal/rewards/Events.ts +468 -0
- package/src/internal/rewards/Projection.test.ts +681 -0
- package/src/internal/rewards/Projection.ts +987 -0
- package/src/internal/rewards/Rates.test.ts +171 -0
- package/src/internal/rewards/Rates.ts +110 -0
- package/src/internal/rewards/Read.test.ts +501 -0
- package/src/internal/rewards/Read.ts +476 -0
- package/src/internal/rewards/Runner.checkpoint.test.ts +80 -0
- package/src/internal/rewards/Runner.states.test.ts +188 -0
- package/src/internal/rewards/Runner.test.ts +90 -0
- package/src/internal/rewards/Runner.ts +2229 -0
- package/src/internal/rewards/Signer.test.ts +79 -0
- package/src/internal/rewards/Signer.ts +180 -0
- package/src/internal/rewards/index.ts +14 -0
- package/src/internal/{funding → routes}/Action.test.ts +63 -14
- package/src/internal/{funding → routes}/Action.ts +35 -8
- package/src/internal/{funding → routes}/Catalog.test.ts +3 -3
- package/src/internal/{funding → routes}/Catalog.ts +39 -39
- package/src/internal/{funding → routes}/Chain.test.ts +1 -1
- package/src/internal/{funding → routes}/Chain.ts +11 -11
- package/src/internal/{funding → routes}/Deposit.test.ts +1 -1
- package/src/internal/{funding → routes}/Deposit.ts +93 -45
- package/src/internal/{funding → routes}/DepositAddress.test.ts +11 -3
- package/src/internal/{funding → routes}/DepositAddress.ts +132 -53
- package/src/internal/{funding → routes}/DepositWebhook.test.ts +61 -18
- package/src/internal/{funding → routes}/DepositWebhook.ts +9 -9
- package/src/internal/routes/Economics.test.ts +42 -0
- package/src/internal/routes/Economics.ts +47 -0
- package/src/internal/{funding → routes}/Evidence.test.ts +6 -6
- package/src/internal/{funding → routes}/Evidence.ts +9 -9
- package/src/internal/routes/Observability.test.ts +636 -0
- package/src/internal/routes/Observability.ts +668 -0
- package/src/internal/{funding → routes}/Provider.test.ts +489 -153
- package/src/internal/{funding → routes}/Provider.ts +489 -186
- package/src/internal/{funding → routes}/Reconciliation.local.test.ts +84 -12
- package/src/internal/{funding → routes}/Reconciliation.test.ts +1213 -279
- package/src/internal/{funding → routes}/Reconciliation.ts +501 -203
- package/src/internal/routes/Reconciliation.unattributed.test.ts +250 -0
- package/src/internal/{funding → routes}/Route.ts +7 -7
- package/src/internal/{funding → routes}/SourceObservation.test.ts +13 -14
- package/src/internal/{funding → routes}/SourceObservation.ts +13 -13
- package/src/internal/{funding → routes}/Subsidy.local.test.ts +7 -7
- package/src/internal/routes/Subsidy.test.ts +169 -0
- package/src/internal/{funding → routes}/Subsidy.ts +86 -6
- package/src/internal/{funding → routes}/Token.test.ts +1 -1
- package/src/internal/{funding → routes}/Token.ts +5 -5
- package/src/internal/routes/Transfer.test.ts +1199 -0
- package/src/internal/routes/Transfer.ts +1206 -0
- package/src/internal/routes/TransferReconciliation.test.ts +731 -0
- package/src/internal/routes/TransferReconciliation.ts +527 -0
- package/src/internal/routes/TransferSubsidy.test.ts +172 -0
- package/src/internal/routes/TransferSubsidy.ts +447 -0
- package/src/internal/{funding → routes}/TransferWebhook.test.ts +13 -13
- package/src/internal/{funding → routes}/TransferWebhook.ts +7 -7
- package/src/internal/{funding → routes}/index.test.ts +5 -3
- package/src/internal/{funding → routes}/index.ts +2 -0
- package/src/internal/{funding → routes}/providers/across.ts +16 -16
- package/src/internal/{funding → routes}/providers/index.test.ts +157 -44
- package/src/internal/{funding → routes}/providers/relay.test.ts +165 -32
- package/src/internal/{funding → routes}/providers/relay.ts +228 -121
- package/src/internal/{funding → routes}/providers/rhino.ts +16 -16
- package/src/internal/{funding → routes}/providers/squid.ts +17 -17
- package/src/internal/routes/providers/stargate.test.ts +728 -0
- package/src/internal/routes/providers/stargate.ts +1276 -0
- package/src/internal/{funding → routes}/providers/symbiosis.ts +64 -24
- package/src/internal/webhookDestinations/slack.ts +10 -10
- package/src/providers/index.ts +13 -13
- package/src/server.ts +18 -0
- package/dist/apps/funding/Access.d.ts.map +0 -1
- package/dist/apps/funding/Access.js.map +0 -1
- package/dist/apps/funding/App.js.map +0 -1
- package/dist/apps/funding/Inventory.d.ts.map +0 -1
- package/dist/apps/funding/Inventory.js.map +0 -1
- package/dist/apps/funding/ProviderAttempts.d.ts +0 -5
- package/dist/apps/funding/ProviderAttempts.d.ts.map +0 -1
- package/dist/apps/funding/ProviderAttempts.js +0 -24
- package/dist/apps/funding/ProviderAttempts.js.map +0 -1
- package/dist/apps/funding/index.d.ts +0 -2
- package/dist/apps/funding/index.d.ts.map +0 -1
- package/dist/apps/funding/index.js +0 -2
- package/dist/apps/funding/index.js.map +0 -1
- package/dist/apps/funding/routes/chains.d.ts.map +0 -1
- package/dist/apps/funding/routes/chains.js.map +0 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +0 -1
- package/dist/apps/funding/routes/deposit-addresses.js.map +0 -1
- package/dist/apps/funding/routes/providers.d.ts.map +0 -1
- package/dist/apps/funding/routes/providers.js +0 -57
- package/dist/apps/funding/routes/providers.js.map +0 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +0 -1
- package/dist/apps/funding/routes/quotes.js.map +0 -1
- package/dist/apps/funding/routes/transfers.d.ts.map +0 -1
- package/dist/apps/funding/routes/transfers.js +0 -828
- package/dist/apps/funding/routes/transfers.js.map +0 -1
- package/dist/db/tables/fundingCatalog.d.ts +0 -58
- package/dist/db/tables/fundingCatalog.d.ts.map +0 -1
- package/dist/db/tables/fundingCatalog.js.map +0 -1
- package/dist/db/tables/fundingDepositAddresses.d.ts +0 -192
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +0 -1
- package/dist/db/tables/fundingDepositAddresses.js +0 -235
- package/dist/db/tables/fundingDepositAddresses.js.map +0 -1
- package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +0 -1
- package/dist/db/tables/fundingDepositRequestObservations.js.map +0 -1
- package/dist/db/tables/fundingDeposits.d.ts.map +0 -1
- package/dist/db/tables/fundingDeposits.js +0 -295
- package/dist/db/tables/fundingDeposits.js.map +0 -1
- package/dist/db/tables/fundingIdempotency.d.ts +0 -91
- package/dist/db/tables/fundingIdempotency.d.ts.map +0 -1
- package/dist/db/tables/fundingIdempotency.js +0 -103
- package/dist/db/tables/fundingIdempotency.js.map +0 -1
- package/dist/db/tables/fundingTransferEvents.d.ts.map +0 -1
- package/dist/db/tables/fundingTransferEvents.js.map +0 -1
- package/dist/db/tables/fundingTransferTransactions.d.ts +0 -53
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +0 -1
- package/dist/db/tables/fundingTransferTransactions.js.map +0 -1
- package/dist/db/tables/fundingTransfers.d.ts +0 -99
- package/dist/db/tables/fundingTransfers.d.ts.map +0 -1
- package/dist/db/tables/fundingTransfers.js +0 -110
- package/dist/db/tables/fundingTransfers.js.map +0 -1
- package/dist/internal/funding/Action.d.ts.map +0 -1
- package/dist/internal/funding/Action.js.map +0 -1
- package/dist/internal/funding/Catalog.d.ts.map +0 -1
- package/dist/internal/funding/Catalog.js.map +0 -1
- package/dist/internal/funding/Chain.d.ts.map +0 -1
- package/dist/internal/funding/Chain.js.map +0 -1
- package/dist/internal/funding/Deposit.d.ts.map +0 -1
- package/dist/internal/funding/Deposit.js.map +0 -1
- package/dist/internal/funding/DepositAddress.d.ts.map +0 -1
- package/dist/internal/funding/DepositAddress.js.map +0 -1
- package/dist/internal/funding/DepositWebhook.d.ts.map +0 -1
- package/dist/internal/funding/DepositWebhook.js.map +0 -1
- package/dist/internal/funding/Evidence.d.ts.map +0 -1
- package/dist/internal/funding/Evidence.js.map +0 -1
- package/dist/internal/funding/Provider.d.ts.map +0 -1
- package/dist/internal/funding/Provider.js.map +0 -1
- package/dist/internal/funding/Reconciliation.d.ts.map +0 -1
- package/dist/internal/funding/Reconciliation.js.map +0 -1
- package/dist/internal/funding/Route.d.ts +0 -21
- package/dist/internal/funding/Route.d.ts.map +0 -1
- package/dist/internal/funding/Route.js.map +0 -1
- package/dist/internal/funding/SourceObservation.d.ts.map +0 -1
- package/dist/internal/funding/SourceObservation.js.map +0 -1
- package/dist/internal/funding/Subsidy.d.ts.map +0 -1
- package/dist/internal/funding/Subsidy.js.map +0 -1
- package/dist/internal/funding/Token.d.ts.map +0 -1
- package/dist/internal/funding/Token.js.map +0 -1
- package/dist/internal/funding/Transfer.d.ts.map +0 -1
- package/dist/internal/funding/Transfer.js +0 -462
- package/dist/internal/funding/Transfer.js.map +0 -1
- package/dist/internal/funding/TransferReconciliation.d.ts.map +0 -1
- package/dist/internal/funding/TransferReconciliation.js +0 -192
- package/dist/internal/funding/TransferReconciliation.js.map +0 -1
- package/dist/internal/funding/TransferWebhook.d.ts.map +0 -1
- package/dist/internal/funding/TransferWebhook.js.map +0 -1
- package/dist/internal/funding/index.d.ts.map +0 -1
- package/dist/internal/funding/index.js.map +0 -1
- package/dist/internal/funding/providers/across.d.ts.map +0 -1
- package/dist/internal/funding/providers/across.js.map +0 -1
- package/dist/internal/funding/providers/relay.d.ts.map +0 -1
- package/dist/internal/funding/providers/relay.js.map +0 -1
- package/dist/internal/funding/providers/rhino.d.ts.map +0 -1
- package/dist/internal/funding/providers/rhino.js.map +0 -1
- package/dist/internal/funding/providers/squid.d.ts.map +0 -1
- package/dist/internal/funding/providers/squid.js.map +0 -1
- package/dist/internal/funding/providers/stargate.d.ts.map +0 -1
- package/dist/internal/funding/providers/stargate.js +0 -579
- package/dist/internal/funding/providers/stargate.js.map +0 -1
- package/dist/internal/funding/providers/symbiosis.d.ts.map +0 -1
- package/dist/internal/funding/providers/symbiosis.js.map +0 -1
- package/src/apps/funding/App.test.ts +0 -78
- package/src/apps/funding/App.ts +0 -88
- package/src/apps/funding/ProviderAttempts.ts +0 -26
- package/src/apps/funding/index.ts +0 -1
- package/src/apps/funding/routes/transfers.ts +0 -987
- package/src/db/tables/fundingCatalog.test.ts +0 -122
- package/src/db/tables/fundingCatalog.ts +0 -163
- package/src/db/tables/fundingDepositAddresses.test.ts +0 -608
- package/src/db/tables/fundingDepositAddresses.ts +0 -443
- package/src/db/tables/fundingDeposits.ts +0 -572
- package/src/db/tables/fundingIdempotency.test.ts +0 -182
- package/src/db/tables/fundingIdempotency.ts +0 -180
- package/src/db/tables/fundingTransferTransactions.test.ts +0 -112
- package/src/db/tables/fundingTransfers.test.ts +0 -115
- package/src/db/tables/fundingTransfers.ts +0 -189
- package/src/handlers/internal/multisig.test.ts +0 -818
- package/src/internal/funding/Subsidy.test.ts +0 -75
- package/src/internal/funding/Transfer.test.ts +0 -524
- package/src/internal/funding/Transfer.ts +0 -762
- package/src/internal/funding/TransferReconciliation.test.ts +0 -147
- package/src/internal/funding/TransferReconciliation.ts +0 -264
- package/src/internal/funding/providers/stargate.test.ts +0 -328
- package/src/internal/funding/providers/stargate.ts +0 -856
- /package/dist/apps/{funding → routes}/Inventory.d.ts +0 -0
- /package/src/internal/{funding → routes}/Route.test.ts +0 -0
|
@@ -6,6 +6,9 @@ import {
|
|
|
6
6
|
ContractFunctionExecutionError,
|
|
7
7
|
ContractFunctionRevertedError,
|
|
8
8
|
ContractFunctionZeroDataError,
|
|
9
|
+
isAddress,
|
|
10
|
+
parseAbi,
|
|
11
|
+
parseUnits,
|
|
9
12
|
zeroAddress,
|
|
10
13
|
} from 'viem'
|
|
11
14
|
import * as z from 'zod/mini'
|
|
@@ -14,12 +17,18 @@ import type * as App from '../../../App.js'
|
|
|
14
17
|
import * as Scope from '../../../Scope.js'
|
|
15
18
|
import * as Db from '../../../db/Db.js'
|
|
16
19
|
import * as core_EarnVaults from '../../../db/tables/earnVaults.js'
|
|
20
|
+
import * as RewardCampaignDistributors from '../../../db/tables/rewardCampaignDistributors.js'
|
|
21
|
+
import * as RewardCampaigns from '../../../db/tables/rewardCampaigns.js'
|
|
22
|
+
import * as RewardEligibilityAssociations from '../../../db/tables/rewardEligibilityAssociations.js'
|
|
17
23
|
import * as Auth from '../../../internal/Auth.js'
|
|
18
24
|
import * as Cache from '../../../internal/Cache.js'
|
|
19
25
|
import * as Cursor from '../../../internal/Cursor.js'
|
|
20
26
|
import * as EarnRates from '../../../internal/EarnRates.js'
|
|
27
|
+
import * as EarnSharePrices from '../../../internal/EarnSharePrices.js'
|
|
21
28
|
import * as EarnVaults from '../../../internal/EarnVaults.js'
|
|
29
|
+
import type * as Log from '../../../internal/Log.js'
|
|
22
30
|
import * as OpenApi from '../../../internal/OpenApi.js'
|
|
31
|
+
import * as RewardRead from '../../../internal/rewards/Read.js'
|
|
23
32
|
import * as Response from '../../../internal/Response.js'
|
|
24
33
|
import * as Schema from '../../../internal/Schema.js'
|
|
25
34
|
import * as Store from '../../../internal/Store.js'
|
|
@@ -28,6 +37,7 @@ import * as Timing from '../../../internal/Timing.js'
|
|
|
28
37
|
import * as Ttl from '../../../internal/Ttl.js'
|
|
29
38
|
import * as Value from '../../../internal/Value.js'
|
|
30
39
|
import * as VerifiedTokens from '../../../internal/VerifiedTokens.js'
|
|
40
|
+
import * as Viem from '../../../internal/Viem.js'
|
|
31
41
|
import * as FxOracle from '../FxOracle.js'
|
|
32
42
|
import * as Tokens from './tokens.js'
|
|
33
43
|
import * as Valuation from './valuation.js'
|
|
@@ -35,6 +45,27 @@ import * as Valuation from './valuation.js'
|
|
|
35
45
|
const deployedSignature =
|
|
36
46
|
'event EarnStackDeployed(address indexed earnVault,address indexed earnShare,address indexed earnFees,address engine,address asset,address owner,bytes32 deploymentId,address emergencyGuardian,address asyncJanitor,uint8 migrationMode,bytes32 earnShareSalt,bytes32 controlConfigHash,bytes32 feeConfigHash,bytes32 earnFeesSalt)'
|
|
37
47
|
|
|
48
|
+
// Historical factories for this signature, verified against upstream deployments
|
|
49
|
+
// and compiled EarnFactory releases. See docs/earn-discovery.md before updating.
|
|
50
|
+
const deploymentFactories: Record<number, readonly string[]> = {
|
|
51
|
+
4217: [
|
|
52
|
+
'0x5b972d2490d06e436982fab77612fd9987f097d0',
|
|
53
|
+
'0x75b20eafdbd3dd974d00b573fd72852ab0237afd',
|
|
54
|
+
],
|
|
55
|
+
42431: [
|
|
56
|
+
'0x0f9ccbc97563a179f5f0886f89ee51c9185f6ec4',
|
|
57
|
+
'0x2aa26b7e24e6f1fb2d539d527b8f1bb5cacfa288',
|
|
58
|
+
'0x4990c74ae874f2b0fd4938662e2cdb8ca4c27887',
|
|
59
|
+
'0x518d4fbd5334bb7ff67c6ebcb67a7d60e1ef8d5d',
|
|
60
|
+
'0x6742345070be5a20ce05f53b6d08d071162c0ef8',
|
|
61
|
+
'0x846b8479d64691ff61c05137dc580a1ecdc188c5',
|
|
62
|
+
'0xb4944264260a6412351d64653f65d2c27d9cb038',
|
|
63
|
+
'0xb4ecb65a57e3585c3699c1617c2abb5de35a697d',
|
|
64
|
+
'0xb5e53c6b17c6f3a380ad94f5417c5e541dfeefac',
|
|
65
|
+
'0xe8fd5b183021ba3f6d3197c5b4238c93561b1b7a',
|
|
66
|
+
],
|
|
67
|
+
}
|
|
68
|
+
|
|
38
69
|
const depositedSignature =
|
|
39
70
|
'event Deposited(address indexed caller,address indexed receiver,uint256 assets,uint256 earnShares)'
|
|
40
71
|
|
|
@@ -56,12 +87,19 @@ const redeemRequestedSignature =
|
|
|
56
87
|
const venueSharesDepositedSignature =
|
|
57
88
|
'event VenueSharesDeposited(address indexed caller,address indexed receiver,uint256 requestedVenueShares,uint256 receivedVenueShares,uint256 earnShares)'
|
|
58
89
|
|
|
90
|
+
const unspentReturnedSignature =
|
|
91
|
+
'event UnspentReturned(address indexed treasury,uint256 earnShares)'
|
|
92
|
+
|
|
59
93
|
const maxScannedDeployments = 250
|
|
60
94
|
const scanLimit = 50
|
|
61
95
|
|
|
62
96
|
// Concurrent metadata reads in one macrotask collapse into one deployless
|
|
63
97
|
// multicall; an await between small chunks keeps each call under the RPC limit.
|
|
64
98
|
const tokenReadChunkSize = 20
|
|
99
|
+
const tempoStateAddress = '0x1c00000000000000000000000000000000000000'
|
|
100
|
+
const tempoStateAbi = parseAbi(['function tempoBlockNumber() view returns (uint64)'])
|
|
101
|
+
const zonePortalAbi = parseAbi(['function lastSyncedTempoBlockNumber() view returns (uint64)'])
|
|
102
|
+
const tokenPositionAbi = parseAbi(['function balanceOf(address account) view returns (uint256)'])
|
|
65
103
|
/** Block boundary that includes all indexed history. */
|
|
66
104
|
const beforeFirstBlockNumber = -1
|
|
67
105
|
|
|
@@ -71,6 +109,13 @@ const tvlDenomination = 'USD'
|
|
|
71
109
|
/** `Valuation.valuationFor` floors to 6 dp, so 6 is the precision a valued amount carries. */
|
|
72
110
|
const tvlDecimals = 6
|
|
73
111
|
|
|
112
|
+
function toRewardEligibilityAssociation(record: RewardEligibilityAssociations.Record) {
|
|
113
|
+
return {
|
|
114
|
+
...record,
|
|
115
|
+
id: `${record.vaultAddress}-${record.walletAddress}`,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
74
119
|
/** Returns the smallest useful live-discovery batch. */
|
|
75
120
|
export function discoveryBatchLimit(options: discoveryBatchLimit.Options): number {
|
|
76
121
|
const needed = options.limit + 1 - options.matches
|
|
@@ -109,6 +154,118 @@ export declare namespace hasZoneAccess {
|
|
|
109
154
|
|
|
110
155
|
/** Zod schemas owned by the public Earn-vault resource. */
|
|
111
156
|
export namespace schema {
|
|
157
|
+
/** Schemas for the registerRewardEligibility operation. */
|
|
158
|
+
export namespace registerRewardEligibility {
|
|
159
|
+
/** Wallet and vault association to register for reward eligibility. */
|
|
160
|
+
export const Body = z
|
|
161
|
+
.strictObject({
|
|
162
|
+
chainId: Schema.ChainId.check(
|
|
163
|
+
z.describe('Chain containing the Earn vault.'),
|
|
164
|
+
z.meta({ examples: [4217] }),
|
|
165
|
+
),
|
|
166
|
+
transactionHash: z.optional(Schema.hash(`0x${'33'.repeat(32)}`)),
|
|
167
|
+
vaultAddress: Schema.Address.check(
|
|
168
|
+
z.describe('Earn vault contract address.'),
|
|
169
|
+
z.meta({ examples: ['0x59d27987bc7cc1521bba5f688a170c65840cbf43'] }),
|
|
170
|
+
),
|
|
171
|
+
walletAddress: Schema.Address.check(
|
|
172
|
+
z.describe('Wallet to register for rewards.'),
|
|
173
|
+
z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
|
|
174
|
+
),
|
|
175
|
+
})
|
|
176
|
+
.check(z.describe('Reward eligibility registration.'))
|
|
177
|
+
|
|
178
|
+
/** Persisted reward eligibility association. */
|
|
179
|
+
export const Association = z
|
|
180
|
+
.strictObject({
|
|
181
|
+
chainId: Schema.ChainId,
|
|
182
|
+
firstRegisteredAt: z.iso
|
|
183
|
+
.datetime()
|
|
184
|
+
.check(
|
|
185
|
+
z.describe('When the association was first registered.'),
|
|
186
|
+
z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
|
|
187
|
+
),
|
|
188
|
+
id: z.string().check(
|
|
189
|
+
z.describe('Stable reward eligibility association identifier.'),
|
|
190
|
+
z.meta({
|
|
191
|
+
examples: [
|
|
192
|
+
'0x59d27987bc7cc1521bba5f688a170c65840cbf43-0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6',
|
|
193
|
+
],
|
|
194
|
+
}),
|
|
195
|
+
),
|
|
196
|
+
latestRegisteredAt: z.iso
|
|
197
|
+
.datetime()
|
|
198
|
+
.check(
|
|
199
|
+
z.describe('When the association was most recently registered.'),
|
|
200
|
+
z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
|
|
201
|
+
),
|
|
202
|
+
registrationOrder: z
|
|
203
|
+
.string()
|
|
204
|
+
.check(
|
|
205
|
+
z.regex(/^\d+$/),
|
|
206
|
+
z.describe('Monotonic registration order.'),
|
|
207
|
+
z.meta({ examples: ['42'] }),
|
|
208
|
+
),
|
|
209
|
+
transactionHash: z.optional(Schema.hash(`0x${'33'.repeat(32)}`)),
|
|
210
|
+
vaultAddress: Schema.Address,
|
|
211
|
+
walletAddress: Schema.Address,
|
|
212
|
+
})
|
|
213
|
+
.check(z.describe('Persisted reward eligibility association.'))
|
|
214
|
+
|
|
215
|
+
/** Persisted reward eligibility registration result. */
|
|
216
|
+
export const Response = z
|
|
217
|
+
.strictObject({
|
|
218
|
+
association: Association,
|
|
219
|
+
created: z
|
|
220
|
+
.boolean()
|
|
221
|
+
.check(
|
|
222
|
+
z.describe('Whether this request created the association.'),
|
|
223
|
+
z.meta({ examples: [true] }),
|
|
224
|
+
),
|
|
225
|
+
})
|
|
226
|
+
.check(z.describe('Persisted reward eligibility registration result.'))
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Schemas for the getRewardEligibility operation. */
|
|
230
|
+
export namespace getRewardEligibility {
|
|
231
|
+
const Limit = z
|
|
232
|
+
._default(
|
|
233
|
+
z.pipe(
|
|
234
|
+
z.coerce.number().check(z.int(), z.gte(Schema.minLimit)),
|
|
235
|
+
z.transform((value) => Math.min(value, 100)),
|
|
236
|
+
),
|
|
237
|
+
10,
|
|
238
|
+
)
|
|
239
|
+
.check(
|
|
240
|
+
z.describe(
|
|
241
|
+
'How many items to return per page (5 to 100, default 10). Use `nextCursor` to fetch more.',
|
|
242
|
+
),
|
|
243
|
+
z.meta({ examples: [10] }),
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
/** Selects one chain and vault eligibility snapshot page. */
|
|
247
|
+
export const Query = z
|
|
248
|
+
.strictObject({
|
|
249
|
+
chainId: Schema.ChainId.check(z.describe('Chain containing the Earn vault.')),
|
|
250
|
+
cursor: Schema.Cursor,
|
|
251
|
+
limit: Limit,
|
|
252
|
+
vaultAddress: Schema.Address.check(z.describe('Earn vault contract address.')),
|
|
253
|
+
})
|
|
254
|
+
.check(z.describe('Reward eligibility page selector.'))
|
|
255
|
+
|
|
256
|
+
/** One page of eligible wallets at the cursor's fixed checkpoint. */
|
|
257
|
+
export const Response = z
|
|
258
|
+
.strictObject({
|
|
259
|
+
chainId: Schema.ChainId,
|
|
260
|
+
data: z
|
|
261
|
+
.array(Schema.Address)
|
|
262
|
+
.check(z.describe('Eligible wallet addresses in registration order.')),
|
|
263
|
+
nextCursor: Schema.NextCursor,
|
|
264
|
+
vaultAddress: Schema.Address,
|
|
265
|
+
})
|
|
266
|
+
.check(z.describe('A fixed-snapshot page of eligible wallet addresses.'))
|
|
267
|
+
}
|
|
268
|
+
|
|
112
269
|
const capability = z
|
|
113
270
|
.enum([
|
|
114
271
|
'asyncRedeem',
|
|
@@ -126,25 +283,28 @@ export namespace schema {
|
|
|
126
283
|
.enum(['erc4626', 'veda'])
|
|
127
284
|
.check(z.describe('Inferred vault engine type.'), z.meta({ examples: ['erc4626'] }))
|
|
128
285
|
|
|
129
|
-
const engine =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
286
|
+
const engine = OpenApi.component(
|
|
287
|
+
Schema.describe(
|
|
288
|
+
z.strictObject({
|
|
289
|
+
address: Schema.Address.check(
|
|
290
|
+
z.describe('Current vault engine contract address.'),
|
|
291
|
+
z.meta({ examples: ['0x59d27987bc7cc1521bba5f688a170c65840cbf43'] }),
|
|
292
|
+
),
|
|
293
|
+
type: z
|
|
294
|
+
.nullable(engineType)
|
|
295
|
+
.check(z.describe('Inferred engine type, or null when it is unknown.')),
|
|
296
|
+
venue: z
|
|
297
|
+
.nullable(
|
|
298
|
+
Schema.Address.check(
|
|
299
|
+
z.describe('Yield venue contract bound to the engine.'),
|
|
300
|
+
z.meta({ examples: ['0x9a044ae05e5e6290dcf56afd69548565e957a626'] }),
|
|
301
|
+
),
|
|
302
|
+
)
|
|
303
|
+
.check(z.describe('Yield venue, or null when the engine does not expose one.')),
|
|
304
|
+
}),
|
|
305
|
+
'Current vault engine.',
|
|
306
|
+
),
|
|
307
|
+
'EarnVaultEngine',
|
|
148
308
|
)
|
|
149
309
|
|
|
150
310
|
const include = z
|
|
@@ -156,6 +316,85 @@ export namespace schema {
|
|
|
156
316
|
'Comma-separated vault fields to include, such as `apy,tvl`.',
|
|
157
317
|
)
|
|
158
318
|
|
|
319
|
+
const aprRatio = z
|
|
320
|
+
.string()
|
|
321
|
+
.check(
|
|
322
|
+
z.regex(/^\d+(\.\d+)?$/),
|
|
323
|
+
z.describe('Annual percentage rate as a non-negative decimal ratio.'),
|
|
324
|
+
z.meta({ examples: ['0.0195'] }),
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
const reward = z.strictObject({
|
|
328
|
+
apr: z
|
|
329
|
+
.nullable(aprRatio)
|
|
330
|
+
.check(z.describe('Current reward APR, or null before its first calculation.')),
|
|
331
|
+
asset: z
|
|
332
|
+
.strictObject({
|
|
333
|
+
address: Schema.Address,
|
|
334
|
+
chainId: Schema.ChainId,
|
|
335
|
+
decimals: z
|
|
336
|
+
.number()
|
|
337
|
+
.check(
|
|
338
|
+
z.int(),
|
|
339
|
+
z.nonnegative(),
|
|
340
|
+
z.describe('Reward asset decimal places.'),
|
|
341
|
+
z.meta({ examples: [18] }),
|
|
342
|
+
),
|
|
343
|
+
})
|
|
344
|
+
.check(z.describe('EarnShare token distributed by the reward campaign.')),
|
|
345
|
+
calculatedThrough: z
|
|
346
|
+
.optional(z.number().check(z.int(), z.nonnegative()))
|
|
347
|
+
.check(
|
|
348
|
+
z.describe('Unix timestamp through which a calculated reward APR applies.'),
|
|
349
|
+
z.meta({ examples: [1788134700] }),
|
|
350
|
+
),
|
|
351
|
+
campaignId: z
|
|
352
|
+
.string()
|
|
353
|
+
.check(
|
|
354
|
+
z.describe('EarnVault address that identifies the reward campaign.'),
|
|
355
|
+
z.meta({ examples: ['0x1000000000000000000000000000000000000001'] }),
|
|
356
|
+
),
|
|
357
|
+
endsAt: z
|
|
358
|
+
.number()
|
|
359
|
+
.check(
|
|
360
|
+
z.int(),
|
|
361
|
+
z.nonnegative(),
|
|
362
|
+
z.describe('Exclusive campaign end as a Unix timestamp.'),
|
|
363
|
+
z.meta({ examples: [1790812800] }),
|
|
364
|
+
),
|
|
365
|
+
startsAt: z
|
|
366
|
+
.number()
|
|
367
|
+
.check(
|
|
368
|
+
z.int(),
|
|
369
|
+
z.nonnegative(),
|
|
370
|
+
z.describe('Inclusive campaign start as a Unix timestamp.'),
|
|
371
|
+
z.meta({ examples: [1788134400] }),
|
|
372
|
+
),
|
|
373
|
+
targetTotalApr: aprRatio.check(
|
|
374
|
+
z.describe('Configured target for combined observed vault yield and Merkle rewards.'),
|
|
375
|
+
z.meta({ examples: ['0.0700'] }),
|
|
376
|
+
),
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
const apy = z.strictObject({
|
|
380
|
+
asOf: EarnRates.schema.Apy.shape.asOf,
|
|
381
|
+
methodology: EarnRates.schema.Apy.shape.methodology,
|
|
382
|
+
net: EarnRates.schema.Apy.shape.net.check(
|
|
383
|
+
z.describe('Higher of observed vault APY and configured reward campaign targets.'),
|
|
384
|
+
),
|
|
385
|
+
rewards: z
|
|
386
|
+
.optional(z.array(reward))
|
|
387
|
+
.check(
|
|
388
|
+
z.describe(
|
|
389
|
+
'Enabled, registered Merkle rewards. Omitted when reward enrichment is unavailable.',
|
|
390
|
+
),
|
|
391
|
+
),
|
|
392
|
+
vault: EarnRates.schema.Apy.shape.net.check(
|
|
393
|
+
z.describe('Observed fee-aware vault APY before reward APR.'),
|
|
394
|
+
),
|
|
395
|
+
window: EarnRates.schema.Apy.shape.window,
|
|
396
|
+
})
|
|
397
|
+
|
|
159
398
|
// `apy` and `tvl` need indexer and FX access, so surfaces lacking either
|
|
160
399
|
// select from this reduced set instead.
|
|
161
400
|
const baseInclude = z
|
|
@@ -167,65 +406,71 @@ export namespace schema {
|
|
|
167
406
|
'Comma-separated vault fields to include, such as `access,zone`.',
|
|
168
407
|
)
|
|
169
408
|
|
|
170
|
-
const zone =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
inputTokens: z
|
|
177
|
-
.array(Schema.Address)
|
|
178
|
-
.check(
|
|
179
|
-
z.describe('Tokens accepted by private deposits.'),
|
|
180
|
-
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
181
|
-
),
|
|
182
|
-
name: z
|
|
183
|
-
.string()
|
|
184
|
-
.check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-mainnet-internal'] })),
|
|
185
|
-
outputTokens: z
|
|
186
|
-
.array(Schema.Address)
|
|
187
|
-
.check(
|
|
188
|
-
z.describe('Tokens supported by private redemptions.'),
|
|
189
|
-
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
409
|
+
const zone = OpenApi.component(
|
|
410
|
+
z
|
|
411
|
+
.strictObject({
|
|
412
|
+
chainId: Schema.ChainId.check(
|
|
413
|
+
z.describe('Private Zone chain id.'),
|
|
414
|
+
z.meta({ examples: [421700001] }),
|
|
190
415
|
),
|
|
191
|
-
|
|
192
|
-
|
|
416
|
+
inputTokens: z
|
|
417
|
+
.array(Schema.Address)
|
|
418
|
+
.check(
|
|
419
|
+
z.describe('Tokens accepted by private deposits.'),
|
|
420
|
+
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
421
|
+
),
|
|
422
|
+
name: z
|
|
423
|
+
.string()
|
|
424
|
+
.check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-mainnet-internal'] })),
|
|
425
|
+
outputTokens: z
|
|
426
|
+
.array(Schema.Address)
|
|
427
|
+
.check(
|
|
428
|
+
z.describe('Tokens supported by private redemptions.'),
|
|
429
|
+
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
430
|
+
),
|
|
431
|
+
})
|
|
432
|
+
.check(z.describe('Private Zone route configured for a verified vault.')),
|
|
433
|
+
'EarnVaultZone',
|
|
434
|
+
)
|
|
193
435
|
|
|
194
|
-
const zoneRoute =
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
deploymentBlock: z
|
|
201
|
-
.number()
|
|
202
|
-
.check(
|
|
203
|
-
z.int(),
|
|
204
|
-
z.nonnegative(),
|
|
205
|
-
z.describe('Parent-chain block that deployed the Earn router.'),
|
|
206
|
-
z.meta({ examples: [35816964] }),
|
|
207
|
-
),
|
|
208
|
-
earnRouter: Schema.Address.check(
|
|
209
|
-
z.describe('Parent-chain router for this Zone and Earn vault.'),
|
|
210
|
-
z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
|
|
211
|
-
),
|
|
212
|
-
inputTokens: z
|
|
213
|
-
.array(Schema.Address)
|
|
214
|
-
.check(
|
|
215
|
-
z.describe('Tokens accepted by private deposits.'),
|
|
216
|
-
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
436
|
+
const zoneRoute = OpenApi.component(
|
|
437
|
+
z
|
|
438
|
+
.strictObject({
|
|
439
|
+
chainId: Schema.ChainId.check(
|
|
440
|
+
z.describe('Private Zone chain id.'),
|
|
441
|
+
z.meta({ examples: [421700001] }),
|
|
217
442
|
),
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
443
|
+
deploymentBlock: z
|
|
444
|
+
.number()
|
|
445
|
+
.check(
|
|
446
|
+
z.int(),
|
|
447
|
+
z.nonnegative(),
|
|
448
|
+
z.describe('Parent-chain block that deployed the Earn router.'),
|
|
449
|
+
z.meta({ examples: [35822949] }),
|
|
450
|
+
),
|
|
451
|
+
earnRouter: Schema.Address.check(
|
|
452
|
+
z.describe('Parent-chain router for this Zone and Earn vault.'),
|
|
453
|
+
z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
|
|
226
454
|
),
|
|
227
|
-
|
|
228
|
-
|
|
455
|
+
inputTokens: z
|
|
456
|
+
.array(Schema.Address)
|
|
457
|
+
.check(
|
|
458
|
+
z.describe('Tokens accepted by private deposits.'),
|
|
459
|
+
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
460
|
+
),
|
|
461
|
+
name: z
|
|
462
|
+
.string()
|
|
463
|
+
.check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-mainnet-internal'] })),
|
|
464
|
+
outputTokens: z
|
|
465
|
+
.array(Schema.Address)
|
|
466
|
+
.check(
|
|
467
|
+
z.describe('Tokens returned by private redemptions.'),
|
|
468
|
+
z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
|
|
469
|
+
),
|
|
470
|
+
})
|
|
471
|
+
.check(z.describe('Verified Earn route through one private Zone.')),
|
|
472
|
+
'EarnVaultZoneRoute',
|
|
473
|
+
)
|
|
229
474
|
|
|
230
475
|
const value = z.strictObject({
|
|
231
476
|
amount: Schema.DecimalString.check(
|
|
@@ -257,10 +502,10 @@ export namespace schema {
|
|
|
257
502
|
.optional(EarnVaults.schema.Discovery.shape.access)
|
|
258
503
|
.check(z.describe('Vault share-token access, when requested.')),
|
|
259
504
|
apy: z
|
|
260
|
-
.optional(z.nullable(
|
|
505
|
+
.optional(z.nullable(apy))
|
|
261
506
|
.check(
|
|
262
507
|
z.describe(
|
|
263
|
-
'Annualized
|
|
508
|
+
'Annualized vault yield over the selected window, plus every available current Merkle reward APR. Null when no component is measurable.',
|
|
264
509
|
),
|
|
265
510
|
),
|
|
266
511
|
assetToken: Tokens.schema.Token.check(
|
|
@@ -365,7 +610,7 @@ export namespace schema {
|
|
|
365
610
|
[
|
|
366
611
|
{
|
|
367
612
|
chainId: 421700001,
|
|
368
|
-
deploymentBlock:
|
|
613
|
+
deploymentBlock: 35822949,
|
|
369
614
|
earnRouter: '0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6',
|
|
370
615
|
inputTokens: ['0x20c0000000000000000000006fd9a167923ba194'],
|
|
371
616
|
name: 'zone-mainnet-internal',
|
|
@@ -378,26 +623,32 @@ export namespace schema {
|
|
|
378
623
|
})
|
|
379
624
|
|
|
380
625
|
/** One compatible Earn vault resolved from current chain state. */
|
|
381
|
-
export const Vault =
|
|
626
|
+
export const Vault = OpenApi.component(
|
|
627
|
+
Schema.describe(vault, 'A compatible earn vault resolved from chain state.'),
|
|
628
|
+
'EarnVault',
|
|
629
|
+
)
|
|
382
630
|
|
|
383
631
|
/** One registry-curated Earn vault. */
|
|
384
|
-
export const VerifiedVault =
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
632
|
+
export const VerifiedVault = OpenApi.component(
|
|
633
|
+
Schema.describe(
|
|
634
|
+
z.extend(vault, {
|
|
635
|
+
engine: z.extend(engine, { type: engineType }),
|
|
636
|
+
slug: z
|
|
637
|
+
.string()
|
|
638
|
+
.check(
|
|
639
|
+
z.describe('Stable curated vault slug.'),
|
|
640
|
+
z.meta({ examples: ['btpathusd-earn-h8k2m4n6'] }),
|
|
641
|
+
),
|
|
642
|
+
verified: z
|
|
643
|
+
.literal(true)
|
|
644
|
+
.check(
|
|
645
|
+
z.describe('This vault is in the curated earn registry.'),
|
|
646
|
+
z.meta({ examples: [true] }),
|
|
647
|
+
),
|
|
648
|
+
}),
|
|
649
|
+
'A registry-curated earn vault resolved from chain state.',
|
|
650
|
+
),
|
|
651
|
+
'VerifiedEarnVault',
|
|
401
652
|
)
|
|
402
653
|
|
|
403
654
|
const position = z.strictObject({
|
|
@@ -406,7 +657,9 @@ export namespace schema {
|
|
|
406
657
|
z.meta({ examples: ['0xbe058e1c4df8a4366a387bf595b284246a93039e'] }),
|
|
407
658
|
),
|
|
408
659
|
assetAllowance: Schema.DecimalString.check(
|
|
409
|
-
z.describe(
|
|
660
|
+
z.describe(
|
|
661
|
+
'Assets the vault may spend from a direct account, in asset base units. Always zero for Zone-routed positions, which use Zone withdrawals instead of approvals.',
|
|
662
|
+
),
|
|
410
663
|
z.meta({ examples: ['0'] }),
|
|
411
664
|
),
|
|
412
665
|
assetBalance: Schema.DecimalString.check(
|
|
@@ -414,14 +667,20 @@ export namespace schema {
|
|
|
414
667
|
z.meta({ examples: ['250000000'] }),
|
|
415
668
|
),
|
|
416
669
|
assetToken: Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50').check(
|
|
417
|
-
z.describe('TIP-20 asset token accepted by the vault.'),
|
|
670
|
+
z.describe('TIP-20 asset token accepted by the vault or its selected Zone route.'),
|
|
671
|
+
),
|
|
672
|
+
chainId: Schema.ChainId.check(
|
|
673
|
+
z.describe('Chain containing the account position.'),
|
|
674
|
+
z.meta({ examples: [42431] }),
|
|
418
675
|
),
|
|
419
676
|
id: Schema.Address.check(
|
|
420
677
|
z.describe('Stable resource ID for this vault position, equal to the account address.'),
|
|
421
678
|
z.meta({ examples: ['0xbe058e1c4df8a4366a387bf595b284246a93039e'] }),
|
|
422
679
|
),
|
|
423
680
|
shareAllowance: Schema.DecimalString.check(
|
|
424
|
-
z.describe(
|
|
681
|
+
z.describe(
|
|
682
|
+
'Earn shares the vault may spend from a direct account, in share base units. Always zero for Zone-routed positions, which use Zone withdrawals instead of approvals.',
|
|
683
|
+
),
|
|
425
684
|
z.meta({ examples: ['0'] }),
|
|
426
685
|
),
|
|
427
686
|
shareBalance: Schema.DecimalString.check(
|
|
@@ -433,12 +692,91 @@ export namespace schema {
|
|
|
433
692
|
),
|
|
434
693
|
value: Schema.DecimalString.check(
|
|
435
694
|
z.describe(
|
|
436
|
-
'Asset value of this account’s earn shares at the observation block, including fees, in
|
|
695
|
+
'Asset value of this account’s earn shares at the observation block, including fees, in `valueToken` base units.',
|
|
437
696
|
),
|
|
438
697
|
z.meta({ examples: ['100000000'] }),
|
|
439
698
|
),
|
|
699
|
+
valueToken: Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50').check(
|
|
700
|
+
z.describe('TIP-20 asset denominating `value` on the vault’s parent chain.'),
|
|
701
|
+
),
|
|
440
702
|
})
|
|
441
703
|
|
|
704
|
+
const positionApy = z
|
|
705
|
+
.strictObject({
|
|
706
|
+
breakdown: z
|
|
707
|
+
.array(
|
|
708
|
+
z
|
|
709
|
+
.strictObject({
|
|
710
|
+
assetAmount: z
|
|
711
|
+
.strictObject({
|
|
712
|
+
baseUnits: Schema.DecimalString.check(
|
|
713
|
+
z.describe('Position amount in vault asset base units.'),
|
|
714
|
+
z.meta({ examples: ['25000000000'] }),
|
|
715
|
+
),
|
|
716
|
+
decimals: z
|
|
717
|
+
.number()
|
|
718
|
+
.check(
|
|
719
|
+
z.int(),
|
|
720
|
+
z.nonnegative(),
|
|
721
|
+
z.describe('Vault asset decimal places.'),
|
|
722
|
+
z.meta({ examples: [6] }),
|
|
723
|
+
),
|
|
724
|
+
formatted: z
|
|
725
|
+
.string()
|
|
726
|
+
.check(
|
|
727
|
+
z.regex(/^\d+(\.\d+)?$/),
|
|
728
|
+
z.describe('Position amount rendered in whole vault asset units.'),
|
|
729
|
+
z.meta({ examples: ['25000'] }),
|
|
730
|
+
),
|
|
731
|
+
})
|
|
732
|
+
.check(
|
|
733
|
+
z.describe('Vault asset amount receiving this annual rate.'),
|
|
734
|
+
z.meta({
|
|
735
|
+
examples: [{ baseUnits: '25000000000', decimals: 6, formatted: '25000' }],
|
|
736
|
+
}),
|
|
737
|
+
),
|
|
738
|
+
net: EarnRates.schema.Apy.shape.net.check(
|
|
739
|
+
z.describe('Annual rate applied to this position amount.'),
|
|
740
|
+
z.meta({ examples: ['0.07'] }),
|
|
741
|
+
),
|
|
742
|
+
type: z
|
|
743
|
+
.enum(['base', 'boost'])
|
|
744
|
+
.check(
|
|
745
|
+
z.describe('Base vault yield or qualified depositor boost.'),
|
|
746
|
+
z.meta({ examples: ['boost'] }),
|
|
747
|
+
),
|
|
748
|
+
})
|
|
749
|
+
.check(z.describe('Position component receiving one annual rate.')),
|
|
750
|
+
)
|
|
751
|
+
.check(
|
|
752
|
+
z.describe('Position amounts grouped by the annual rate they receive.'),
|
|
753
|
+
z.meta({
|
|
754
|
+
examples: [
|
|
755
|
+
[
|
|
756
|
+
{
|
|
757
|
+
assetAmount: {
|
|
758
|
+
baseUnits: '25000000000',
|
|
759
|
+
decimals: 6,
|
|
760
|
+
formatted: '25000',
|
|
761
|
+
},
|
|
762
|
+
net: '0.07',
|
|
763
|
+
type: 'boost',
|
|
764
|
+
},
|
|
765
|
+
],
|
|
766
|
+
],
|
|
767
|
+
}),
|
|
768
|
+
),
|
|
769
|
+
net: EarnRates.schema.Apy.shape.net.check(
|
|
770
|
+
z.describe('Balance-weighted annual rate for this wallet position.'),
|
|
771
|
+
z.meta({ examples: ['0.0616666666666667'] }),
|
|
772
|
+
),
|
|
773
|
+
})
|
|
774
|
+
.check(
|
|
775
|
+
z.describe(
|
|
776
|
+
'Wallet-specific effective APY combining live position amounts with qualification from the latest delivered reward snapshot.',
|
|
777
|
+
),
|
|
778
|
+
)
|
|
779
|
+
|
|
442
780
|
const lifetimeCashFlows = z.union([
|
|
443
781
|
z.strictObject({
|
|
444
782
|
status: z
|
|
@@ -464,41 +802,55 @@ export namespace schema {
|
|
|
464
802
|
}),
|
|
465
803
|
])
|
|
466
804
|
|
|
467
|
-
const addressPosition =
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
475
|
-
),
|
|
476
|
-
lifetimeCashFlows: z
|
|
477
|
-
.optional(lifetimeCashFlows)
|
|
478
|
-
.check(z.describe('Lifetime deposits and completed withdrawals, when requested.')),
|
|
479
|
-
shareAmount: value.check(
|
|
480
|
-
z.describe('Earn share balance this account holds, in `shareToken` units.'),
|
|
481
|
-
),
|
|
482
|
-
shareToken: Tokens.schema.Token.check(z.describe('Token representing vault shares.')),
|
|
483
|
-
valuation: z
|
|
484
|
-
.optional(z.nullable(Valuation.schema.Value))
|
|
485
|
-
.check(
|
|
486
|
-
z.describe(
|
|
487
|
-
'The position’s nominal value when `valuation.currency` is requested, or `null` when ' +
|
|
488
|
-
'the asset token is unverified, its display currency has no rate, or rates were unavailable.',
|
|
805
|
+
const addressPosition = OpenApi.component(
|
|
806
|
+
z
|
|
807
|
+
.strictObject({
|
|
808
|
+
assetAmount: value.check(
|
|
809
|
+
z.describe(
|
|
810
|
+
'Current asset value of the held shares, including fees, in `valueToken` units.',
|
|
811
|
+
),
|
|
489
812
|
),
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
813
|
+
assetToken: Tokens.schema.Token.check(z.describe('Asset accepted by the vault.')),
|
|
814
|
+
chainId: Schema.ChainId.check(
|
|
815
|
+
z.describe('Chain containing the held shares.'),
|
|
816
|
+
z.meta({ examples: [42431] }),
|
|
817
|
+
),
|
|
818
|
+
id: Schema.Address.check(
|
|
819
|
+
z.describe('Stable resource ID for this position, equal to the vault address.'),
|
|
820
|
+
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
821
|
+
),
|
|
822
|
+
lifetimeCashFlows: z
|
|
823
|
+
.optional(lifetimeCashFlows)
|
|
824
|
+
.check(z.describe('Lifetime deposits and completed withdrawals, when requested.')),
|
|
825
|
+
shareAmount: value.check(
|
|
826
|
+
z.describe('Earn share balance this account holds, in `shareToken` units.'),
|
|
827
|
+
),
|
|
828
|
+
shareToken: Tokens.schema.Token.check(z.describe('Token representing vault shares.')),
|
|
829
|
+
valuation: z
|
|
830
|
+
.optional(z.nullable(Valuation.schema.Value))
|
|
831
|
+
.check(
|
|
832
|
+
z.describe(
|
|
833
|
+
'The position’s nominal value when `valuation.currency` is requested, or `null` when ' +
|
|
834
|
+
'the asset token is unverified, its display currency has no rate, or rates were unavailable.',
|
|
835
|
+
),
|
|
836
|
+
),
|
|
837
|
+
valueToken: Tokens.schema.Token.check(
|
|
838
|
+
z.describe('Parent-chain asset denominating `assetAmount`.'),
|
|
839
|
+
),
|
|
840
|
+
vaultAddress: Schema.Address.check(
|
|
841
|
+
z.describe('Earn vault contract address holding this position.'),
|
|
842
|
+
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
843
|
+
),
|
|
844
|
+
verified: z
|
|
845
|
+
.boolean()
|
|
846
|
+
.check(
|
|
847
|
+
z.describe('Whether the vault is in the curated earn registry.'),
|
|
848
|
+
z.meta({ examples: [true] }),
|
|
849
|
+
),
|
|
850
|
+
})
|
|
851
|
+
.check(z.describe('An account’s position in one earn vault.')),
|
|
852
|
+
'EarnAddressPosition',
|
|
853
|
+
)
|
|
502
854
|
|
|
503
855
|
const earningsBase = z.strictObject({
|
|
504
856
|
account: Schema.Address.check(
|
|
@@ -703,15 +1055,18 @@ export namespace schema {
|
|
|
703
1055
|
export const Query = collectionQuery
|
|
704
1056
|
|
|
705
1057
|
/** Paginated list of compatible deployed Earn vaults. */
|
|
706
|
-
export const Response =
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
1058
|
+
export const Response = OpenApi.component(
|
|
1059
|
+
z
|
|
1060
|
+
.strictObject({
|
|
1061
|
+
data: z
|
|
1062
|
+
.array(Vault)
|
|
1063
|
+
.check(z.describe('Compatible deployed earn vaults in deployment order.')),
|
|
1064
|
+
meta: z.optional(meta),
|
|
1065
|
+
nextCursor: Schema.NextCursor,
|
|
1066
|
+
})
|
|
1067
|
+
.check(z.describe('A page of compatible deployed earn vaults.')),
|
|
1068
|
+
'EarnVaultList',
|
|
1069
|
+
)
|
|
715
1070
|
}
|
|
716
1071
|
|
|
717
1072
|
/** Schemas for the getVerifiedEarnVaults operation. */
|
|
@@ -726,15 +1081,18 @@ export namespace schema {
|
|
|
726
1081
|
export const Query = collectionQuery
|
|
727
1082
|
|
|
728
1083
|
/** Paginated list of registry-curated Earn vaults. */
|
|
729
|
-
export const Response =
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1084
|
+
export const Response = OpenApi.component(
|
|
1085
|
+
z
|
|
1086
|
+
.strictObject({
|
|
1087
|
+
data: z
|
|
1088
|
+
.array(VerifiedVault)
|
|
1089
|
+
.check(z.describe('Registry-curated earn vaults ordered by vault address.')),
|
|
1090
|
+
meta: z.optional(meta),
|
|
1091
|
+
nextCursor: Schema.NextCursor,
|
|
1092
|
+
})
|
|
1093
|
+
.check(z.describe('A page of registry-curated earn vaults.')),
|
|
1094
|
+
'VerifiedEarnVaultList',
|
|
1095
|
+
)
|
|
738
1096
|
}
|
|
739
1097
|
|
|
740
1098
|
/** Schemas for the getEarnAddressPositions operation. */
|
|
@@ -753,7 +1111,7 @@ export namespace schema {
|
|
|
753
1111
|
cursor: Schema.Cursor,
|
|
754
1112
|
include: Schema.includeQuery(
|
|
755
1113
|
z.enum(['earnings']),
|
|
756
|
-
'Comma-separated position fields to include, such as `earnings`.',
|
|
1114
|
+
'Comma-separated position fields to include, such as `earnings`. Earnings are unavailable when selecting a private Zone.',
|
|
757
1115
|
),
|
|
758
1116
|
limit: Schema.Limit,
|
|
759
1117
|
'valuation.currency': Schema.Denomination.check(
|
|
@@ -788,15 +1146,18 @@ export namespace schema {
|
|
|
788
1146
|
.check(z.describe('Page-level valuation rate provenance.'))
|
|
789
1147
|
|
|
790
1148
|
/** Paginated list of the account's earn vault positions. */
|
|
791
|
-
export const Response =
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1149
|
+
export const Response = OpenApi.component(
|
|
1150
|
+
z
|
|
1151
|
+
.strictObject({
|
|
1152
|
+
data: z
|
|
1153
|
+
.array(addressPosition)
|
|
1154
|
+
.check(z.describe('Vaults where the account holds earn shares.')),
|
|
1155
|
+
meta: z.optional(Meta),
|
|
1156
|
+
nextCursor: Schema.NextCursor,
|
|
1157
|
+
})
|
|
1158
|
+
.check(z.describe('A page of the account’s earn vault positions.')),
|
|
1159
|
+
'EarnAddressPositionList',
|
|
1160
|
+
)
|
|
800
1161
|
}
|
|
801
1162
|
|
|
802
1163
|
/** Schemas for the getEarnVault operation. */
|
|
@@ -820,9 +1181,103 @@ export namespace schema {
|
|
|
820
1181
|
.check(z.describe('Query parameters selecting one earn vault.'))
|
|
821
1182
|
|
|
822
1183
|
/** One compatible Earn vault resolved directly from current chain state. */
|
|
823
|
-
export const Response =
|
|
824
|
-
|
|
825
|
-
|
|
1184
|
+
export const Response = OpenApi.component(
|
|
1185
|
+
Schema.describe(
|
|
1186
|
+
z.extend(vault, { meta: z.optional(meta) }),
|
|
1187
|
+
'A compatible earn vault resolved from chain state, with rate provenance for its valued fields.',
|
|
1188
|
+
),
|
|
1189
|
+
'EarnVaultDetail',
|
|
1190
|
+
)
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/** Schemas for the getEarnVaultSharePrices operation. */
|
|
1194
|
+
export namespace getEarnVaultSharePrices {
|
|
1195
|
+
const timestamp = z.iso.datetime({ offset: true })
|
|
1196
|
+
|
|
1197
|
+
/** Path parameters identifying one Earn vault. */
|
|
1198
|
+
export const Params = z
|
|
1199
|
+
.strictObject({
|
|
1200
|
+
vaultId: Schema.address('0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a').check(
|
|
1201
|
+
z.describe('Earn vault contract address.'),
|
|
1202
|
+
),
|
|
1203
|
+
})
|
|
1204
|
+
.check(z.describe('Path parameters identifying one Earn vault share-price series.'))
|
|
1205
|
+
|
|
1206
|
+
/** Query parameters selecting a daily historical share-price range. */
|
|
1207
|
+
export const Query = z
|
|
1208
|
+
.strictObject({
|
|
1209
|
+
chainId: Schema.ChainIdQuery,
|
|
1210
|
+
from: timestamp.check(
|
|
1211
|
+
z.describe('First daily share-price observation, as an ISO 8601 timestamp.'),
|
|
1212
|
+
z.meta({ examples: ['2026-07-01T00:00:00.000Z'] }),
|
|
1213
|
+
),
|
|
1214
|
+
interval: z
|
|
1215
|
+
._default(z.literal(EarnSharePrices.interval), EarnSharePrices.interval)
|
|
1216
|
+
.check(
|
|
1217
|
+
z.describe('Time between share-price observations.'),
|
|
1218
|
+
z.meta({ examples: [EarnSharePrices.interval] }),
|
|
1219
|
+
),
|
|
1220
|
+
to: timestamp.check(
|
|
1221
|
+
z.describe('Last possible daily share-price observation, as an ISO 8601 timestamp.'),
|
|
1222
|
+
z.meta({ examples: ['2026-07-31T00:00:00.000Z'] }),
|
|
1223
|
+
),
|
|
1224
|
+
})
|
|
1225
|
+
.check(
|
|
1226
|
+
z.refine((query) => Date.parse(query.from) <= Date.parse(query.to), {
|
|
1227
|
+
error: '`from` must be before or equal to `to`.',
|
|
1228
|
+
path: ['from'],
|
|
1229
|
+
}),
|
|
1230
|
+
z.refine(
|
|
1231
|
+
(query) =>
|
|
1232
|
+
Math.floor((Date.parse(query.to) - Date.parse(query.from)) / Ttl.days(1)) + 1 <=
|
|
1233
|
+
EarnSharePrices.maxPoints,
|
|
1234
|
+
{
|
|
1235
|
+
error: `Share-price series are limited to ${EarnSharePrices.maxPoints} daily observations.`,
|
|
1236
|
+
path: ['to'],
|
|
1237
|
+
},
|
|
1238
|
+
),
|
|
1239
|
+
z.describe('Query parameters selecting an Earn vault share-price series.'),
|
|
1240
|
+
)
|
|
1241
|
+
|
|
1242
|
+
const Point = z
|
|
1243
|
+
.strictObject({
|
|
1244
|
+
sharePrice: value.check(
|
|
1245
|
+
z.describe('Assets returned for one whole Earn share at the observation block.'),
|
|
1246
|
+
),
|
|
1247
|
+
timestamp: z.iso
|
|
1248
|
+
.datetime()
|
|
1249
|
+
.check(
|
|
1250
|
+
z.describe('Requested daily observation timestamp.'),
|
|
1251
|
+
z.meta({ examples: ['2026-07-01T00:00:00.000Z'] }),
|
|
1252
|
+
),
|
|
1253
|
+
})
|
|
1254
|
+
.check(z.describe('One historical Earn vault share price.'))
|
|
1255
|
+
|
|
1256
|
+
/** Daily share prices for one Earn vault. */
|
|
1257
|
+
export const Response = OpenApi.component(
|
|
1258
|
+
z
|
|
1259
|
+
.strictObject({
|
|
1260
|
+
data: z.array(Point).check(
|
|
1261
|
+
z.describe('Daily Earn vault share prices.'),
|
|
1262
|
+
z.meta({
|
|
1263
|
+
examples: [
|
|
1264
|
+
[
|
|
1265
|
+
{
|
|
1266
|
+
sharePrice: {
|
|
1267
|
+
amount: '1000000',
|
|
1268
|
+
currency: 'USD',
|
|
1269
|
+
decimals: 6,
|
|
1270
|
+
formatted: '1',
|
|
1271
|
+
},
|
|
1272
|
+
timestamp: '2026-07-01T00:00:00.000Z',
|
|
1273
|
+
},
|
|
1274
|
+
],
|
|
1275
|
+
],
|
|
1276
|
+
}),
|
|
1277
|
+
),
|
|
1278
|
+
})
|
|
1279
|
+
.check(z.describe('Daily historical share prices for one Earn vault.')),
|
|
1280
|
+
'EarnVaultSharePriceList',
|
|
826
1281
|
)
|
|
827
1282
|
}
|
|
828
1283
|
|
|
@@ -852,6 +1307,10 @@ export namespace schema {
|
|
|
852
1307
|
z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
|
|
853
1308
|
),
|
|
854
1309
|
chainId: Schema.ChainIdQuery,
|
|
1310
|
+
include: Schema.includeQuery(
|
|
1311
|
+
z.enum(['apy', 'rewards', 'rewards.proof']),
|
|
1312
|
+
'Include wallet-specific APY or current reward state, optionally with the latest recovery proof.',
|
|
1313
|
+
),
|
|
855
1314
|
})
|
|
856
1315
|
.check(z.describe('Query parameters selecting an earn vault position.'))
|
|
857
1316
|
|
|
@@ -875,23 +1334,79 @@ export namespace schema {
|
|
|
875
1334
|
.check(z.describe('Indexed block used for a historical Earn position observation.'))
|
|
876
1335
|
|
|
877
1336
|
/** Current or historical asset and Earn-share state for one account in one vault. */
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
.
|
|
1337
|
+
const Rewards = z
|
|
1338
|
+
.strictObject({
|
|
1339
|
+
cumulativeEntitlement: Schema.DecimalString.check(
|
|
1340
|
+
z.describe('Cumulative EarnShare entitlement.'),
|
|
1341
|
+
),
|
|
1342
|
+
cumulativePaid: Schema.DecimalString.check(z.describe('Cumulative EarnShare paid.')),
|
|
1343
|
+
deferral: z
|
|
1344
|
+
.optional(z.string())
|
|
882
1345
|
.check(
|
|
883
|
-
z.describe('
|
|
884
|
-
z.meta({ examples: ['
|
|
1346
|
+
z.describe('Current payout delivery exception.'),
|
|
1347
|
+
z.meta({ examples: ['transfer_unavailable'] }),
|
|
885
1348
|
),
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
.
|
|
1349
|
+
pending: Schema.DecimalString.check(z.describe('EarnShare still owed.')),
|
|
1350
|
+
proof: z
|
|
1351
|
+
.optional(
|
|
1352
|
+
z.strictObject({
|
|
1353
|
+
cumulativeAmount: Schema.DecimalString,
|
|
1354
|
+
distributorAddress: Schema.Address,
|
|
1355
|
+
proof: z.array(Schema.Hash),
|
|
1356
|
+
rootVersion: Schema.DecimalString,
|
|
1357
|
+
statementHash: Schema.Hash,
|
|
1358
|
+
}),
|
|
1359
|
+
)
|
|
1360
|
+
.check(z.describe('Permissionless recovery proof against the confirmed root.')),
|
|
1361
|
+
})
|
|
1362
|
+
.check(z.describe('Current Earn reward state.'))
|
|
1363
|
+
|
|
1364
|
+
export const Response = OpenApi.component(
|
|
1365
|
+
Schema.describe(
|
|
1366
|
+
z.extend(position, {
|
|
1367
|
+
apy: z.optional(z.nullable(positionApy)).check(
|
|
889
1368
|
z.describe(
|
|
890
|
-
'
|
|
1369
|
+
'Wallet-specific effective APY when requested, or null when unavailable. Qualification comes from the latest delivered reward snapshot and may lag recent deposits or transfers.',
|
|
891
1370
|
),
|
|
1371
|
+
z.meta({
|
|
1372
|
+
examples: [
|
|
1373
|
+
{
|
|
1374
|
+
breakdown: [
|
|
1375
|
+
{
|
|
1376
|
+
assetAmount: {
|
|
1377
|
+
baseUnits: '25000000000',
|
|
1378
|
+
decimals: 6,
|
|
1379
|
+
formatted: '25000',
|
|
1380
|
+
},
|
|
1381
|
+
net: '0.07',
|
|
1382
|
+
type: 'boost',
|
|
1383
|
+
},
|
|
1384
|
+
],
|
|
1385
|
+
net: '0.07',
|
|
1386
|
+
},
|
|
1387
|
+
],
|
|
1388
|
+
}),
|
|
892
1389
|
),
|
|
893
|
-
|
|
894
|
-
|
|
1390
|
+
asOf: z
|
|
1391
|
+
.optional(asOf)
|
|
1392
|
+
.check(
|
|
1393
|
+
z.describe('Requested historical observation time, when supplied.'),
|
|
1394
|
+
z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
|
|
1395
|
+
),
|
|
1396
|
+
block: z
|
|
1397
|
+
.optional(Block)
|
|
1398
|
+
.check(
|
|
1399
|
+
z.describe(
|
|
1400
|
+
'Indexed block used for a historical Earn position observation, when requested.',
|
|
1401
|
+
),
|
|
1402
|
+
),
|
|
1403
|
+
rewards: z
|
|
1404
|
+
.optional(Rewards)
|
|
1405
|
+
.check(z.describe('Current reward state when requested through `include`.')),
|
|
1406
|
+
}),
|
|
1407
|
+
'Current or historical asset and earn-share balances, allowances, and asset value for an account in one earn vault.',
|
|
1408
|
+
),
|
|
1409
|
+
'EarnVaultPosition',
|
|
895
1410
|
)
|
|
896
1411
|
}
|
|
897
1412
|
|
|
@@ -916,9 +1431,12 @@ export namespace schema {
|
|
|
916
1431
|
.check(z.describe('Query parameters selecting an earn vault account.'))
|
|
917
1432
|
|
|
918
1433
|
/** Earnings for one account and period in one Earn vault. */
|
|
919
|
-
export const Response =
|
|
920
|
-
|
|
921
|
-
|
|
1434
|
+
export const Response = OpenApi.component(
|
|
1435
|
+
Schema.describe(
|
|
1436
|
+
earnings,
|
|
1437
|
+
'Indexed asset value and cost-basis-aware earnings for an account in one earn vault.',
|
|
1438
|
+
),
|
|
1439
|
+
'EarnVaultEarnings',
|
|
922
1440
|
)
|
|
923
1441
|
}
|
|
924
1442
|
}
|
|
@@ -927,6 +1445,113 @@ export namespace schema {
|
|
|
927
1445
|
export function earn(options: earn.Options = {}) {
|
|
928
1446
|
const oracle = options.fx?.oracle ?? FxOracle.ecb()
|
|
929
1447
|
return new Hono<App.Environment>()
|
|
1448
|
+
.post(
|
|
1449
|
+
'/v1/earn/rewards/eligibility',
|
|
1450
|
+
Auth.policy({ apiKey: { scopes: [Scope.wildcard] } }),
|
|
1451
|
+
OpenApi.validate('json', schema.registerRewardEligibility.Body, {
|
|
1452
|
+
code: 'body_invalid',
|
|
1453
|
+
message: 'Invalid reward eligibility registration',
|
|
1454
|
+
}),
|
|
1455
|
+
OpenApi.describeRoute({
|
|
1456
|
+
description: 'Registers a wallet and Earn vault association for reward eligibility.',
|
|
1457
|
+
hide: true,
|
|
1458
|
+
operationId: 'registerRewardEligibility',
|
|
1459
|
+
responses: OpenApi.responses({
|
|
1460
|
+
errors: {
|
|
1461
|
+
400: { codes: ['body_invalid', 'chain_id_unsupported'] },
|
|
1462
|
+
},
|
|
1463
|
+
success: {
|
|
1464
|
+
description: 'The persisted reward eligibility association.',
|
|
1465
|
+
schema: schema.registerRewardEligibility.Response,
|
|
1466
|
+
},
|
|
1467
|
+
}),
|
|
1468
|
+
summary: 'Register reward eligibility',
|
|
1469
|
+
tags: ['Earn'],
|
|
1470
|
+
}),
|
|
1471
|
+
async (c) => {
|
|
1472
|
+
if (Auth.narrowAccess) return Auth.accessError(c)
|
|
1473
|
+
if (OpenApi.narrowValidation)
|
|
1474
|
+
return OpenApi.validationError(c, {
|
|
1475
|
+
code: 'body_invalid',
|
|
1476
|
+
message: 'Invalid reward eligibility registration',
|
|
1477
|
+
})
|
|
1478
|
+
|
|
1479
|
+
const body = c.req.valid('json')
|
|
1480
|
+
if (!c.get('supportedChainIds').has(body.chainId))
|
|
1481
|
+
return Response.unsupportedChainId(c, body.chainId, c.get('supportedChainIds'))
|
|
1482
|
+
c.set('chainId', body.chainId)
|
|
1483
|
+
c.header('Cache-Control', Cache.policies.noStore)
|
|
1484
|
+
const result = await RewardEligibilityAssociations.upsert(Db.get(c.get('db')), {
|
|
1485
|
+
...body,
|
|
1486
|
+
})
|
|
1487
|
+
return c.json(
|
|
1488
|
+
Response.validated(schema.registerRewardEligibility.Response, {
|
|
1489
|
+
association: toRewardEligibilityAssociation(result.record),
|
|
1490
|
+
created: result.created,
|
|
1491
|
+
}),
|
|
1492
|
+
200,
|
|
1493
|
+
)
|
|
1494
|
+
},
|
|
1495
|
+
)
|
|
1496
|
+
.get(
|
|
1497
|
+
'/v1/earn/rewards/eligibility',
|
|
1498
|
+
Auth.policy({ apiKey: { scopes: ['rewards:read'] } }),
|
|
1499
|
+
OpenApi.validate('query', schema.getRewardEligibility.Query, {
|
|
1500
|
+
code: 'query_invalid',
|
|
1501
|
+
message: 'Invalid reward eligibility selector',
|
|
1502
|
+
}),
|
|
1503
|
+
OpenApi.describeRoute({
|
|
1504
|
+
description:
|
|
1505
|
+
'Lists reward eligibility associations for one Earn vault at a fixed high-water checkpoint.',
|
|
1506
|
+
hide: true,
|
|
1507
|
+
operationId: 'getRewardEligibility',
|
|
1508
|
+
responses: OpenApi.responses({
|
|
1509
|
+
success: {
|
|
1510
|
+
description: 'A checkpointed page of reward eligibility associations.',
|
|
1511
|
+
schema: schema.getRewardEligibility.Response,
|
|
1512
|
+
},
|
|
1513
|
+
}),
|
|
1514
|
+
summary: 'List reward eligibility',
|
|
1515
|
+
tags: ['Earn'],
|
|
1516
|
+
}),
|
|
1517
|
+
async (c) => {
|
|
1518
|
+
if (Auth.narrowAccess) return Auth.accessError(c)
|
|
1519
|
+
if (OpenApi.narrowValidation)
|
|
1520
|
+
return OpenApi.validationError(c, {
|
|
1521
|
+
code: 'query_invalid',
|
|
1522
|
+
message: 'Invalid reward eligibility selector',
|
|
1523
|
+
})
|
|
1524
|
+
|
|
1525
|
+
const query = c.req.valid('query')
|
|
1526
|
+
const zone = c.get('zones').get(query.chainId)
|
|
1527
|
+
const sourceChainId = zone ? zone.sourceId : query.chainId
|
|
1528
|
+
const principal = Auth.getPrincipal(c)
|
|
1529
|
+
if (
|
|
1530
|
+
principal?.type === 'api_key' &&
|
|
1531
|
+
principal.environment === 'sandbox' &&
|
|
1532
|
+
(sourceChainId === undefined || Viem.isMainnet(sourceChainId))
|
|
1533
|
+
)
|
|
1534
|
+
return Response.error(c, {
|
|
1535
|
+
code: 'api_key_forbidden',
|
|
1536
|
+
message: 'Sandbox API keys only support testnet.',
|
|
1537
|
+
status: 403,
|
|
1538
|
+
})
|
|
1539
|
+
|
|
1540
|
+
c.header('Cache-Control', Cache.policies.noStore)
|
|
1541
|
+
const page = await RewardEligibilityAssociations.list(Db.get(c.get('db')), {
|
|
1542
|
+
...query,
|
|
1543
|
+
})
|
|
1544
|
+
return c.json(
|
|
1545
|
+
Response.validated(schema.getRewardEligibility.Response, {
|
|
1546
|
+
chainId: query.chainId,
|
|
1547
|
+
data: page.data.map((association) => association.walletAddress),
|
|
1548
|
+
nextCursor: page.nextCursor,
|
|
1549
|
+
vaultAddress: query.vaultAddress,
|
|
1550
|
+
}),
|
|
1551
|
+
200,
|
|
1552
|
+
)
|
|
1553
|
+
},
|
|
1554
|
+
)
|
|
930
1555
|
.get(
|
|
931
1556
|
'/v1/earn/vaults',
|
|
932
1557
|
Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
|
|
@@ -939,7 +1564,12 @@ export function earn(options: earn.Options = {}) {
|
|
|
939
1564
|
'Lists compatible earn vaults discovered from deployment events and resolved from current chain state.',
|
|
940
1565
|
operationId: 'getEarnVaults',
|
|
941
1566
|
responses: OpenApi.responses({
|
|
942
|
-
errors: {
|
|
1567
|
+
errors: {
|
|
1568
|
+
400: {
|
|
1569
|
+
codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
|
|
1570
|
+
},
|
|
1571
|
+
502: 'Could not read earn deployment or vault data.',
|
|
1572
|
+
},
|
|
943
1573
|
success: {
|
|
944
1574
|
description: 'A page of compatible deployed earn vaults.',
|
|
945
1575
|
schema: schema.getEarnVaults.Response,
|
|
@@ -953,10 +1583,22 @@ export function earn(options: earn.Options = {}) {
|
|
|
953
1583
|
Cache.response<App.Environment>({
|
|
954
1584
|
cacheControl: Cache.policies.state,
|
|
955
1585
|
key: (c) => vaultCacheKey(c, schema.getEarnVaults.Query),
|
|
956
|
-
name: 'tempo-api:earn-vaults:
|
|
1586
|
+
name: 'tempo-api:earn-vaults:v5',
|
|
957
1587
|
}),
|
|
958
1588
|
async (c) => {
|
|
959
1589
|
if (Auth.narrowAccess) return Auth.paidAccessError(c)
|
|
1590
|
+
if (OpenApi.narrowValidation)
|
|
1591
|
+
return Response.error(c, {
|
|
1592
|
+
code: 'chain_id_invalid',
|
|
1593
|
+
message: 'Invalid chain id',
|
|
1594
|
+
status: 400,
|
|
1595
|
+
})
|
|
1596
|
+
if (OpenApi.narrowValidation)
|
|
1597
|
+
return Response.error(c, {
|
|
1598
|
+
code: 'chain_id_unsupported',
|
|
1599
|
+
message: 'Unsupported chain id',
|
|
1600
|
+
status: 400,
|
|
1601
|
+
})
|
|
960
1602
|
if (OpenApi.narrowValidation)
|
|
961
1603
|
return OpenApi.validationError(c, {
|
|
962
1604
|
code: 'query_invalid',
|
|
@@ -985,7 +1627,12 @@ export function earn(options: earn.Options = {}) {
|
|
|
985
1627
|
'Lists registry-curated earn vaults after resolving their current onchain configuration.',
|
|
986
1628
|
operationId: 'getVerifiedEarnVaults',
|
|
987
1629
|
responses: OpenApi.responses({
|
|
988
|
-
errors: {
|
|
1630
|
+
errors: {
|
|
1631
|
+
400: {
|
|
1632
|
+
codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
|
|
1633
|
+
},
|
|
1634
|
+
502: 'Could not read curated earn registry or vault data.',
|
|
1635
|
+
},
|
|
989
1636
|
success: {
|
|
990
1637
|
description: 'A page of registry-curated earn vaults.',
|
|
991
1638
|
schema: schema.getVerifiedEarnVaults.Response,
|
|
@@ -1001,6 +1648,18 @@ export function earn(options: earn.Options = {}) {
|
|
|
1001
1648
|
}),
|
|
1002
1649
|
async (c) => {
|
|
1003
1650
|
if (Auth.narrowAccess) return Auth.paidAccessError(c)
|
|
1651
|
+
if (OpenApi.narrowValidation)
|
|
1652
|
+
return Response.error(c, {
|
|
1653
|
+
code: 'chain_id_invalid',
|
|
1654
|
+
message: 'Invalid chain id',
|
|
1655
|
+
status: 400,
|
|
1656
|
+
})
|
|
1657
|
+
if (OpenApi.narrowValidation)
|
|
1658
|
+
return Response.error(c, {
|
|
1659
|
+
code: 'chain_id_unsupported',
|
|
1660
|
+
message: 'Unsupported chain id',
|
|
1661
|
+
status: 400,
|
|
1662
|
+
})
|
|
1004
1663
|
if (OpenApi.narrowValidation)
|
|
1005
1664
|
return OpenApi.validationError(c, {
|
|
1006
1665
|
code: 'query_invalid',
|
|
@@ -1010,7 +1669,11 @@ export function earn(options: earn.Options = {}) {
|
|
|
1010
1669
|
const query = c.req.valid('query')
|
|
1011
1670
|
try {
|
|
1012
1671
|
const chainId = query.chainId ?? c.get('chainId')
|
|
1013
|
-
const data = await listVerifiedVaults(c, {
|
|
1672
|
+
const data = await listVerifiedVaults(c, {
|
|
1673
|
+
...query,
|
|
1674
|
+
chainId,
|
|
1675
|
+
oracle,
|
|
1676
|
+
})
|
|
1014
1677
|
return c.json(Response.validated(schema.getVerifiedEarnVaults.Response, data), 200)
|
|
1015
1678
|
} catch (cause) {
|
|
1016
1679
|
return Response.upstream(c, cause)
|
|
@@ -1030,7 +1693,7 @@ export function earn(options: earn.Options = {}) {
|
|
|
1030
1693
|
}),
|
|
1031
1694
|
OpenApi.describeRoute({
|
|
1032
1695
|
description:
|
|
1033
|
-
'Lists every earn vault where an account currently holds shares
|
|
1696
|
+
'Lists every earn vault where an account currently holds shares on the selected Tempo chain or private Zone. Lifetime cash flows are available on Tempo chains.',
|
|
1034
1697
|
operationId: 'getEarnAddressPositions',
|
|
1035
1698
|
responses: OpenApi.responses({
|
|
1036
1699
|
errors: {
|
|
@@ -1093,6 +1756,109 @@ export function earn(options: earn.Options = {}) {
|
|
|
1093
1756
|
} catch (cause) {
|
|
1094
1757
|
if (cause instanceof Valuation.UnsupportedDenominationError)
|
|
1095
1758
|
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
1759
|
+
if (cause instanceof ZoneEarningsUnsupportedError)
|
|
1760
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
1761
|
+
return Response.upstream(c, cause)
|
|
1762
|
+
}
|
|
1763
|
+
},
|
|
1764
|
+
)
|
|
1765
|
+
.get(
|
|
1766
|
+
'/v1/earn/vaults/:vaultId/share-prices',
|
|
1767
|
+
Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
|
|
1768
|
+
OpenApi.validate('param', schema.getEarnVaultSharePrices.Params, {
|
|
1769
|
+
code: 'vault_id_invalid',
|
|
1770
|
+
message: 'Invalid vault id',
|
|
1771
|
+
}),
|
|
1772
|
+
OpenApi.validate('query', schema.getEarnVaultSharePrices.Query, {
|
|
1773
|
+
code: 'query_invalid',
|
|
1774
|
+
message: 'Invalid query parameters',
|
|
1775
|
+
}),
|
|
1776
|
+
OpenApi.describeRoute({
|
|
1777
|
+
description: 'Lists daily historical share prices for one earn vault.',
|
|
1778
|
+
operationId: 'getEarnVaultSharePrices',
|
|
1779
|
+
responses: OpenApi.responses({
|
|
1780
|
+
errors: {
|
|
1781
|
+
400: {
|
|
1782
|
+
codes: [
|
|
1783
|
+
'chain_id_invalid',
|
|
1784
|
+
'chain_id_unsupported',
|
|
1785
|
+
'query_invalid',
|
|
1786
|
+
'vault_id_invalid',
|
|
1787
|
+
],
|
|
1788
|
+
},
|
|
1789
|
+
404: {
|
|
1790
|
+
codes: ['earn_vault_not_found'],
|
|
1791
|
+
description: 'No compatible earn vault was found at the supplied vault address.',
|
|
1792
|
+
},
|
|
1793
|
+
502: 'Could not read historical earn vault share prices.',
|
|
1794
|
+
},
|
|
1795
|
+
success: {
|
|
1796
|
+
description: 'Daily historical share prices for one earn vault.',
|
|
1797
|
+
schema: schema.getEarnVaultSharePrices.Response,
|
|
1798
|
+
},
|
|
1799
|
+
}),
|
|
1800
|
+
summary: 'List share prices',
|
|
1801
|
+
tags: ['Earn'],
|
|
1802
|
+
}),
|
|
1803
|
+
Cache.response<App.Environment>({
|
|
1804
|
+
cacheControl: Cache.policies.state,
|
|
1805
|
+
key: (c) => Cache.urlKey(c, schema.getEarnVaultSharePrices.Query),
|
|
1806
|
+
name: 'tempo-api:earn-vault-share-prices:v1',
|
|
1807
|
+
}),
|
|
1808
|
+
async (c) => {
|
|
1809
|
+
if (Auth.narrowAccess) return Auth.paidAccessError(c)
|
|
1810
|
+
if (OpenApi.narrowValidation)
|
|
1811
|
+
return Response.error(c, {
|
|
1812
|
+
code: 'chain_id_invalid',
|
|
1813
|
+
message: 'Invalid chain id',
|
|
1814
|
+
status: 400,
|
|
1815
|
+
})
|
|
1816
|
+
if (OpenApi.narrowValidation)
|
|
1817
|
+
return Response.error(c, {
|
|
1818
|
+
code: 'chain_id_unsupported',
|
|
1819
|
+
message: 'Unsupported chain id',
|
|
1820
|
+
status: 400,
|
|
1821
|
+
})
|
|
1822
|
+
if (OpenApi.narrowValidation)
|
|
1823
|
+
return OpenApi.validationError(c, {
|
|
1824
|
+
code: 'vault_id_invalid',
|
|
1825
|
+
message: 'Invalid vault id',
|
|
1826
|
+
})
|
|
1827
|
+
if (OpenApi.narrowValidation)
|
|
1828
|
+
return OpenApi.validationError(c, {
|
|
1829
|
+
code: 'query_invalid',
|
|
1830
|
+
message: 'Invalid query parameters',
|
|
1831
|
+
})
|
|
1832
|
+
|
|
1833
|
+
const { vaultId } = c.req.valid('param')
|
|
1834
|
+
const query = c.req.valid('query')
|
|
1835
|
+
const chainId = query.chainId ?? c.get('chainId')
|
|
1836
|
+
try {
|
|
1837
|
+
const discovery = await resolveSharePriceVaultDiscovery(c, {
|
|
1838
|
+
chainId,
|
|
1839
|
+
vaultAddress: vaultId,
|
|
1840
|
+
})
|
|
1841
|
+
if (!discovery)
|
|
1842
|
+
return Response.error(c, {
|
|
1843
|
+
code: 'earn_vault_not_found',
|
|
1844
|
+
message: 'Earn vault not found',
|
|
1845
|
+
status: 404,
|
|
1846
|
+
})
|
|
1847
|
+
const data = await getVaultSharePrices(c, {
|
|
1848
|
+
...query,
|
|
1849
|
+
chainId,
|
|
1850
|
+
discovery,
|
|
1851
|
+
vault: vaultId,
|
|
1852
|
+
})
|
|
1853
|
+
return c.json(Response.validated(schema.getEarnVaultSharePrices.Response, { data }), 200)
|
|
1854
|
+
} catch (cause) {
|
|
1855
|
+
if (
|
|
1856
|
+
cause instanceof EarnSharePrices.IndexedBlockNotFoundError ||
|
|
1857
|
+
cause instanceof EarnSharePrices.IndexedCoverageError
|
|
1858
|
+
)
|
|
1859
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
1860
|
+
const failure = sharePriceProviderFailure({ cause, chainId })
|
|
1861
|
+
if (failure) c.set('providerFailure', failure)
|
|
1096
1862
|
return Response.upstream(c, cause)
|
|
1097
1863
|
}
|
|
1098
1864
|
},
|
|
@@ -1110,7 +1876,7 @@ export function earn(options: earn.Options = {}) {
|
|
|
1110
1876
|
}),
|
|
1111
1877
|
OpenApi.describeRoute({
|
|
1112
1878
|
description:
|
|
1113
|
-
'Gets an account’s
|
|
1879
|
+
'Gets an account’s direct or Zone-routed balances and asset value for one earn vault, optionally at an ISO 8601 timestamp.',
|
|
1114
1880
|
operationId: 'getEarnVaultPosition',
|
|
1115
1881
|
responses: OpenApi.responses({
|
|
1116
1882
|
errors: {
|
|
@@ -1140,7 +1906,7 @@ export function earn(options: earn.Options = {}) {
|
|
|
1140
1906
|
Cache.response<App.Environment>({
|
|
1141
1907
|
cacheControl: Cache.policies.noStore,
|
|
1142
1908
|
key: (c) => Cache.urlKey(c, schema.getEarnVaultPosition.Query),
|
|
1143
|
-
name: 'tempo-api:earn-vault-positions:
|
|
1909
|
+
name: 'tempo-api:earn-vault-positions:v3',
|
|
1144
1910
|
}),
|
|
1145
1911
|
async (c) => {
|
|
1146
1912
|
if (Auth.narrowAccess) return Auth.paidAccessError(c)
|
|
@@ -1170,85 +1936,133 @@ export function earn(options: earn.Options = {}) {
|
|
|
1170
1936
|
const { address, vaultId } = c.req.valid('param')
|
|
1171
1937
|
const query = c.req.valid('query')
|
|
1172
1938
|
const chainId = query.chainId ?? c.get('chainId')
|
|
1173
|
-
|
|
1939
|
+
if (query.asOf && query.include.length > 0)
|
|
1940
|
+
return Response.error(c, {
|
|
1941
|
+
code: 'query_invalid',
|
|
1942
|
+
message: 'Historical position enrichments are not available.',
|
|
1943
|
+
status: 400,
|
|
1944
|
+
})
|
|
1945
|
+
if (c.get('zones').has(chainId)) Cache.setPolicy(c, Cache.policies.noStore)
|
|
1174
1946
|
try {
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1947
|
+
const position = await getVaultPosition(c, {
|
|
1948
|
+
account: address,
|
|
1949
|
+
asOf: query.asOf,
|
|
1950
|
+
chainId,
|
|
1951
|
+
vault: vaultId,
|
|
1952
|
+
})
|
|
1953
|
+
const apy = query.include.includes('apy')
|
|
1954
|
+
? await resolvePositionApy(c, {
|
|
1955
|
+
chainId,
|
|
1956
|
+
recipient: address,
|
|
1957
|
+
shareBalance: position.shareBalance,
|
|
1958
|
+
value: position.value,
|
|
1959
|
+
vault: vaultId,
|
|
1960
|
+
})
|
|
1961
|
+
: undefined
|
|
1962
|
+
const rewards = query.include.some((value) => value.startsWith('rewards'))
|
|
1963
|
+
? await RewardRead.recipient({
|
|
1964
|
+
chainId,
|
|
1965
|
+
db: c.get('db'),
|
|
1966
|
+
getClient: c.get('getClient'),
|
|
1967
|
+
recipient: address,
|
|
1968
|
+
vaultAddress: vaultId,
|
|
1969
|
+
})
|
|
1970
|
+
: undefined
|
|
1971
|
+
return c.json(
|
|
1972
|
+
Response.validated(schema.getEarnVaultPosition.Response, {
|
|
1181
1973
|
account: address,
|
|
1182
|
-
...(
|
|
1183
|
-
|
|
1974
|
+
...(query.include.includes('apy') ? { apy } : {}),
|
|
1975
|
+
assetAllowance: position.assetAllowance.toString(),
|
|
1976
|
+
assetBalance: position.assetBalance.toString(),
|
|
1977
|
+
assetToken: position.assetToken,
|
|
1978
|
+
chainId,
|
|
1979
|
+
asOf: query.asOf,
|
|
1980
|
+
block: position.block,
|
|
1981
|
+
id: address,
|
|
1982
|
+
...(rewards
|
|
1983
|
+
? {
|
|
1984
|
+
rewards: query.include.includes('rewards.proof')
|
|
1985
|
+
? rewards
|
|
1986
|
+
: { ...rewards, proof: undefined },
|
|
1987
|
+
}
|
|
1988
|
+
: {}),
|
|
1989
|
+
shareAllowance: position.shareAllowance.toString(),
|
|
1990
|
+
shareBalance: position.shareBalance.toString(),
|
|
1991
|
+
shareToken: position.shareToken,
|
|
1992
|
+
value: position.value.toString(),
|
|
1993
|
+
valueToken: position.valueToken,
|
|
1994
|
+
}),
|
|
1995
|
+
200,
|
|
1996
|
+
)
|
|
1997
|
+
} catch (cause) {
|
|
1998
|
+
if (cause instanceof IndexedBlockNotFoundError || cause instanceof IndexedCoverageError)
|
|
1999
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
2000
|
+
if (cause instanceof ZoneHistoricalAlignmentError)
|
|
2001
|
+
return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
|
|
2002
|
+
if (cause instanceof EarnVaults.NotFoundError)
|
|
2003
|
+
return Response.error(c, {
|
|
2004
|
+
code: 'earn_vault_not_found',
|
|
2005
|
+
message: 'Earn vault not found',
|
|
2006
|
+
status: 404,
|
|
1184
2007
|
})
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
account: address,
|
|
1188
|
-
assetAllowance: position.assetAllowance.toString(),
|
|
1189
|
-
assetBalance: position.assetBalance.toString(),
|
|
1190
|
-
assetToken: position.assetToken,
|
|
1191
|
-
asOf: query.asOf,
|
|
1192
|
-
block,
|
|
1193
|
-
id: address,
|
|
1194
|
-
shareAllowance: position.shareAllowance.toString(),
|
|
1195
|
-
shareBalance: position.shareBalance.toString(),
|
|
1196
|
-
shareToken: position.shareToken,
|
|
1197
|
-
value: position.value.toString(),
|
|
1198
|
-
}),
|
|
1199
|
-
200,
|
|
1200
|
-
)
|
|
1201
|
-
} catch (cause) {
|
|
1202
|
-
if (block) {
|
|
1203
|
-
try {
|
|
1204
|
-
// These immutable bindings establish historical vault identity
|
|
1205
|
-
// without repeating fallible token or redemption subreads.
|
|
1206
|
-
const [asset, shareToken] = await Promise.all([
|
|
1207
|
-
client.readContract({
|
|
1208
|
-
abi: Abis.earnVault,
|
|
1209
|
-
address: vaultId,
|
|
1210
|
-
blockNumber: BigInt(block.number),
|
|
1211
|
-
functionName: 'asset',
|
|
1212
|
-
}),
|
|
1213
|
-
client.readContract({
|
|
1214
|
-
abi: Abis.earnVault,
|
|
1215
|
-
address: vaultId,
|
|
1216
|
-
blockNumber: BigInt(block.number),
|
|
1217
|
-
functionName: 'earnShare',
|
|
1218
|
-
}),
|
|
1219
|
-
])
|
|
1220
|
-
if (asset === zeroAddress || shareToken === zeroAddress)
|
|
1221
|
-
return Response.error(c, {
|
|
1222
|
-
code: 'earn_vault_not_found',
|
|
1223
|
-
message: 'Earn vault not found',
|
|
1224
|
-
status: 404,
|
|
1225
|
-
})
|
|
1226
|
-
} catch (identityCause) {
|
|
1227
|
-
if (isIncompatible(identityCause))
|
|
1228
|
-
return Response.error(c, {
|
|
1229
|
-
code: 'earn_vault_not_found',
|
|
1230
|
-
message: 'Earn vault not found',
|
|
1231
|
-
status: 404,
|
|
1232
|
-
})
|
|
1233
|
-
return Response.upstream(c, identityCause)
|
|
1234
|
-
}
|
|
1235
|
-
return Response.upstream(c, cause)
|
|
1236
|
-
}
|
|
2008
|
+
const zone = c.get('zones').get(chainId)
|
|
2009
|
+
if (query.asOf && !zone) {
|
|
1237
2010
|
try {
|
|
1238
|
-
await
|
|
1239
|
-
|
|
1240
|
-
|
|
2011
|
+
const block = await getIndexedBlockAtOrBefore(c.get('getTidx')(chainId), query.asOf)
|
|
2012
|
+
const client = c.get('getClient')(chainId)
|
|
2013
|
+
// These immutable bindings establish historical vault identity
|
|
2014
|
+
// without repeating fallible token or redemption subreads.
|
|
2015
|
+
const [asset, shareToken] = await Promise.all([
|
|
2016
|
+
client.readContract({
|
|
2017
|
+
abi: Abis.earnVault,
|
|
2018
|
+
address: vaultId,
|
|
2019
|
+
blockNumber: BigInt(block.number),
|
|
2020
|
+
functionName: 'asset',
|
|
2021
|
+
}),
|
|
2022
|
+
client.readContract({
|
|
2023
|
+
abi: Abis.earnVault,
|
|
2024
|
+
address: vaultId,
|
|
2025
|
+
blockNumber: BigInt(block.number),
|
|
2026
|
+
functionName: 'earnShare',
|
|
2027
|
+
}),
|
|
2028
|
+
])
|
|
2029
|
+
if (asset === zeroAddress || shareToken === zeroAddress)
|
|
2030
|
+
return Response.error(c, {
|
|
2031
|
+
code: 'earn_vault_not_found',
|
|
2032
|
+
message: 'Earn vault not found',
|
|
2033
|
+
status: 404,
|
|
2034
|
+
})
|
|
2035
|
+
} catch (identityCause) {
|
|
2036
|
+
if (
|
|
2037
|
+
identityCause instanceof IndexedBlockNotFoundError ||
|
|
2038
|
+
identityCause instanceof IndexedCoverageError
|
|
2039
|
+
)
|
|
2040
|
+
return Response.error(c, {
|
|
2041
|
+
code: 'query_invalid',
|
|
2042
|
+
message: identityCause.message,
|
|
2043
|
+
status: 400,
|
|
2044
|
+
})
|
|
2045
|
+
if (isIncompatible(identityCause))
|
|
1241
2046
|
return Response.error(c, {
|
|
1242
2047
|
code: 'earn_vault_not_found',
|
|
1243
2048
|
message: 'Earn vault not found',
|
|
1244
2049
|
status: 404,
|
|
1245
2050
|
})
|
|
2051
|
+
return Response.upstream(c, identityCause)
|
|
1246
2052
|
}
|
|
1247
2053
|
return Response.upstream(c, cause)
|
|
1248
2054
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
2055
|
+
if (zone) return Response.upstream(c, cause)
|
|
2056
|
+
try {
|
|
2057
|
+
await resolveVaultDiscovery(c, { chainId, include: [], vaultAddress: vaultId })
|
|
2058
|
+
} catch (vaultCause) {
|
|
2059
|
+
if (isIncompatible(vaultCause))
|
|
2060
|
+
return Response.error(c, {
|
|
2061
|
+
code: 'earn_vault_not_found',
|
|
2062
|
+
message: 'Earn vault not found',
|
|
2063
|
+
status: 404,
|
|
2064
|
+
})
|
|
2065
|
+
}
|
|
1252
2066
|
return Response.upstream(c, cause)
|
|
1253
2067
|
}
|
|
1254
2068
|
},
|
|
@@ -1365,6 +2179,14 @@ export function earn(options: earn.Options = {}) {
|
|
|
1365
2179
|
operationId: 'getEarnVault',
|
|
1366
2180
|
responses: OpenApi.responses({
|
|
1367
2181
|
errors: {
|
|
2182
|
+
400: {
|
|
2183
|
+
codes: [
|
|
2184
|
+
'chain_id_invalid',
|
|
2185
|
+
'chain_id_unsupported',
|
|
2186
|
+
'query_invalid',
|
|
2187
|
+
'vault_id_invalid',
|
|
2188
|
+
],
|
|
2189
|
+
},
|
|
1368
2190
|
404: {
|
|
1369
2191
|
codes: ['earn_vault_not_found'],
|
|
1370
2192
|
description: 'No compatible earn vault was found at this address.',
|
|
@@ -1386,6 +2208,18 @@ export function earn(options: earn.Options = {}) {
|
|
|
1386
2208
|
}),
|
|
1387
2209
|
async (c) => {
|
|
1388
2210
|
if (Auth.narrowAccess) return Auth.paidAccessError(c)
|
|
2211
|
+
if (OpenApi.narrowValidation)
|
|
2212
|
+
return Response.error(c, {
|
|
2213
|
+
code: 'chain_id_invalid',
|
|
2214
|
+
message: 'Invalid chain id',
|
|
2215
|
+
status: 400,
|
|
2216
|
+
})
|
|
2217
|
+
if (OpenApi.narrowValidation)
|
|
2218
|
+
return Response.error(c, {
|
|
2219
|
+
code: 'chain_id_unsupported',
|
|
2220
|
+
message: 'Unsupported chain id',
|
|
2221
|
+
status: 400,
|
|
2222
|
+
})
|
|
1389
2223
|
if (OpenApi.narrowValidation)
|
|
1390
2224
|
return OpenApi.validationError(c, {
|
|
1391
2225
|
code: 'vault_id_invalid',
|
|
@@ -1437,7 +2271,10 @@ export async function getVaultEarnings(
|
|
|
1437
2271
|
) {
|
|
1438
2272
|
const client = c.get('getClient')(options.chainId)
|
|
1439
2273
|
const tidx = c.get('getTidx')(options.chainId)
|
|
1440
|
-
const block = await
|
|
2274
|
+
const [block, rewardTransfer] = await Promise.all([
|
|
2275
|
+
getLatestIndexedBlock(tidx),
|
|
2276
|
+
getRewardTransferPredicate(c, options),
|
|
2277
|
+
])
|
|
1441
2278
|
const blockNumber = block.number
|
|
1442
2279
|
if (options.period === '30d')
|
|
1443
2280
|
return getWindowVaultEarnings(c, {
|
|
@@ -1445,6 +2282,7 @@ export async function getVaultEarnings(
|
|
|
1445
2282
|
blockNumber,
|
|
1446
2283
|
chainId: options.chainId,
|
|
1447
2284
|
period: options.period,
|
|
2285
|
+
rewardTransfer,
|
|
1448
2286
|
timestamp: block.timestamp,
|
|
1449
2287
|
vault: options.vault,
|
|
1450
2288
|
})
|
|
@@ -1465,6 +2303,7 @@ export async function getVaultEarnings(
|
|
|
1465
2303
|
const activeCostBasis = await getActiveCostBasis(tidx, {
|
|
1466
2304
|
account: options.account,
|
|
1467
2305
|
blockNumber,
|
|
2306
|
+
rewardTransfer,
|
|
1468
2307
|
shareBalance: current.shareBalance,
|
|
1469
2308
|
shareToken: current.shareToken,
|
|
1470
2309
|
vault: options.vault,
|
|
@@ -1488,6 +2327,7 @@ export async function getVaultEarnings(
|
|
|
1488
2327
|
const externalShareTransfer = await hasExternalShareTransfer(tidx, {
|
|
1489
2328
|
account: options.account,
|
|
1490
2329
|
blockNumber,
|
|
2330
|
+
rewardTransfer,
|
|
1491
2331
|
shareToken: current.shareToken,
|
|
1492
2332
|
startBlockNumber: beforeFirstBlockNumber,
|
|
1493
2333
|
vault: options.vault,
|
|
@@ -1536,6 +2376,7 @@ async function getWindowVaultEarnings(
|
|
|
1536
2376
|
hasExternalShareTransfer(tidx, {
|
|
1537
2377
|
account: options.account,
|
|
1538
2378
|
blockNumber: options.blockNumber,
|
|
2379
|
+
rewardTransfer: options.rewardTransfer,
|
|
1539
2380
|
shareToken: current.shareToken,
|
|
1540
2381
|
startBlockNumber,
|
|
1541
2382
|
vault: options.vault,
|
|
@@ -1600,6 +2441,8 @@ declare namespace getWindowVaultEarnings {
|
|
|
1600
2441
|
chainId: z.output<typeof Schema.ChainId>
|
|
1601
2442
|
/** Trailing earnings period. */
|
|
1602
2443
|
period: '30d'
|
|
2444
|
+
/** SQL predicate recognizing paid rewards in the share-transfer history. */
|
|
2445
|
+
rewardTransfer: string
|
|
1603
2446
|
/** Latest indexed block timestamp. */
|
|
1604
2447
|
timestamp: string
|
|
1605
2448
|
/** Earn vault contract address. */
|
|
@@ -1981,6 +2824,39 @@ declare namespace getWindowShareState {
|
|
|
1981
2824
|
}
|
|
1982
2825
|
}
|
|
1983
2826
|
|
|
2827
|
+
/** Builds a share-transfer predicate for the vault's verified reward distributors. */
|
|
2828
|
+
async function getRewardTransferPredicate(
|
|
2829
|
+
c: Context<App.Environment>,
|
|
2830
|
+
options: Pick<getVaultEarnings.Options, 'chainId' | 'vault'>,
|
|
2831
|
+
) {
|
|
2832
|
+
const db = Db.get(c.get('db'))
|
|
2833
|
+
const campaign = await RewardCampaigns.get(db, {
|
|
2834
|
+
chainId: options.chainId,
|
|
2835
|
+
vaultAddress: options.vault,
|
|
2836
|
+
})
|
|
2837
|
+
if (!campaign) return '0'
|
|
2838
|
+
const distributors = await RewardCampaignDistributors.list(db, {
|
|
2839
|
+
chainId: options.chainId,
|
|
2840
|
+
vaultAddress: options.vault,
|
|
2841
|
+
})
|
|
2842
|
+
if (distributors.length === 0) return '0'
|
|
2843
|
+
const addresses = distributors
|
|
2844
|
+
.map(({ distributorAddress }) => Schema.Address.parse(distributorAddress))
|
|
2845
|
+
.map((address) => `'${address}'`)
|
|
2846
|
+
.join(', ')
|
|
2847
|
+
const shareToken = Schema.Address.parse(campaign.earnShareAddress)
|
|
2848
|
+
|
|
2849
|
+
// Batch rewards have no per-recipient event; exclude treasury returns instead. Qualify the filter so TIDX does not apply it to other event CTEs.
|
|
2850
|
+
return `
|
|
2851
|
+
token = '${shareToken}'
|
|
2852
|
+
AND "from" IN (${addresses})
|
|
2853
|
+
AND tx_hash NOT IN (
|
|
2854
|
+
SELECT returned.tx_hash FROM UnspentReturned AS returned
|
|
2855
|
+
WHERE returned.address IN (${addresses})
|
|
2856
|
+
)
|
|
2857
|
+
`
|
|
2858
|
+
}
|
|
2859
|
+
|
|
1984
2860
|
/** Returns whether an account sent or received Earn shares outside known vault flows. */
|
|
1985
2861
|
async function hasExternalShareTransfer(
|
|
1986
2862
|
tidx: Tidx.Client,
|
|
@@ -1995,6 +2871,7 @@ async function hasExternalShareTransfer(
|
|
|
1995
2871
|
SELECT count()
|
|
1996
2872
|
FROM token_transfers
|
|
1997
2873
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
2874
|
+
AND toUInt256(amount) > 0
|
|
1998
2875
|
AND block_num > ${options.startBlockNumber}
|
|
1999
2876
|
AND block_num <= ${options.blockNumber}
|
|
2000
2877
|
AND (
|
|
@@ -2003,6 +2880,7 @@ async function hasExternalShareTransfer(
|
|
|
2003
2880
|
"to" = '${options.account}'
|
|
2004
2881
|
AND "from" != '${zeroAddress}'
|
|
2005
2882
|
AND "from" != '${options.vault}'
|
|
2883
|
+
AND NOT (${options.rewardTransfer})
|
|
2006
2884
|
)
|
|
2007
2885
|
)
|
|
2008
2886
|
) + (
|
|
@@ -2011,6 +2889,7 @@ async function hasExternalShareTransfer(
|
|
|
2011
2889
|
SELECT tx_hash, toUInt256(amount) AS amount, count() AS transfer_count
|
|
2012
2890
|
FROM token_transfers
|
|
2013
2891
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
2892
|
+
AND toUInt256(amount) > 0
|
|
2014
2893
|
AND "from" = '${options.account}'
|
|
2015
2894
|
AND "to" = '${options.vault}'
|
|
2016
2895
|
AND block_num > ${options.startBlockNumber}
|
|
@@ -2051,6 +2930,7 @@ async function hasExternalShareTransfer(
|
|
|
2051
2930
|
SELECT tx_hash, toUInt256(amount) AS amount, count() AS transfer_count
|
|
2052
2931
|
FROM token_transfers
|
|
2053
2932
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
2933
|
+
AND toUInt256(amount) > 0
|
|
2054
2934
|
AND "from" = '${options.vault}'
|
|
2055
2935
|
AND "to" = '${options.account}'
|
|
2056
2936
|
AND block_num > ${options.startBlockNumber}
|
|
@@ -2074,6 +2954,7 @@ async function hasExternalShareTransfer(
|
|
|
2074
2954
|
redeemCancelledSignature,
|
|
2075
2955
|
redeemedSignature,
|
|
2076
2956
|
redeemRequestedSignature,
|
|
2957
|
+
unspentReturnedSignature,
|
|
2077
2958
|
withdrewExactSignature,
|
|
2078
2959
|
],
|
|
2079
2960
|
})
|
|
@@ -2086,6 +2967,7 @@ declare namespace hasExternalShareTransfer {
|
|
|
2086
2967
|
type Options = {
|
|
2087
2968
|
account: z.output<typeof Schema.Address>
|
|
2088
2969
|
blockNumber: number
|
|
2970
|
+
rewardTransfer: string
|
|
2089
2971
|
shareToken: z.output<typeof Schema.Address>
|
|
2090
2972
|
startBlockNumber: number
|
|
2091
2973
|
vault: z.output<typeof Schema.Address>
|
|
@@ -2111,6 +2993,7 @@ export function calculateActiveCostBasis(options: calculateActiveCostBasis.Optio
|
|
|
2111
2993
|
}
|
|
2112
2994
|
|
|
2113
2995
|
for (const action of options.actions) {
|
|
2996
|
+
if (action.shares === 0n) continue
|
|
2114
2997
|
if (action.kind === 'deposit') {
|
|
2115
2998
|
if (costBasis !== undefined) costBasis += action.assets
|
|
2116
2999
|
shares += action.shares
|
|
@@ -2273,7 +3156,7 @@ async function getActiveCostBasis(tidx: Tidx.Client, options: getActiveCostBasis
|
|
|
2273
3156
|
AND block_num <= ${options.blockNumber}
|
|
2274
3157
|
UNION ALL
|
|
2275
3158
|
SELECT
|
|
2276
|
-
'unknown' AS kind,
|
|
3159
|
+
if(${options.rewardTransfer}, 'deposit', 'unknown') AS kind,
|
|
2277
3160
|
block_num,
|
|
2278
3161
|
log_idx,
|
|
2279
3162
|
'' AS request_id,
|
|
@@ -2281,6 +3164,7 @@ async function getActiveCostBasis(tidx: Tidx.Client, options: getActiveCostBasis
|
|
|
2281
3164
|
'0' AS assets
|
|
2282
3165
|
FROM token_transfers
|
|
2283
3166
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
3167
|
+
AND toUInt256(amount) > 0
|
|
2284
3168
|
AND "to" = '${options.account}'
|
|
2285
3169
|
AND "from" != '${zeroAddress}'
|
|
2286
3170
|
AND "from" != '${options.vault}'
|
|
@@ -2295,6 +3179,7 @@ async function getActiveCostBasis(tidx: Tidx.Client, options: getActiveCostBasis
|
|
|
2295
3179
|
'0' AS assets
|
|
2296
3180
|
FROM token_transfers
|
|
2297
3181
|
WHERE token = '${options.shareToken.toLowerCase()}'
|
|
3182
|
+
AND toUInt256(amount) > 0
|
|
2298
3183
|
AND "from" = '${options.account}'
|
|
2299
3184
|
AND "to" != '${options.vault}'
|
|
2300
3185
|
AND block_num <= ${options.blockNumber}
|
|
@@ -2306,6 +3191,7 @@ async function getActiveCostBasis(tidx: Tidx.Client, options: getActiveCostBasis
|
|
|
2306
3191
|
redeemCancelledSignature,
|
|
2307
3192
|
redeemRequestedSignature,
|
|
2308
3193
|
redeemedSignature,
|
|
3194
|
+
unspentReturnedSignature,
|
|
2309
3195
|
venueSharesDepositedSignature,
|
|
2310
3196
|
withdrewExactSignature,
|
|
2311
3197
|
],
|
|
@@ -2355,6 +3241,7 @@ declare namespace getActiveCostBasis {
|
|
|
2355
3241
|
type Options = {
|
|
2356
3242
|
account: z.output<typeof Schema.Address>
|
|
2357
3243
|
blockNumber: number
|
|
3244
|
+
rewardTransfer: string
|
|
2358
3245
|
shareBalance: bigint
|
|
2359
3246
|
shareToken: z.output<typeof Schema.Address>
|
|
2360
3247
|
vault: z.output<typeof Schema.Address>
|
|
@@ -2458,7 +3345,7 @@ export async function listVaults(c: Context<App.Environment>, options: listVault
|
|
|
2458
3345
|
apyByVault.has(vaultAddress.toLowerCase()) ? [] : [vaultAddress],
|
|
2459
3346
|
)
|
|
2460
3347
|
: []
|
|
2461
|
-
const [missingApy, rates, tokens] = await Promise.all([
|
|
3348
|
+
const [missingApy, rates, rewards, tokens] = await Promise.all([
|
|
2462
3349
|
missingApyVaults.length > 0
|
|
2463
3350
|
? resolvePageApy(c, {
|
|
2464
3351
|
chainId: options.chainId,
|
|
@@ -2468,12 +3355,27 @@ export async function listVaults(c: Context<App.Environment>, options: listVault
|
|
|
2468
3355
|
})
|
|
2469
3356
|
: undefined,
|
|
2470
3357
|
resolvePageRates(c, { discoveries, include, oracle: options.oracle, snapshot }),
|
|
3358
|
+
resolvePageRewards(c, {
|
|
3359
|
+
chainId: options.chainId,
|
|
3360
|
+
include,
|
|
3361
|
+
vaults: discoveries.map(({ vaultAddress }) => vaultAddress),
|
|
3362
|
+
}),
|
|
2471
3363
|
resolvePageTokens(c, { chainId: options.chainId, discoveries, include, snapshot }),
|
|
2472
3364
|
])
|
|
2473
3365
|
for (const [vault, apy] of missingApy ?? []) apyByVault.set(vault, apy)
|
|
2474
3366
|
const apy = include.includes('apy') ? apyByVault : undefined
|
|
2475
3367
|
const data = await Promise.all(
|
|
2476
|
-
page.map((match) =>
|
|
3368
|
+
page.map((match) =>
|
|
3369
|
+
resolveVault(c, {
|
|
3370
|
+
...match,
|
|
3371
|
+
apy,
|
|
3372
|
+
include,
|
|
3373
|
+
rates,
|
|
3374
|
+
rewards: rewards?.get(match.discovery.vaultAddress),
|
|
3375
|
+
snapshot,
|
|
3376
|
+
tokens,
|
|
3377
|
+
}),
|
|
3378
|
+
),
|
|
2477
3379
|
)
|
|
2478
3380
|
const last = matches[options.limit - 1]
|
|
2479
3381
|
const nextPosition =
|
|
@@ -2557,7 +3459,7 @@ export async function listVerifiedVaults(
|
|
|
2557
3459
|
|
|
2558
3460
|
const page = matches.slice(0, options.limit)
|
|
2559
3461
|
const discoveries = page.map(({ discovery }) => discovery)
|
|
2560
|
-
const [apy, rates, tokens] = await Promise.all([
|
|
3462
|
+
const [apy, rates, rewards, tokens] = await Promise.all([
|
|
2561
3463
|
resolvePageApy(c, {
|
|
2562
3464
|
chainId: options.chainId,
|
|
2563
3465
|
include,
|
|
@@ -2565,13 +3467,26 @@ export async function listVerifiedVaults(
|
|
|
2565
3467
|
window: options['apy.window'],
|
|
2566
3468
|
}),
|
|
2567
3469
|
resolvePageRates(c, { discoveries, include, oracle: options.oracle, snapshot }),
|
|
3470
|
+
resolvePageRewards(c, {
|
|
3471
|
+
chainId: options.chainId,
|
|
3472
|
+
include,
|
|
3473
|
+
vaults: discoveries.map(({ vaultAddress }) => vaultAddress),
|
|
3474
|
+
}),
|
|
2568
3475
|
resolvePageTokens(c, { chainId: options.chainId, discoveries, include, snapshot }),
|
|
2569
3476
|
])
|
|
2570
3477
|
const data = await Promise.all(
|
|
2571
3478
|
page.map(async (match) =>
|
|
2572
3479
|
Response.validated(
|
|
2573
3480
|
schema.VerifiedVault,
|
|
2574
|
-
await resolveVault(c, {
|
|
3481
|
+
await resolveVault(c, {
|
|
3482
|
+
...match,
|
|
3483
|
+
apy,
|
|
3484
|
+
include,
|
|
3485
|
+
rates,
|
|
3486
|
+
rewards: rewards?.get(match.discovery.vaultAddress),
|
|
3487
|
+
snapshot,
|
|
3488
|
+
tokens,
|
|
3489
|
+
}),
|
|
2575
3490
|
),
|
|
2576
3491
|
),
|
|
2577
3492
|
)
|
|
@@ -2600,15 +3515,371 @@ export declare namespace listVerifiedVaults {
|
|
|
2600
3515
|
}
|
|
2601
3516
|
}
|
|
2602
3517
|
|
|
3518
|
+
/** Reads daily historical share prices for one Earn vault. */
|
|
3519
|
+
export async function getVaultSharePrices(
|
|
3520
|
+
c: Context<App.Environment>,
|
|
3521
|
+
options: getVaultSharePrices.Options,
|
|
3522
|
+
) {
|
|
3523
|
+
const prices = await Timing.time(c, 'earn_share_prices', () =>
|
|
3524
|
+
EarnSharePrices.resolve({
|
|
3525
|
+
chainId: options.chainId,
|
|
3526
|
+
from: options.from,
|
|
3527
|
+
// This client is request-local so viem's stateful HTTP batch cannot cross Worker invocations.
|
|
3528
|
+
getClient: (chainId = options.chainId) =>
|
|
3529
|
+
Viem.createBatchClient({
|
|
3530
|
+
chainId,
|
|
3531
|
+
principal: Auth.getPrincipal(c),
|
|
3532
|
+
rpc: c.get('rpc'),
|
|
3533
|
+
zone: c.get('zones').get(chainId),
|
|
3534
|
+
}),
|
|
3535
|
+
getTidx: c.get('getTidx'),
|
|
3536
|
+
shareDecimals: options.discovery.shareToken.decimals,
|
|
3537
|
+
to: options.to,
|
|
3538
|
+
vault: options.vault,
|
|
3539
|
+
}),
|
|
3540
|
+
)
|
|
3541
|
+
return prices.map((price) => ({
|
|
3542
|
+
sharePrice: {
|
|
3543
|
+
amount: price.amount.toString(),
|
|
3544
|
+
currency: options.discovery.assetToken.currency,
|
|
3545
|
+
decimals: options.discovery.assetToken.decimals,
|
|
3546
|
+
formatted: core_Value.format(price.amount, options.discovery.assetToken.decimals),
|
|
3547
|
+
},
|
|
3548
|
+
timestamp: price.timestamp,
|
|
3549
|
+
}))
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3552
|
+
/** Classifies an Earn share-price dependency failure for request metrics. */
|
|
3553
|
+
export function sharePriceProviderFailure(
|
|
3554
|
+
options: sharePriceProviderFailure.Options,
|
|
3555
|
+
): Log.ProviderFailure | undefined {
|
|
3556
|
+
if (options.cause instanceof EarnSharePrices.MalformedResponseError)
|
|
3557
|
+
return {
|
|
3558
|
+
chainId: options.chainId,
|
|
3559
|
+
failure: 'payload',
|
|
3560
|
+
id: 'tidx',
|
|
3561
|
+
operation: 'query',
|
|
3562
|
+
}
|
|
3563
|
+
if (options.cause instanceof EarnSharePrices.TidxRequestError)
|
|
3564
|
+
return { ...Tidx.providerFailure(options.cause.cause), chainId: options.chainId }
|
|
3565
|
+
const failure = Viem.requestFailure(options.cause)
|
|
3566
|
+
if (failure) return { ...failure, chainId: options.chainId, id: 'rpc', operation: 'eth_call' }
|
|
3567
|
+
return undefined
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
export declare namespace sharePriceProviderFailure {
|
|
3571
|
+
/** Failure and chain used to derive bounded dependency metadata. */
|
|
3572
|
+
type Options = {
|
|
3573
|
+
/** Chain whose dependency call failed. */
|
|
3574
|
+
chainId: number
|
|
3575
|
+
/** Error returned by TIDX parsing or the RPC client. */
|
|
3576
|
+
cause: unknown
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
export declare namespace getVaultSharePrices {
|
|
3581
|
+
/** Inputs selecting one Earn vault share-price series. */
|
|
3582
|
+
type Options = z.output<typeof schema.getEarnVaultSharePrices.Query> & {
|
|
3583
|
+
/** Chain containing the Earn vault. */
|
|
3584
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
3585
|
+
/** Current compatible vault and token metadata. */
|
|
3586
|
+
discovery: EarnVaults.Discovery
|
|
3587
|
+
/** Earn vault contract address. */
|
|
3588
|
+
vault: z.output<typeof Schema.Address>
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3592
|
+
async function resolveSharePriceVaultDiscovery(
|
|
3593
|
+
c: Context<App.Environment>,
|
|
3594
|
+
options: resolveSharePriceVaultDiscovery.Options,
|
|
3595
|
+
): Promise<EarnVaults.Discovery | undefined> {
|
|
3596
|
+
const result = await Store.memoize(
|
|
3597
|
+
async () => {
|
|
3598
|
+
try {
|
|
3599
|
+
return {
|
|
3600
|
+
discovery: await readVaultDiscovery(c, { ...options, include: [] }),
|
|
3601
|
+
status: 'found',
|
|
3602
|
+
} as const
|
|
3603
|
+
} catch (cause) {
|
|
3604
|
+
if (isIncompatible(cause)) return { status: 'not_found' } as const
|
|
3605
|
+
throw cause
|
|
3606
|
+
}
|
|
3607
|
+
},
|
|
3608
|
+
{
|
|
3609
|
+
key: `earn-share-price-vault:v1:${options.chainId}:${options.vaultAddress.toLowerCase()}`,
|
|
3610
|
+
store: c.get('store'),
|
|
3611
|
+
ttl: Ttl.seconds(5),
|
|
3612
|
+
},
|
|
3613
|
+
)
|
|
3614
|
+
return result.status === 'found' ? result.discovery : undefined
|
|
3615
|
+
}
|
|
3616
|
+
|
|
3617
|
+
declare namespace resolveSharePriceVaultDiscovery {
|
|
3618
|
+
type Options = {
|
|
3619
|
+
/** Chain containing the candidate Earn vault. */
|
|
3620
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
3621
|
+
/** Candidate Earn vault contract address. */
|
|
3622
|
+
vaultAddress: z.output<typeof Schema.Address>
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
/** Reads one direct or Zone-routed account position in a parent-chain Earn vault. */
|
|
3627
|
+
export async function getVaultPosition(
|
|
3628
|
+
c: Context<App.Environment>,
|
|
3629
|
+
options: getVaultPosition.Options,
|
|
3630
|
+
): Promise<getVaultPosition.ReturnType> {
|
|
3631
|
+
const zone = c.get('zones').get(options.chainId)
|
|
3632
|
+
if (!zone) {
|
|
3633
|
+
const block =
|
|
3634
|
+
options.asOf === undefined
|
|
3635
|
+
? undefined
|
|
3636
|
+
: await getIndexedBlockAtOrBefore(c.get('getTidx')(options.chainId), options.asOf)
|
|
3637
|
+
const position = await c
|
|
3638
|
+
.get('getClient')(options.chainId)
|
|
3639
|
+
.earn.getPosition({
|
|
3640
|
+
account: options.account,
|
|
3641
|
+
...(block ? { blockNumber: BigInt(block.number) } : {}),
|
|
3642
|
+
vault: options.vault,
|
|
3643
|
+
})
|
|
3644
|
+
return { ...position, block, valueToken: position.assetToken }
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
const route = await resolveZonePositionRoute(c, {
|
|
3648
|
+
chainId: options.chainId,
|
|
3649
|
+
vault: options.vault,
|
|
3650
|
+
})
|
|
3651
|
+
const block =
|
|
3652
|
+
options.asOf === undefined
|
|
3653
|
+
? undefined
|
|
3654
|
+
: await getIndexedBlockAtOrBefore(c.get('getTidx')(options.chainId), options.asOf)
|
|
3655
|
+
const zoneClient = c.get('getClient')(options.chainId)
|
|
3656
|
+
const blockNumber = block ? BigInt(block.number) : await zoneClient.getBlockNumber()
|
|
3657
|
+
const [assetBalance, shareBalance, importedParentBlockNumber] = await Promise.all([
|
|
3658
|
+
readZoneBalance(zoneClient, {
|
|
3659
|
+
account: options.account,
|
|
3660
|
+
blockNumber,
|
|
3661
|
+
token: route.privateAsset,
|
|
3662
|
+
}),
|
|
3663
|
+
readZoneBalance(zoneClient, {
|
|
3664
|
+
account: options.account,
|
|
3665
|
+
blockNumber,
|
|
3666
|
+
token: route.shareToken,
|
|
3667
|
+
}),
|
|
3668
|
+
readZoneSourceBlock(c, {
|
|
3669
|
+
blockNumber,
|
|
3670
|
+
historical: block !== undefined,
|
|
3671
|
+
portal: route.portal,
|
|
3672
|
+
sourceChainId: route.sourceChainId,
|
|
3673
|
+
zoneClient,
|
|
3674
|
+
}),
|
|
3675
|
+
])
|
|
3676
|
+
const sourceBlock = Value.toNumber(importedParentBlockNumber)
|
|
3677
|
+
if (sourceBlock === undefined || sourceBlock < route.deploymentBlock)
|
|
3678
|
+
throw new EarnVaults.NotFoundError()
|
|
3679
|
+
const value = await c
|
|
3680
|
+
.get('getClient')(route.sourceChainId)
|
|
3681
|
+
.earn.getRedeemQuote({
|
|
3682
|
+
blockNumber: BigInt(sourceBlock),
|
|
3683
|
+
shareAmount: shareBalance,
|
|
3684
|
+
vault: options.vault,
|
|
3685
|
+
})
|
|
3686
|
+
return {
|
|
3687
|
+
assetAllowance: 0n,
|
|
3688
|
+
assetBalance,
|
|
3689
|
+
assetToken: route.privateAsset,
|
|
3690
|
+
block,
|
|
3691
|
+
shareAllowance: 0n,
|
|
3692
|
+
shareBalance,
|
|
3693
|
+
shareToken: route.shareToken,
|
|
3694
|
+
value,
|
|
3695
|
+
valueToken: route.vaultAsset,
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
export declare namespace getVaultPosition {
|
|
3700
|
+
/** Inputs selecting one direct or Zone-routed account position. */
|
|
3701
|
+
type Options = {
|
|
3702
|
+
account: z.output<typeof Schema.Address>
|
|
3703
|
+
asOf?: string | undefined
|
|
3704
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
3705
|
+
vault: z.output<typeof Schema.Address>
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3708
|
+
/** Normalized position state across a direct chain or private Zone. */
|
|
3709
|
+
type ReturnType = Actions.earn.getPosition.ReturnValue & {
|
|
3710
|
+
block?: { number: number; timestamp: string } | undefined
|
|
3711
|
+
valueToken: z.output<typeof Schema.Address>
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
/** Reads a private Zone token balance with the holder as the authorized RPC caller. */
|
|
3716
|
+
async function readZoneBalance(
|
|
3717
|
+
client: ReturnType<App.Environment['Variables']['getClient']>,
|
|
3718
|
+
options: readZoneBalance.Options,
|
|
3719
|
+
) {
|
|
3720
|
+
return client.readContract({
|
|
3721
|
+
abi: tokenPositionAbi,
|
|
3722
|
+
account: options.account,
|
|
3723
|
+
address: options.token,
|
|
3724
|
+
args: [options.account],
|
|
3725
|
+
...(options.blockNumber === undefined ? {} : { blockNumber: options.blockNumber }),
|
|
3726
|
+
functionName: 'balanceOf',
|
|
3727
|
+
})
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
declare namespace readZoneBalance {
|
|
3731
|
+
/** Private balance selector and optional historical Zone block. */
|
|
3732
|
+
type Options = {
|
|
3733
|
+
account: z.output<typeof Schema.Address>
|
|
3734
|
+
blockNumber?: bigint | undefined
|
|
3735
|
+
token: z.output<typeof Schema.Address>
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
/** Reads the parent Tempo checkpoint imported by one Zone observation. */
|
|
3740
|
+
async function readZoneSourceBlock(
|
|
3741
|
+
c: Context<App.Environment>,
|
|
3742
|
+
options: readZoneSourceBlock.Options,
|
|
3743
|
+
): Promise<bigint> {
|
|
3744
|
+
const verifiedPromise = c.get('getClient')(options.sourceChainId).readContract({
|
|
3745
|
+
abi: zonePortalAbi,
|
|
3746
|
+
address: options.portal,
|
|
3747
|
+
functionName: 'lastSyncedTempoBlockNumber',
|
|
3748
|
+
})
|
|
3749
|
+
// A historical Zone without TempoState rejects before awaiting the portal.
|
|
3750
|
+
void verifiedPromise.catch(() => undefined)
|
|
3751
|
+
const reported = await (async () => {
|
|
3752
|
+
try {
|
|
3753
|
+
return await options.zoneClient.readContract({
|
|
3754
|
+
abi: tempoStateAbi,
|
|
3755
|
+
address: tempoStateAddress,
|
|
3756
|
+
blockNumber: options.blockNumber,
|
|
3757
|
+
functionName: 'tempoBlockNumber',
|
|
3758
|
+
})
|
|
3759
|
+
} catch (cause) {
|
|
3760
|
+
if (
|
|
3761
|
+
!(cause instanceof ContractFunctionExecutionError) ||
|
|
3762
|
+
!(cause.cause instanceof ContractFunctionZeroDataError)
|
|
3763
|
+
)
|
|
3764
|
+
throw cause
|
|
3765
|
+
if (options.historical) throw new ZoneHistoricalAlignmentError()
|
|
3766
|
+
return undefined
|
|
3767
|
+
}
|
|
3768
|
+
})()
|
|
3769
|
+
const verified = await verifiedPromise
|
|
3770
|
+
return alignZoneSourceBlock({ reported, verified })
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3773
|
+
declare namespace readZoneSourceBlock {
|
|
3774
|
+
/** Zone observation and parent Portal used to resolve one synchronization boundary. */
|
|
3775
|
+
type Options = {
|
|
3776
|
+
blockNumber: bigint
|
|
3777
|
+
historical: boolean
|
|
3778
|
+
portal: z.output<typeof Schema.Address>
|
|
3779
|
+
sourceChainId: number
|
|
3780
|
+
zoneClient: ReturnType<App.Environment['Variables']['getClient']>
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
/** Caps a Zone-reported parent checkpoint at the L1 portal's verified watermark. */
|
|
3785
|
+
export function alignZoneSourceBlock(options: alignZoneSourceBlock.Options): bigint {
|
|
3786
|
+
if (options.reported === undefined || options.verified < options.reported) return options.verified
|
|
3787
|
+
return options.reported
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
export declare namespace alignZoneSourceBlock {
|
|
3791
|
+
/** Zone-reported and L1-verified parent checkpoints. */
|
|
3792
|
+
type Options = {
|
|
3793
|
+
/** Parent checkpoint reported by the Zone, when available. */
|
|
3794
|
+
reported?: bigint | undefined
|
|
3795
|
+
/** Latest parent checkpoint verified by the L1 portal. */
|
|
3796
|
+
verified: bigint
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
|
|
3800
|
+
/** Resolves the verified parent vault and token pair for one Zone route. */
|
|
3801
|
+
async function resolveZonePositionRoute(
|
|
3802
|
+
c: Context<App.Environment>,
|
|
3803
|
+
options: resolveZonePositionRoute.Options,
|
|
3804
|
+
): Promise<resolveZonePositionRoute.ReturnType> {
|
|
3805
|
+
const zone = c.get('zones').get(options.chainId)
|
|
3806
|
+
if (!zone?.sourceId) throw new EarnVaults.NotFoundError()
|
|
3807
|
+
const db = Db.get(c.get('dbCached'))
|
|
3808
|
+
const record = await core_EarnVaults.get(db, {
|
|
3809
|
+
chainId: zone.sourceId,
|
|
3810
|
+
vaultAddress: options.vault,
|
|
3811
|
+
})
|
|
3812
|
+
const configured = record?.zones.find((route) => route.chainId === options.chainId)
|
|
3813
|
+
if (!record || !configured) throw new EarnVaults.NotFoundError()
|
|
3814
|
+
const discovery = await resolveVaultDiscovery(c, {
|
|
3815
|
+
chainId: zone.sourceId,
|
|
3816
|
+
include: [],
|
|
3817
|
+
vaultAddress: options.vault,
|
|
3818
|
+
})
|
|
3819
|
+
const [route] = await EarnVaults.resolveZoneRoutes({
|
|
3820
|
+
discovery,
|
|
3821
|
+
getClient: c.get('getClient'),
|
|
3822
|
+
routes: [configured],
|
|
3823
|
+
zones: [...c.get('zones').values()],
|
|
3824
|
+
})
|
|
3825
|
+
const privateAsset = route?.inputTokens[0]
|
|
3826
|
+
const portalContract = zone.contracts?.['portal']
|
|
3827
|
+
const portal = Schema.Address.safeParse(
|
|
3828
|
+
portalContract && 'address' in portalContract
|
|
3829
|
+
? portalContract.address
|
|
3830
|
+
: portalContract?.[zone.sourceId]?.address,
|
|
3831
|
+
)
|
|
3832
|
+
if (!route || !privateAsset || !portal.success) throw new EarnVaults.NotFoundError()
|
|
3833
|
+
return {
|
|
3834
|
+
deploymentBlock: route.deploymentBlock,
|
|
3835
|
+
portal: portal.data,
|
|
3836
|
+
privateAsset,
|
|
3837
|
+
shareToken: discovery.shareToken.address,
|
|
3838
|
+
sourceChainId: zone.sourceId,
|
|
3839
|
+
vaultAsset: discovery.assetToken.address,
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
declare namespace resolveZonePositionRoute {
|
|
3844
|
+
/** Zone and parent vault selecting one curated route. */
|
|
3845
|
+
type Options = {
|
|
3846
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
3847
|
+
vault: z.output<typeof Schema.Address>
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3850
|
+
/** Verified addresses needed to read and value a Zone position. */
|
|
3851
|
+
type ReturnType = {
|
|
3852
|
+
deploymentBlock: number
|
|
3853
|
+
privateAsset: z.output<typeof Schema.Address>
|
|
3854
|
+
portal: z.output<typeof Schema.Address>
|
|
3855
|
+
shareToken: z.output<typeof Schema.Address>
|
|
3856
|
+
sourceChainId: number
|
|
3857
|
+
vaultAsset: z.output<typeof Schema.Address>
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
|
|
2603
3861
|
/** Lists every vault where an account holds earn shares, ordered by vault address. */
|
|
2604
3862
|
export async function listPositions(c: Context<App.Environment>, options: listPositions.Options) {
|
|
2605
3863
|
const denomination = options['valuation.currency']
|
|
3864
|
+
const zone = c.get('zones').get(options.chainId)
|
|
3865
|
+
if (zone && options.include.includes('earnings')) throw new ZoneEarningsUnsupportedError()
|
|
3866
|
+
const sourceChainId = zone ? zone.sourceId : options.chainId
|
|
3867
|
+
if (sourceChainId === undefined) throw new EarnVaults.NotFoundError()
|
|
2606
3868
|
const db = Db.get(c.get('dbCached'))
|
|
2607
|
-
const recordsPromise = core_EarnVaults
|
|
3869
|
+
const recordsPromise = core_EarnVaults
|
|
3870
|
+
.list(db, { chainId: sourceChainId })
|
|
3871
|
+
.then((records) =>
|
|
3872
|
+
zone
|
|
3873
|
+
? records.filter((record) =>
|
|
3874
|
+
record.zones.some((route) => route.chainId === options.chainId),
|
|
3875
|
+
)
|
|
3876
|
+
: records,
|
|
3877
|
+
)
|
|
2608
3878
|
// The verified page needs no index: the registry is the candidate set.
|
|
2609
|
-
const heldPromise =
|
|
2610
|
-
|
|
2611
|
-
|
|
3879
|
+
const heldPromise =
|
|
3880
|
+
options.verified || zone
|
|
3881
|
+
? undefined
|
|
3882
|
+
: queryHeldVaults(c, { address: options.address, chainId: options.chainId })
|
|
2612
3883
|
// Observing these branches prevents unhandled rejections while the
|
|
2613
3884
|
// denomination validates; the later await still propagates them.
|
|
2614
3885
|
void recordsPromise.catch(() => undefined)
|
|
@@ -2647,13 +3918,14 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
|
|
|
2647
3918
|
batch.map(async (vault) => {
|
|
2648
3919
|
const record = registry.get(vault)
|
|
2649
3920
|
try {
|
|
2650
|
-
const position = await
|
|
2651
|
-
|
|
3921
|
+
const position = await getVaultPosition(c, {
|
|
3922
|
+
account: options.address,
|
|
2652
3923
|
chainId: options.chainId,
|
|
2653
|
-
|
|
3924
|
+
vault: Schema.Address.parse(vault),
|
|
2654
3925
|
})
|
|
2655
3926
|
return { position, record, vaultAddress: vault }
|
|
2656
3927
|
} catch (cause) {
|
|
3928
|
+
if (cause instanceof EarnVaults.NotFoundError) return undefined
|
|
2657
3929
|
if (!record && isIncompatible(cause)) return undefined
|
|
2658
3930
|
throw cause
|
|
2659
3931
|
}
|
|
@@ -2668,10 +3940,10 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
|
|
|
2668
3940
|
|
|
2669
3941
|
const page = matches.slice(0, options.limit)
|
|
2670
3942
|
const indexedBlock =
|
|
2671
|
-
page.length > 0 && options.include.includes('earnings')
|
|
3943
|
+
!zone && page.length > 0 && options.include.includes('earnings')
|
|
2672
3944
|
? await getLatestIndexedBlock(c.get('getTidx')(options.chainId))
|
|
2673
3945
|
: undefined
|
|
2674
|
-
const [cashFlows, tokens, snapshot] = await Promise.all([
|
|
3946
|
+
const [cashFlows, tokens, valueTokens, snapshot] = await Promise.all([
|
|
2675
3947
|
indexedBlock
|
|
2676
3948
|
? getVaultLifetimeCashFlows(c.get('getTidx')(options.chainId), {
|
|
2677
3949
|
account: options.address,
|
|
@@ -2694,13 +3966,20 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
|
|
|
2694
3966
|
)
|
|
2695
3967
|
return new Map(groups.flatMap((group) => [...group]))
|
|
2696
3968
|
})(),
|
|
2697
|
-
|
|
3969
|
+
zone
|
|
3970
|
+
? Tokens.resolveTokens(c, {
|
|
3971
|
+
addresses: [...new Set(page.map(({ position }) => position.valueToken))],
|
|
3972
|
+
chainId: sourceChainId,
|
|
3973
|
+
include: ['token.verified'],
|
|
3974
|
+
})
|
|
3975
|
+
: undefined,
|
|
3976
|
+
denomination ? VerifiedTokens.snapshot(c, sourceChainId) : undefined,
|
|
2698
3977
|
])
|
|
2699
3978
|
const rates =
|
|
2700
3979
|
denomination && snapshot
|
|
2701
3980
|
? await Valuation.ratesFor(c, {
|
|
2702
3981
|
currencies: page.flatMap(({ position }) => {
|
|
2703
|
-
const currency = snapshot.byAddress.get(position.
|
|
3982
|
+
const currency = snapshot.byAddress.get(position.valueToken.toLowerCase())?.currency
|
|
2704
3983
|
return currency === undefined ? [] : [currency]
|
|
2705
3984
|
}),
|
|
2706
3985
|
denomination,
|
|
@@ -2720,11 +3999,13 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
|
|
|
2720
3999
|
data: page.map((match) =>
|
|
2721
4000
|
serializePosition({
|
|
2722
4001
|
cashFlows: cashFlows?.get(match.vaultAddress),
|
|
4002
|
+
chainId: options.chainId,
|
|
2723
4003
|
denomination,
|
|
2724
4004
|
position: match.position,
|
|
2725
4005
|
rates,
|
|
2726
4006
|
snapshot,
|
|
2727
4007
|
tokens,
|
|
4008
|
+
valueTokens,
|
|
2728
4009
|
vaultAddress: match.vaultAddress,
|
|
2729
4010
|
verified: match.record !== undefined,
|
|
2730
4011
|
}),
|
|
@@ -2737,7 +4018,7 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
|
|
|
2737
4018
|
export declare namespace listPositions {
|
|
2738
4019
|
/** One candidate vault holding a non-zero position. */
|
|
2739
4020
|
type Match = {
|
|
2740
|
-
position:
|
|
4021
|
+
position: getVaultPosition.ReturnType
|
|
2741
4022
|
record?: RegistryRecord | undefined
|
|
2742
4023
|
vaultAddress: string
|
|
2743
4024
|
}
|
|
@@ -2757,12 +4038,11 @@ async function queryHeldVaults(
|
|
|
2757
4038
|
c: Context<App.Environment>,
|
|
2758
4039
|
options: queryHeldVaults.Options,
|
|
2759
4040
|
): Promise<readonly string[]> {
|
|
4041
|
+
const factories = deploymentFactories[options.chainId] ?? []
|
|
4042
|
+
if (factories.length === 0) return []
|
|
2760
4043
|
const tidx = c.get('getTidx')(options.chainId)
|
|
2761
|
-
//
|
|
2762
|
-
//
|
|
2763
|
-
// candidates in one round trip, with no literal list to overflow the request.
|
|
2764
|
-
// Earn shares are factory-minted TIP-20s, so the `0x20c0` prefix bounds the
|
|
2765
|
-
// subquery. Stale delta rows are fine: the live read drops them.
|
|
4044
|
+
// Filter emitters before ranking so forged events cannot replace share bindings.
|
|
4045
|
+
// TIP-20 prefixes bound holder scans; live reads discard exited positions.
|
|
2766
4046
|
const result = await Timing.time(c, 'earn_positions_discovery', () =>
|
|
2767
4047
|
tidx.fetch({
|
|
2768
4048
|
chainId: options.chainId,
|
|
@@ -2778,6 +4058,7 @@ async function queryHeldVaults(
|
|
|
2778
4058
|
ORDER BY block_num DESC, log_idx DESC
|
|
2779
4059
|
) AS deployment_rank
|
|
2780
4060
|
FROM EarnStackDeployed
|
|
4061
|
+
WHERE address IN (${factories.map((address) => `'${address}'`).join(', ')})
|
|
2781
4062
|
)
|
|
2782
4063
|
WHERE deployment_rank = 1 AND lower("earnShare") IN (
|
|
2783
4064
|
SELECT DISTINCT lower(token)
|
|
@@ -2804,34 +4085,17 @@ declare namespace queryHeldVaults {
|
|
|
2804
4085
|
}
|
|
2805
4086
|
}
|
|
2806
4087
|
|
|
2807
|
-
/** Reads one account's live position in one vault. */
|
|
2808
|
-
function readPosition(
|
|
2809
|
-
c: Context<App.Environment>,
|
|
2810
|
-
options: readPosition.Options,
|
|
2811
|
-
): Promise<Actions.earn.getPosition.ReturnValue> {
|
|
2812
|
-
return c
|
|
2813
|
-
.get('getClient')(options.chainId)
|
|
2814
|
-
.earn.getPosition({ account: options.address, vault: options.vaultAddress })
|
|
2815
|
-
}
|
|
2816
|
-
|
|
2817
|
-
declare namespace readPosition {
|
|
2818
|
-
/** Inputs selecting one vault position. */
|
|
2819
|
-
type Options = {
|
|
2820
|
-
address: z.output<typeof Schema.Address>
|
|
2821
|
-
chainId: z.output<typeof Schema.ChainId>
|
|
2822
|
-
vaultAddress: z.output<typeof Schema.Address>
|
|
2823
|
-
}
|
|
2824
|
-
}
|
|
2825
|
-
|
|
2826
4088
|
/** Serializes one live position into the address-scoped row contract. */
|
|
2827
4089
|
function serializePosition(options: serializePosition.Options) {
|
|
2828
4090
|
const { position, tokens } = options
|
|
2829
4091
|
const assetToken = getToken(tokens, position.assetToken)
|
|
2830
4092
|
const shareToken = getToken(tokens, position.shareToken)
|
|
4093
|
+
const valueToken = getToken(options.valueTokens ?? tokens, position.valueToken)
|
|
2831
4094
|
const vaultAddress = Schema.Address.parse(options.vaultAddress.toLowerCase())
|
|
2832
4095
|
return {
|
|
2833
|
-
assetAmount: valueFor(position.value,
|
|
4096
|
+
assetAmount: valueFor(position.value, valueToken),
|
|
2834
4097
|
assetToken,
|
|
4098
|
+
chainId: options.chainId,
|
|
2835
4099
|
id: vaultAddress,
|
|
2836
4100
|
...(options.cashFlows ? { lifetimeCashFlows: options.cashFlows } : {}),
|
|
2837
4101
|
shareAmount: valueFor(position.shareBalance, shareToken),
|
|
@@ -2842,10 +4106,11 @@ function serializePosition(options: serializePosition.Options) {
|
|
|
2842
4106
|
amount: position.value,
|
|
2843
4107
|
denomination: options.denomination,
|
|
2844
4108
|
rates: options.rates,
|
|
2845
|
-
token: options.snapshot?.byAddress.get(
|
|
4109
|
+
token: options.snapshot?.byAddress.get(valueToken.address),
|
|
2846
4110
|
}),
|
|
2847
4111
|
}
|
|
2848
4112
|
: {}),
|
|
4113
|
+
valueToken,
|
|
2849
4114
|
vaultAddress,
|
|
2850
4115
|
verified: options.verified,
|
|
2851
4116
|
}
|
|
@@ -2858,14 +4123,16 @@ declare namespace serializePosition {
|
|
|
2858
4123
|
cashFlows?: z.output<
|
|
2859
4124
|
typeof schema.getEarnAddressPositions.Response
|
|
2860
4125
|
>['data'][number]['lifetimeCashFlows']
|
|
4126
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
2861
4127
|
/** Currency the row valuation is denominated in (uppercase). */
|
|
2862
4128
|
denomination?: string | undefined
|
|
2863
|
-
position:
|
|
4129
|
+
position: getVaultPosition.ReturnType
|
|
2864
4130
|
/** Consulted FX rate set, or undefined when unavailable or unnecessary. */
|
|
2865
4131
|
rates: Awaited<ReturnType<typeof Valuation.ratesFor>>
|
|
2866
4132
|
/** Curated token snapshot backing valuation, present when requested. */
|
|
2867
4133
|
snapshot?: VerifiedTokens.Snapshot | undefined
|
|
2868
4134
|
tokens: Tokens.resolveTokens.ReturnType
|
|
4135
|
+
valueTokens?: Tokens.resolveTokens.ReturnType | undefined
|
|
2869
4136
|
vaultAddress: string
|
|
2870
4137
|
verified: boolean
|
|
2871
4138
|
}
|
|
@@ -3054,7 +4321,7 @@ export async function getVault(c: Context<App.Environment>, options: getVault.Op
|
|
|
3054
4321
|
record,
|
|
3055
4322
|
})
|
|
3056
4323
|
const discoveries = [discovery]
|
|
3057
|
-
const [apy, rates, tokens] = await Promise.all([
|
|
4324
|
+
const [apy, rates, rewards, tokens] = await Promise.all([
|
|
3058
4325
|
resolvePageApy(c, {
|
|
3059
4326
|
chainId: options.chainId,
|
|
3060
4327
|
include,
|
|
@@ -3062,6 +4329,11 @@ export async function getVault(c: Context<App.Environment>, options: getVault.Op
|
|
|
3062
4329
|
window: options['apy.window'],
|
|
3063
4330
|
}),
|
|
3064
4331
|
resolvePageRates(c, { discoveries, include, oracle: options.oracle, snapshot }),
|
|
4332
|
+
resolveVaultRewards(c, {
|
|
4333
|
+
chainId: options.chainId,
|
|
4334
|
+
include,
|
|
4335
|
+
vault: discovery.vaultAddress,
|
|
4336
|
+
}),
|
|
3065
4337
|
resolvePageTokens(c, { chainId: options.chainId, discoveries, include, snapshot }),
|
|
3066
4338
|
])
|
|
3067
4339
|
return {
|
|
@@ -3071,6 +4343,7 @@ export async function getVault(c: Context<App.Environment>, options: getVault.Op
|
|
|
3071
4343
|
include,
|
|
3072
4344
|
rates,
|
|
3073
4345
|
record,
|
|
4346
|
+
rewards,
|
|
3074
4347
|
snapshot,
|
|
3075
4348
|
tokens,
|
|
3076
4349
|
zoneRoutes,
|
|
@@ -3148,29 +4421,36 @@ async function resolveVaultDiscovery(
|
|
|
3148
4421
|
c: Context<App.Environment>,
|
|
3149
4422
|
options: resolveVaultDiscovery.Options,
|
|
3150
4423
|
) {
|
|
3151
|
-
return Store.memoize(
|
|
3152
|
-
()
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
4424
|
+
return Store.memoize(() => readVaultDiscovery(c, options), {
|
|
4425
|
+
key: `earn-vault:v3:${options.chainId}:${options.vaultAddress.toLowerCase()}:include:${options.include.join(',') || 'base'}`,
|
|
4426
|
+
store: c.get('store'),
|
|
4427
|
+
// Matches the routes' `state` policy `max-age` so the two cache layers do
|
|
4428
|
+
// not compound staleness on live vault state.
|
|
4429
|
+
ttl: Ttl.seconds(30),
|
|
4430
|
+
})
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
async function readVaultDiscovery(
|
|
4434
|
+
c: Context<App.Environment>,
|
|
4435
|
+
options: readVaultDiscovery.Options,
|
|
4436
|
+
) {
|
|
4437
|
+
return Timing.time(c, 'earn_vault_discovery', () =>
|
|
4438
|
+
EarnVaults.resolve({
|
|
4439
|
+
getClient: c.get('getClient'),
|
|
4440
|
+
include: options.include,
|
|
4441
|
+
input: {
|
|
4442
|
+
chainId: options.chainId,
|
|
4443
|
+
vaultAddress: options.vaultAddress,
|
|
4444
|
+
},
|
|
4445
|
+
zones: [...c.get('zones').values()],
|
|
4446
|
+
}),
|
|
3171
4447
|
)
|
|
3172
4448
|
}
|
|
3173
4449
|
|
|
4450
|
+
declare namespace readVaultDiscovery {
|
|
4451
|
+
type Options = resolveVaultDiscovery.Options
|
|
4452
|
+
}
|
|
4453
|
+
|
|
3174
4454
|
declare namespace resolveVaultDiscovery {
|
|
3175
4455
|
type Options = {
|
|
3176
4456
|
chainId: z.output<typeof Schema.ChainId>
|
|
@@ -3233,6 +4513,129 @@ declare namespace resolveVaultRoutes {
|
|
|
3233
4513
|
}
|
|
3234
4514
|
}
|
|
3235
4515
|
|
|
4516
|
+
async function resolvePositionApy(
|
|
4517
|
+
c: Context<App.Environment>,
|
|
4518
|
+
options: resolvePositionApy.Options,
|
|
4519
|
+
): Promise<RewardRead.PositionApy | null> {
|
|
4520
|
+
const sourceChainId = c.get('zones').get(options.chainId)?.sourceId ?? options.chainId
|
|
4521
|
+
const recordFailure = (failure: Log.ProviderFailure) => {
|
|
4522
|
+
Cache.setPolicy(c, Cache.policies.noStore)
|
|
4523
|
+
c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure])
|
|
4524
|
+
}
|
|
4525
|
+
const rateFailures: Log.ProviderFailure[] = []
|
|
4526
|
+
const [rates, discovery] = await Promise.all([
|
|
4527
|
+
Timing.time(c, 'earn_apy', () =>
|
|
4528
|
+
EarnRates.resolve({
|
|
4529
|
+
chainId: sourceChainId,
|
|
4530
|
+
getClient: c.get('getClient'),
|
|
4531
|
+
getTidx: c.get('getTidx'),
|
|
4532
|
+
onFailure: (failure) => {
|
|
4533
|
+
rateFailures.push({ ...failure, chainId: sourceChainId })
|
|
4534
|
+
},
|
|
4535
|
+
store: c.get('store'),
|
|
4536
|
+
vaults: [options.vault],
|
|
4537
|
+
}),
|
|
4538
|
+
).catch(() => {
|
|
4539
|
+
rateFailures.push({
|
|
4540
|
+
chainId: sourceChainId,
|
|
4541
|
+
failure: 'unknown',
|
|
4542
|
+
id: 'earn-apy',
|
|
4543
|
+
operation: 'resolve',
|
|
4544
|
+
})
|
|
4545
|
+
return undefined
|
|
4546
|
+
}),
|
|
4547
|
+
resolveVaultDiscovery(c, {
|
|
4548
|
+
chainId: sourceChainId,
|
|
4549
|
+
include: [],
|
|
4550
|
+
vaultAddress: options.vault,
|
|
4551
|
+
}).catch((cause) => {
|
|
4552
|
+
const failure = Viem.requestFailure(cause)
|
|
4553
|
+
recordFailure(
|
|
4554
|
+
failure
|
|
4555
|
+
? { ...failure, chainId: sourceChainId, id: 'rpc', operation: 'eth_call' }
|
|
4556
|
+
: {
|
|
4557
|
+
chainId: sourceChainId,
|
|
4558
|
+
failure: 'unknown',
|
|
4559
|
+
id: 'earn-vaults',
|
|
4560
|
+
operation: 'getVault',
|
|
4561
|
+
},
|
|
4562
|
+
)
|
|
4563
|
+
return undefined
|
|
4564
|
+
}),
|
|
4565
|
+
])
|
|
4566
|
+
const base = rates?.get(options.vault.toLowerCase())
|
|
4567
|
+
const rateFailure = rateFailures[0]
|
|
4568
|
+
if (rateFailure) recordFailure(rateFailure)
|
|
4569
|
+
if (!base || !discovery) return null
|
|
4570
|
+
return await Timing.time(c, 'earn_rewards_apy', async () => {
|
|
4571
|
+
const [earnFees, record] = await Promise.all([
|
|
4572
|
+
c.get('getClient')(sourceChainId).readContract({
|
|
4573
|
+
abi: Abis.earnVault,
|
|
4574
|
+
address: options.vault,
|
|
4575
|
+
functionName: 'earnFees',
|
|
4576
|
+
}),
|
|
4577
|
+
core_EarnVaults.get(Db.get(c.get('db')), {
|
|
4578
|
+
chainId: options.chainId,
|
|
4579
|
+
vaultAddress: options.vault,
|
|
4580
|
+
}),
|
|
4581
|
+
])
|
|
4582
|
+
// Accounting retains qualified shares for excluded infrastructure, so apply its current exclusions here too.
|
|
4583
|
+
const zoneContracts = [...c.get('zones').values()]
|
|
4584
|
+
.filter((zone) => zone.sourceId === options.chainId)
|
|
4585
|
+
.flatMap((zone) => positionApyContractAddresses(zone.contracts))
|
|
4586
|
+
return RewardRead.positionApy({
|
|
4587
|
+
assetDecimals: discovery.assetToken.decimals,
|
|
4588
|
+
baseNet: base.net,
|
|
4589
|
+
chainId: options.chainId,
|
|
4590
|
+
db: c.get('db'),
|
|
4591
|
+
excludedAddresses: [
|
|
4592
|
+
discovery.engine.address,
|
|
4593
|
+
earnFees,
|
|
4594
|
+
...(record?.zones.map((zone) => zone.earnRouter) ?? []),
|
|
4595
|
+
...zoneContracts,
|
|
4596
|
+
],
|
|
4597
|
+
recipient: options.recipient,
|
|
4598
|
+
shareBalance: options.shareBalance.toString(),
|
|
4599
|
+
value: options.value.toString(),
|
|
4600
|
+
vaultAddress: options.vault,
|
|
4601
|
+
})
|
|
4602
|
+
}).catch((cause) => {
|
|
4603
|
+
recordFailure(
|
|
4604
|
+
sharePriceProviderFailure({ cause, chainId: sourceChainId }) ?? {
|
|
4605
|
+
chainId: options.chainId,
|
|
4606
|
+
failure: 'unknown',
|
|
4607
|
+
id: 'earn-rewards',
|
|
4608
|
+
operation: 'getPositionApy',
|
|
4609
|
+
},
|
|
4610
|
+
)
|
|
4611
|
+
return null
|
|
4612
|
+
})
|
|
4613
|
+
}
|
|
4614
|
+
|
|
4615
|
+
declare namespace resolvePositionApy {
|
|
4616
|
+
/** Current wallet position used to resolve its effective APY. */
|
|
4617
|
+
type Options = {
|
|
4618
|
+
/** Chain containing the vault position. */
|
|
4619
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
4620
|
+
/** Wallet receiving the position yield. */
|
|
4621
|
+
recipient: z.output<typeof Schema.Address>
|
|
4622
|
+
/** Current EarnShare balance. */
|
|
4623
|
+
shareBalance: bigint
|
|
4624
|
+
/** Current asset value of the position. */
|
|
4625
|
+
value: bigint
|
|
4626
|
+
/** EarnVault containing the position. */
|
|
4627
|
+
vault: z.output<typeof Schema.Address>
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
|
|
4631
|
+
function positionApyContractAddresses(contract: unknown): string[] {
|
|
4632
|
+
if (!contract || typeof contract !== 'object') return []
|
|
4633
|
+
const value = contract as Record<string, unknown>
|
|
4634
|
+
const address = value['address']
|
|
4635
|
+
if (typeof address === 'string' && isAddress(address)) return [address]
|
|
4636
|
+
return Object.values(value).flatMap(positionApyContractAddresses)
|
|
4637
|
+
}
|
|
4638
|
+
|
|
3236
4639
|
// Measuring a rate costs indexer boundary queries plus historical quotes against
|
|
3237
4640
|
// an archive node, so an unrequested rate reaches neither.
|
|
3238
4641
|
function resolvePageApy(c: Context<App.Environment>, options: resolvePageApy.Options) {
|
|
@@ -3249,6 +4652,64 @@ function resolvePageApy(c: Context<App.Environment>, options: resolvePageApy.Opt
|
|
|
3249
4652
|
)
|
|
3250
4653
|
}
|
|
3251
4654
|
|
|
4655
|
+
function resolvePageRewards(c: Context<App.Environment>, options: resolvePageRewards.Options) {
|
|
4656
|
+
if (!options.include.includes('apy')) return undefined
|
|
4657
|
+
return Timing.time(c, 'earn_rewards_apy', () =>
|
|
4658
|
+
RewardRead.resolveCollection({
|
|
4659
|
+
chainId: options.chainId,
|
|
4660
|
+
db: c.get('dbCached'),
|
|
4661
|
+
vaults: options.vaults,
|
|
4662
|
+
}).catch(() => {
|
|
4663
|
+
Cache.setPolicy(c, Cache.policies.noStore)
|
|
4664
|
+
const failure = {
|
|
4665
|
+
chainId: options.chainId,
|
|
4666
|
+
failure: 'unknown',
|
|
4667
|
+
id: 'earn-rewards',
|
|
4668
|
+
operation: 'listVaultRewards',
|
|
4669
|
+
} satisfies Log.ProviderFailure
|
|
4670
|
+
c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure])
|
|
4671
|
+
return new Map<string, readonly RewardRead.Reward[]>()
|
|
4672
|
+
}),
|
|
4673
|
+
)
|
|
4674
|
+
}
|
|
4675
|
+
|
|
4676
|
+
function resolveVaultRewards(c: Context<App.Environment>, options: resolveVaultRewards.Options) {
|
|
4677
|
+
if (!options.include.includes('apy')) return undefined
|
|
4678
|
+
return Timing.time(c, 'earn_rewards_apy', () =>
|
|
4679
|
+
RewardRead.get({
|
|
4680
|
+
chainId: options.chainId,
|
|
4681
|
+
db: c.get('dbCached'),
|
|
4682
|
+
vaultAddress: options.vault,
|
|
4683
|
+
}).catch(() => {
|
|
4684
|
+
Cache.setPolicy(c, Cache.policies.noStore)
|
|
4685
|
+
const failure = {
|
|
4686
|
+
chainId: options.chainId,
|
|
4687
|
+
failure: 'unknown',
|
|
4688
|
+
id: 'earn-rewards',
|
|
4689
|
+
operation: 'getVaultRewards',
|
|
4690
|
+
} satisfies Log.ProviderFailure
|
|
4691
|
+
c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure])
|
|
4692
|
+
return undefined
|
|
4693
|
+
}),
|
|
4694
|
+
)
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
declare namespace resolveVaultRewards {
|
|
4698
|
+
type Options = {
|
|
4699
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
4700
|
+
include: z.output<typeof schema.getEarnVault.Query>['include']
|
|
4701
|
+
vault: z.output<typeof Schema.Address>
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4705
|
+
declare namespace resolvePageRewards {
|
|
4706
|
+
type Options = {
|
|
4707
|
+
chainId: z.output<typeof Schema.ChainId>
|
|
4708
|
+
include: z.output<typeof schema.getEarnVault.Query>['include']
|
|
4709
|
+
vaults: readonly z.output<typeof Schema.Address>[]
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
|
|
3252
4713
|
declare namespace resolvePageApy {
|
|
3253
4714
|
type Options = {
|
|
3254
4715
|
chainId: z.output<typeof Schema.ChainId>
|
|
@@ -3351,6 +4812,7 @@ async function resolveVault(c: Context<App.Environment>, options: resolveVault.O
|
|
|
3351
4812
|
}
|
|
3352
4813
|
: null,
|
|
3353
4814
|
record,
|
|
4815
|
+
rewards: options.rewards,
|
|
3354
4816
|
shareToken: getToken(options.tokens, discovery.shareToken.address),
|
|
3355
4817
|
tvl: valued
|
|
3356
4818
|
? {
|
|
@@ -3372,6 +4834,7 @@ declare namespace resolveVault {
|
|
|
3372
4834
|
include: z.output<typeof schema.getEarnVault.Query>['include']
|
|
3373
4835
|
rates: Awaited<ReturnType<typeof Valuation.ratesFor>>
|
|
3374
4836
|
record?: RegistryRecord | undefined
|
|
4837
|
+
rewards?: readonly RewardRead.Reward[] | undefined
|
|
3375
4838
|
snapshot: VerifiedTokens.Snapshot
|
|
3376
4839
|
tokens: Tokens.resolveTokens.ReturnType
|
|
3377
4840
|
zoneRoutes: readonly EarnVaults.ResolvedZoneRoute[]
|
|
@@ -3386,9 +4849,41 @@ export function serializeVault(options: serializeVault.Options): z.output<typeof
|
|
|
3386
4849
|
if (options.include.includes('capabilities') && !discovery.capabilities)
|
|
3387
4850
|
throw new Error('Earn vault capabilities were not resolved.')
|
|
3388
4851
|
const vaultAddress = Schema.Address.parse(discovery.vaultAddress.toLowerCase())
|
|
4852
|
+
const rewards = options.rewards?.map((reward) => ({
|
|
4853
|
+
apr:
|
|
4854
|
+
reward.currentRewardsAprBps === null ? null : RewardRead.ratio(reward.currentRewardsAprBps),
|
|
4855
|
+
asset: reward.asset,
|
|
4856
|
+
...(reward.calculatedThrough !== undefined
|
|
4857
|
+
? { calculatedThrough: reward.calculatedThrough }
|
|
4858
|
+
: {}),
|
|
4859
|
+
campaignId: reward.campaignId,
|
|
4860
|
+
endsAt: reward.endsAt,
|
|
4861
|
+
startsAt: reward.startsAt,
|
|
4862
|
+
targetTotalApr: RewardRead.ratio(reward.targetTotalAprBps),
|
|
4863
|
+
}))
|
|
4864
|
+
const startedRewards = options.rewards?.filter(
|
|
4865
|
+
(reward) => reward.startsAt <= Math.floor(Date.now() / 1_000),
|
|
4866
|
+
)
|
|
4867
|
+
const targetTotalAprBps = startedRewards?.reduce(
|
|
4868
|
+
(target, reward) => Math.max(target, reward.targetTotalAprBps),
|
|
4869
|
+
0,
|
|
4870
|
+
)
|
|
4871
|
+
const apy = options.apy
|
|
4872
|
+
? {
|
|
4873
|
+
...options.apy,
|
|
4874
|
+
net: (() => {
|
|
4875
|
+
if (!startedRewards || startedRewards.length === 0) return options.apy.net
|
|
4876
|
+
const target = targetTotalAprBps ?? 0
|
|
4877
|
+
if (parseUnits(options.apy.net, 6) >= BigInt(target) * 100n) return options.apy.net
|
|
4878
|
+
return RewardRead.ratio(target)
|
|
4879
|
+
})(),
|
|
4880
|
+
...(rewards ? { rewards } : {}),
|
|
4881
|
+
vault: options.apy.net,
|
|
4882
|
+
}
|
|
4883
|
+
: null
|
|
3389
4884
|
return Response.validated(schema.Vault, {
|
|
3390
4885
|
...(options.include.includes('access') ? { access: discovery.access } : {}),
|
|
3391
|
-
...(options.include.includes('apy') ? { apy
|
|
4886
|
+
...(options.include.includes('apy') ? { apy } : {}),
|
|
3392
4887
|
assetToken: options.assetToken,
|
|
3393
4888
|
...(options.include.includes('capabilities') ? { capabilities: discovery.capabilities } : {}),
|
|
3394
4889
|
description: record?.description ?? null,
|
|
@@ -3449,6 +4944,8 @@ export declare namespace serializeVault {
|
|
|
3449
4944
|
instantLiquidityValue: z.output<typeof schema.Vault>['instantLiquidityValue']
|
|
3450
4945
|
/** Curated registry row, when verified. */
|
|
3451
4946
|
record?: core_EarnVaults.Record | undefined
|
|
4947
|
+
/** Enabled, registered Merkle rewards, or undefined when enrichment is unavailable. */
|
|
4948
|
+
rewards?: readonly RewardRead.Reward[] | undefined
|
|
3452
4949
|
/** Resolved share token. */
|
|
3453
4950
|
shareToken: z.output<typeof Tokens.schema.Token>
|
|
3454
4951
|
/** USD value of the assets, or null when unpriced; omitted unless `include` carries `tvl`. */
|
|
@@ -3517,6 +5014,8 @@ async function queryDeployments(
|
|
|
3517
5014
|
c: Context<App.Environment>,
|
|
3518
5015
|
options: queryDeployments.Options,
|
|
3519
5016
|
): Promise<queryDeployments.Result> {
|
|
5017
|
+
const factories = deploymentFactories[options.chainId] ?? []
|
|
5018
|
+
if (factories.length === 0) return { hasMore: false, items: [] }
|
|
3520
5019
|
const filters: string[] = []
|
|
3521
5020
|
if (options.asset) filters.push(`lower(asset) = '${options.asset.toLowerCase()}'`)
|
|
3522
5021
|
if (options.cursor)
|
|
@@ -3535,7 +5034,8 @@ async function queryDeployments(
|
|
|
3535
5034
|
]),
|
|
3536
5035
|
)
|
|
3537
5036
|
|
|
3538
|
-
//
|
|
5037
|
+
// Authenticate emitters before deduplication so a forged newer event cannot
|
|
5038
|
+
// replace a factory deployment or suppress it through outer filters.
|
|
3539
5039
|
const result = await c
|
|
3540
5040
|
.get('getTidx')(options.chainId)
|
|
3541
5041
|
.fetch({
|
|
@@ -3550,6 +5050,7 @@ async function queryDeployments(
|
|
|
3550
5050
|
block_num,
|
|
3551
5051
|
log_idx
|
|
3552
5052
|
FROM EarnStackDeployed
|
|
5053
|
+
WHERE address IN (${factories.map((address) => `'${address}'`).join(', ')})
|
|
3553
5054
|
ORDER BY block_num DESC, log_idx DESC
|
|
3554
5055
|
LIMIT 1 BY lower("earnVault")
|
|
3555
5056
|
)
|
|
@@ -3664,3 +5165,19 @@ class IndexedCoverageError extends Error {
|
|
|
3664
5165
|
super(`Indexed history does not yet cover ${asOf}.`)
|
|
3665
5166
|
}
|
|
3666
5167
|
}
|
|
5168
|
+
|
|
5169
|
+
class ZoneHistoricalAlignmentError extends Error {
|
|
5170
|
+
override name = 'Earn.ZoneHistoricalAlignmentError'
|
|
5171
|
+
|
|
5172
|
+
constructor() {
|
|
5173
|
+
super('This Zone does not expose historical parent-chain synchronization checkpoints.')
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5176
|
+
|
|
5177
|
+
class ZoneEarningsUnsupportedError extends Error {
|
|
5178
|
+
override name = 'Earn.ZoneEarningsUnsupportedError'
|
|
5179
|
+
|
|
5180
|
+
constructor() {
|
|
5181
|
+
super('Zone positions do not support the earnings include.')
|
|
5182
|
+
}
|
|
5183
|
+
}
|