tapimo 0.7.0 → 0.7.2
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/dist/ApiKeys.d.ts +24 -7
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +17 -5
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12104 -7861
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +191 -128
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +10 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +17 -4
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +19 -8
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +25 -9
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +1 -1
- package/dist/admin/App.d.ts +601 -20
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +12 -2
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +94 -11
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +141 -32
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +1069 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
- package/dist/admin/apps/earn-vaults.js +409 -0
- package/dist/admin/apps/earn-vaults.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +166 -166
- 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 +151 -95
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +2 -0
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +18 -2
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +22 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +59 -39
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/Zones.d.ts +8335 -0
- package/dist/apps/Zones.d.ts.map +1 -0
- package/dist/apps/Zones.js +38 -0
- package/dist/apps/Zones.js.map +1 -0
- package/dist/apps/data/App.d.ts +14377 -10165
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +91 -19
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +1 -1
- package/dist/apps/data/FxOracle.d.ts.map +1 -1
- package/dist/apps/data/index.d.ts +0 -1
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +0 -1
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +32 -32
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +130 -65
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +312 -312
- package/dist/apps/data/routes/balances.d.ts +18 -18
- package/dist/apps/data/routes/balances.js +5 -5
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +176 -176
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
- package/dist/apps/data/routes/coingecko.js +62 -35
- package/dist/apps/data/routes/coingecko.js.map +1 -1
- package/dist/apps/data/routes/earn.d.ts +2144 -0
- package/dist/apps/data/routes/earn.d.ts.map +1 -0
- package/dist/apps/data/routes/earn.js +947 -0
- package/dist/apps/data/routes/earn.js.map +1 -0
- package/dist/apps/data/routes/exchanges.d.ts +1231 -324
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +656 -193
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +59 -8
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/funding.d.ts +4092 -387
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +1403 -256
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +5 -5
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +19 -2
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +265 -265
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +11 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +5 -5
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +211 -22
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +36 -36
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +49 -9
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +116 -88
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +198 -91
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +55 -55
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +78 -39
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +78 -29
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +165 -67
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +10 -10
- package/dist/apps/data/routes/valuation.js +2 -2
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +34 -9
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +5 -3
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +175 -65
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +281 -0
- package/dist/apps/data/routes/zones.d.ts.map +1 -0
- package/dist/apps/data/routes/zones.js +252 -0
- package/dist/apps/data/routes/zones.js.map +1 -0
- package/dist/apps/docs/reference.js +6 -5
- package/dist/apps/docs/reference.js.map +1 -1
- package/dist/apps/index.d.ts +2 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +2 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +670 -670
- package/dist/apps/management/Billing.d.ts +8 -0
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +12 -0
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/Error.d.ts +12 -0
- package/dist/apps/management/Error.d.ts.map +1 -0
- package/dist/apps/management/Error.js +10 -0
- package/dist/apps/management/Error.js.map +1 -0
- package/dist/apps/management/routes/api-keys.d.ts +5 -5
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +2 -8
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +119 -119
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/invitations.d.ts +62 -62
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +4 -10
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +30 -30
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +78 -78
- package/dist/apps/management/routes/orgs.d.ts +48 -48
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +2 -8
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +9 -9
- package/dist/apps/management/routes/scopes.js +2 -2
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +80 -80
- package/dist/apps/management/routes/verified-token-requests.d.ts +36 -36
- package/dist/apps/management/routes/webhooks.d.ts +50 -50
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +15 -3
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/App.d.ts +55 -56
- package/dist/apps/mpp/App.d.ts.map +1 -1
- package/dist/apps/mpp/App.js +192 -27
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/Mpp.d.ts +0 -20
- package/dist/apps/mpp/Mpp.d.ts.map +1 -1
- package/dist/apps/mpp/Mpp.js +0 -24
- package/dist/apps/mpp/Mpp.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Adapter.js +66 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -0
- package/dist/apps/mpp/internal/Error.d.ts +4 -0
- package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Error.js +41 -0
- package/dist/apps/mpp/internal/Error.js.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.js +28 -0
- package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
- package/dist/apps/mpp/internal/Policy.d.ts +46 -0
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Policy.js +57 -0
- package/dist/apps/mpp/internal/Policy.js.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.js +18 -0
- package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
- package/dist/apps/mpp/internal/Screening.d.ts +35 -0
- package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Screening.js +20 -0
- package/dist/apps/mpp/internal/Screening.js.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.js +103 -0
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
- package/dist/apps/mpp/internal/Utils.d.ts +7 -0
- package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Utils.js +24 -0
- package/dist/apps/mpp/internal/Utils.js.map +1 -0
- package/dist/apps/relay/App.js +184 -24
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +4 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +16 -7
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/db/Db.d.ts +20 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +342 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +921 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +269 -1
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +68 -0
- package/dist/db/tables/earnVaults.d.ts.map +1 -0
- package/dist/db/tables/earnVaults.js +72 -0
- package/dist/db/tables/earnVaults.js.map +1 -0
- package/dist/db/tables/fundingCatalog.d.ts +56 -0
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
- package/dist/db/tables/fundingCatalog.js +85 -0
- package/dist/db/tables/fundingCatalog.js.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts +159 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.js +206 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
- package/dist/db/tables/fundingDeposits.d.ts +115 -0
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
- package/dist/db/tables/fundingDeposits.js +100 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -0
- package/dist/db/tables/fundingIdempotency.d.ts +91 -0
- package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
- package/dist/db/tables/fundingIdempotency.js +103 -0
- package/dist/db/tables/fundingIdempotency.js.map +1 -0
- package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
- package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferEvents.js +18 -0
- package/dist/db/tables/fundingTransferEvents.js.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.js +27 -0
- package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
- package/dist/db/tables/fundingTransfers.d.ts +82 -0
- package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
- package/dist/db/tables/fundingTransfers.js +89 -0
- package/dist/db/tables/fundingTransfers.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +8 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +35 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +8 -0
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +16 -0
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +13 -0
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js +16 -0
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +4 -2
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +14 -4
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/users.d.ts +8 -0
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +16 -0
- package/dist/db/tables/users.js.map +1 -1
- package/dist/db/tables/verifiedTokens.d.ts +14 -7
- package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
- package/dist/db/tables/verifiedTokens.js +9 -7
- package/dist/db/tables/verifiedTokens.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +24 -3
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/relay.js +108 -108
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +26 -0
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +35 -2
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +16 -10
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/Cursor.js +1 -1
- package/dist/internal/Cursor.js.map +1 -1
- package/dist/internal/EarnRates.d.ts +89 -0
- package/dist/internal/EarnRates.d.ts.map +1 -0
- package/dist/internal/EarnRates.js +266 -0
- package/dist/internal/EarnRates.js.map +1 -0
- package/dist/internal/EarnVaults.d.ts +171 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -0
- package/dist/internal/EarnVaults.js +547 -0
- package/dist/internal/EarnVaults.js.map +1 -0
- package/dist/internal/EdgeCache.d.ts +9 -2
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +36 -9
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/Id.d.ts +11 -0
- package/dist/internal/Id.d.ts.map +1 -1
- package/dist/internal/Id.js +13 -0
- package/dist/internal/Id.js.map +1 -1
- package/dist/internal/Idempotency.d.ts +83 -0
- package/dist/internal/Idempotency.d.ts.map +1 -0
- package/dist/internal/Idempotency.js +113 -0
- package/dist/internal/Idempotency.js.map +1 -0
- package/dist/internal/Log.d.ts +64 -9
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +29 -7
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +47 -1
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +1 -1
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Provider.d.ts +14 -0
- package/dist/internal/Provider.d.ts.map +1 -0
- package/dist/internal/Provider.js +5 -0
- package/dist/internal/Provider.js.map +1 -0
- package/dist/internal/Schema.d.ts +8 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +24 -13
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +6 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +35 -0
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +43 -24
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +79 -11
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Viem.d.ts +82 -65
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +83 -12
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +34 -28
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +9 -0
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +15 -10
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/exchange/Provider.d.ts +219 -0
- package/dist/internal/exchange/Provider.d.ts.map +1 -0
- package/dist/internal/exchange/Provider.js +117 -0
- package/dist/internal/exchange/Provider.js.map +1 -0
- package/dist/internal/exchange/index.d.ts +2 -0
- package/dist/internal/exchange/index.d.ts.map +1 -0
- package/dist/internal/exchange/index.js +2 -0
- package/dist/internal/exchange/index.js.map +1 -0
- package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
- package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
- package/dist/internal/exchange/providers/uniswap.js +553 -0
- package/dist/internal/exchange/providers/uniswap.js.map +1 -0
- package/dist/internal/funding/Action.d.ts +55 -0
- package/dist/internal/funding/Action.d.ts.map +1 -0
- package/dist/internal/funding/Action.js +74 -0
- package/dist/internal/funding/Action.js.map +1 -0
- package/dist/internal/funding/Catalog.d.ts +107 -0
- package/dist/internal/funding/Catalog.d.ts.map +1 -0
- package/dist/internal/funding/Catalog.js +270 -0
- package/dist/internal/funding/Catalog.js.map +1 -0
- package/dist/internal/funding/Chain.d.ts +76 -0
- package/dist/internal/funding/Chain.d.ts.map +1 -0
- package/dist/internal/funding/Chain.js +38 -0
- package/dist/internal/funding/Chain.js.map +1 -0
- package/dist/internal/funding/Deposit.d.ts +366 -0
- package/dist/internal/funding/Deposit.d.ts.map +1 -0
- package/dist/internal/funding/Deposit.js +286 -0
- package/dist/internal/funding/Deposit.js.map +1 -0
- package/dist/internal/funding/DepositAddress.d.ts +345 -0
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
- package/dist/internal/funding/DepositAddress.js +189 -0
- package/dist/internal/funding/DepositAddress.js.map +1 -0
- package/dist/internal/funding/Evidence.d.ts +52 -0
- package/dist/internal/funding/Evidence.d.ts.map +1 -0
- package/dist/internal/funding/Evidence.js +314 -0
- package/dist/internal/funding/Evidence.js.map +1 -0
- package/dist/internal/funding/Provider.d.ts +1186 -0
- package/dist/internal/funding/Provider.d.ts.map +1 -0
- package/dist/internal/funding/Provider.js +1081 -0
- package/dist/internal/funding/Provider.js.map +1 -0
- package/dist/internal/funding/Reconciliation.d.ts +113 -0
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
- package/dist/internal/funding/Reconciliation.js +676 -0
- package/dist/internal/funding/Reconciliation.js.map +1 -0
- package/dist/internal/funding/Route.d.ts +21 -0
- package/dist/internal/funding/Route.d.ts.map +1 -0
- package/dist/internal/funding/Route.js +5 -0
- package/dist/internal/funding/Route.js.map +1 -0
- package/dist/internal/funding/Subsidy.d.ts +113 -0
- package/dist/internal/funding/Subsidy.d.ts.map +1 -0
- package/dist/internal/funding/Subsidy.js +138 -0
- package/dist/internal/funding/Subsidy.js.map +1 -0
- package/dist/internal/funding/Token.d.ts +41 -0
- package/dist/internal/funding/Token.d.ts.map +1 -0
- package/dist/internal/funding/Token.js +22 -0
- package/dist/internal/funding/Token.js.map +1 -0
- package/dist/internal/funding/Transfer.d.ts +643 -0
- package/dist/internal/funding/Transfer.d.ts.map +1 -0
- package/dist/internal/funding/Transfer.js +332 -0
- package/dist/internal/funding/Transfer.js.map +1 -0
- package/dist/internal/funding/index.d.ts +13 -0
- package/dist/internal/funding/index.d.ts.map +1 -0
- package/dist/internal/funding/index.js +13 -0
- package/dist/internal/funding/index.js.map +1 -0
- package/dist/internal/funding/providers/across.d.ts +21 -0
- package/dist/internal/funding/providers/across.d.ts.map +1 -0
- package/dist/internal/funding/providers/across.js +117 -0
- package/dist/internal/funding/providers/across.js.map +1 -0
- package/dist/internal/funding/providers/relay.d.ts +46 -0
- package/dist/internal/funding/providers/relay.d.ts.map +1 -0
- package/dist/internal/funding/providers/relay.js +464 -0
- package/dist/internal/funding/providers/relay.js.map +1 -0
- package/dist/internal/funding/providers/rhino.d.ts +15 -0
- package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
- package/dist/internal/funding/providers/rhino.js +116 -0
- package/dist/internal/funding/providers/rhino.js.map +1 -0
- package/dist/internal/funding/providers/squid.d.ts +19 -0
- package/dist/internal/funding/providers/squid.d.ts.map +1 -0
- package/dist/internal/funding/providers/squid.js +120 -0
- package/dist/internal/funding/providers/squid.js.map +1 -0
- package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
- package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
- package/dist/internal/funding/providers/symbiosis.js +176 -0
- package/dist/internal/funding/providers/symbiosis.js.map +1 -0
- package/dist/internal/index.d.ts +5 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +5 -1
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/url.js +61 -57
- package/dist/internal/webhookDestinations/url.js.map +1 -1
- package/dist/providers/index.d.ts +43 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +19 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +9 -4
- package/src/ApiKeys.test.ts +11 -7
- package/src/ApiKeys.ts +37 -9
- package/src/App.test.ts +85 -10
- package/src/App.ts +224 -137
- package/src/Assets.ts +29 -4
- package/src/Client.test-d.ts +650 -30
- package/src/Scope.test.ts +19 -0
- package/src/Scope.ts +28 -11
- package/src/Webhooks.test.ts +25 -0
- package/src/Webhooks.ts +1 -1
- package/src/admin/App.test.ts +9 -2
- package/src/admin/App.ts +32 -9
- package/src/admin/apps/api-keys.test.ts +167 -23
- package/src/admin/apps/api-keys.ts +166 -28
- package/src/admin/apps/earn-vaults.test.ts +338 -0
- package/src/admin/apps/earn-vaults.ts +572 -0
- package/src/admin/apps/scopes.test.ts +16 -1
- package/src/admin/ui/plugin.ts +2 -2
- package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
- package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
- package/src/admin/ui/src/components/Page.tsx +1 -1
- package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
- package/src/admin/ui/src/lib/api-keys.ts +37 -7
- package/src/admin/ui/src/lib/client.ts +1 -1
- package/src/admin/ui/src/lib/config.ts +1 -1
- package/src/admin/ui/src/lib/early-access.ts +8 -9
- package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
- package/src/admin/ui/src/lib/format.ts +13 -0
- package/src/admin/ui/src/lib/organizations.test.ts +14 -4
- package/src/admin/ui/src/lib/organizations.ts +7 -1
- package/src/admin/ui/src/lib/response.ts +22 -0
- package/src/admin/ui/src/lib/scopes.test.ts +19 -11
- package/src/admin/ui/src/lib/scopes.ts +28 -7
- package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
- package/src/admin/ui/src/routeTree.gen.ts +70 -7
- package/src/admin/ui/src/router.tsx +2 -2
- package/src/admin/ui/src/routes/__root.tsx +9 -8
- package/src/admin/ui/src/routes/api-keys.tsx +475 -64
- package/src/admin/ui/src/routes/early-access.tsx +5 -12
- package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
- package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
- package/src/admin/ui/src/routes/organizations.tsx +4 -7
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
- package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
- package/src/admin/ui/vite.config.ts +4 -1
- package/src/admin/ui.generated.ts +189 -95
- package/src/analytics/Analytics.test.ts +69 -10
- package/src/analytics/Analytics.ts +20 -1
- package/src/analytics/tables/requestEvents.ts +79 -37
- package/src/apps/Zones.test.ts +33 -0
- package/src/apps/Zones.ts +40 -0
- package/src/apps/composition.test.ts +84 -1
- package/src/apps/data/App.test.ts +38 -9
- package/src/apps/data/App.ts +96 -33
- package/src/apps/data/FxOracle.ts +1 -1
- package/src/apps/data/index.ts +0 -1
- package/src/apps/data/routes/activities.test.ts +82 -6
- package/src/apps/data/routes/activities.ts +131 -71
- package/src/apps/data/routes/balances.test.ts +50 -37
- package/src/apps/data/routes/balances.ts +5 -5
- package/src/apps/data/routes/blocks.test.ts +2 -0
- package/src/apps/data/routes/coingecko.test.ts +22 -0
- package/src/apps/data/routes/coingecko.ts +84 -48
- package/src/apps/data/routes/earn.test.ts +1108 -0
- package/src/apps/data/routes/earn.ts +1391 -0
- package/src/apps/data/routes/exchanges.test.ts +82 -33
- package/src/apps/data/routes/exchanges.ts +842 -227
- package/src/apps/data/routes/fee-amm.test.ts +4 -6
- package/src/apps/data/routes/fee-amm.ts +69 -12
- package/src/apps/data/routes/funding.test.ts +2712 -221
- package/src/apps/data/routes/funding.ts +1604 -387
- package/src/apps/data/routes/indexer.test.ts +43 -34
- package/src/apps/data/routes/indexer.ts +19 -2
- package/src/apps/data/routes/receipts.test.ts +5 -3
- package/src/apps/data/routes/receipts.ts +13 -11
- package/src/apps/data/routes/rpc.test.ts +446 -28
- package/src/apps/data/routes/rpc.ts +243 -25
- package/src/apps/data/routes/tokenlist.test.ts +15 -0
- package/src/apps/data/routes/tokenlist.ts +88 -22
- package/src/apps/data/routes/tokens.ts +262 -86
- package/src/apps/data/routes/transactions.test.ts +2 -0
- package/src/apps/data/routes/transactions.ts +77 -42
- package/src/apps/data/routes/transfers.test.ts +166 -4
- package/src/apps/data/routes/transfers.ts +216 -78
- package/src/apps/data/routes/valuation.test.ts +62 -9
- package/src/apps/data/routes/valuation.ts +2 -2
- package/src/apps/data/routes/verified-tokens.test.ts +51 -0
- package/src/apps/data/routes/verified-tokens.ts +52 -15
- package/src/apps/data/routes/webhooks.test.ts +432 -33
- package/src/apps/data/routes/webhooks.ts +189 -79
- package/src/apps/data/routes/zones.test.ts +473 -0
- package/src/apps/data/routes/zones.ts +338 -0
- package/src/apps/docs/reference.ts +8 -6
- package/src/apps/index.ts +2 -1
- package/src/apps/management/Billing.test.ts +29 -0
- package/src/apps/management/Billing.ts +23 -0
- package/src/apps/management/Error.ts +12 -0
- package/src/apps/management/routes/api-keys.test.ts +5 -3
- package/src/apps/management/routes/api-keys.ts +2 -9
- package/src/apps/management/routes/invitations.ts +4 -11
- package/src/apps/management/routes/orgs.ts +2 -9
- package/src/apps/management/routes/scopes.test.ts +7 -2
- package/src/apps/management/routes/scopes.ts +2 -2
- package/src/apps/management/routes/webhooks.test.ts +6 -1
- package/src/apps/management/routes/webhooks.ts +15 -3
- package/src/apps/mpp/App.ts +276 -29
- package/src/apps/mpp/Mpp.test.ts +631 -26
- package/src/apps/mpp/Mpp.ts +0 -42
- package/src/apps/mpp/internal/Adapter.ts +108 -3
- package/src/apps/mpp/internal/Error.test.ts +33 -0
- package/src/apps/mpp/internal/Error.ts +44 -6
- package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
- package/src/apps/mpp/internal/Idempotency.ts +59 -5
- package/src/apps/mpp/internal/Policy.test.ts +122 -0
- package/src/apps/mpp/internal/Policy.ts +98 -0
- package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
- package/src/apps/mpp/internal/ScreenManager.ts +41 -0
- package/src/apps/mpp/internal/Screening.ts +40 -3
- package/src/apps/mpp/internal/Sponsorship.ts +144 -0
- package/src/apps/mpp/internal/Utils.ts +30 -0
- package/src/apps/relay/App.test.ts +495 -64
- package/src/apps/relay/App.ts +234 -24
- package/src/apps/relay/Sponsorships.test.ts +51 -0
- package/src/apps/relay/Sponsorships.ts +19 -7
- package/src/db/Db.ts +439 -0
- package/src/db/Schema.ts +325 -2
- package/src/db/tables/earnVaults.test.ts +185 -0
- package/src/db/tables/earnVaults.ts +151 -0
- package/src/db/tables/fundingCatalog.test.ts +108 -0
- package/src/db/tables/fundingCatalog.ts +157 -0
- package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
- package/src/db/tables/fundingDepositAddresses.ts +376 -0
- package/src/db/tables/fundingDeposits.test.ts +261 -0
- package/src/db/tables/fundingDeposits.ts +229 -0
- package/src/db/tables/fundingIdempotency.test.ts +182 -0
- package/src/db/tables/fundingIdempotency.ts +180 -0
- package/src/db/tables/fundingTransferEvents.ts +28 -0
- package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
- package/src/db/tables/fundingTransferTransactions.ts +37 -0
- package/src/db/tables/fundingTransfers.test.ts +89 -0
- package/src/db/tables/fundingTransfers.ts +153 -0
- package/src/db/tables/organizations.test.ts +88 -0
- package/src/db/tables/organizations.ts +42 -1
- package/src/db/tables/projects.ts +16 -0
- package/src/db/tables/requestUsage.ts +23 -0
- package/src/db/tables/sponsoredTransactions.test.ts +52 -2
- package/src/db/tables/sponsoredTransactions.ts +18 -6
- package/src/db/tables/users.ts +16 -0
- package/src/db/tables/verifiedTokens.ts +19 -14
- package/src/db/tables/webhookSubscriptions.ts +58 -3
- package/src/handlers/relay.test.ts +2 -0
- package/src/handlers/relay.ts +95 -99
- package/src/internal/Auth.test.ts +48 -0
- package/src/internal/Auth.ts +61 -2
- package/src/internal/Cache.ts +13 -9
- package/src/internal/Cursor.test.ts +2 -2
- package/src/internal/Cursor.ts +1 -1
- package/src/internal/EarnRates.test.ts +125 -0
- package/src/internal/EarnRates.ts +409 -0
- package/src/internal/EarnVaults.test.ts +195 -0
- package/src/internal/EarnVaults.ts +876 -0
- package/src/internal/EdgeCache.test.ts +37 -5
- package/src/internal/EdgeCache.ts +39 -7
- package/src/internal/Id.ts +14 -0
- package/src/internal/Idempotency.test.ts +109 -0
- package/src/internal/Idempotency.ts +237 -0
- package/src/internal/Log.test-d.ts +41 -8
- package/src/internal/Log.test.ts +189 -8
- package/src/internal/Log.ts +124 -17
- package/src/internal/MetricSink.test.ts +244 -4
- package/src/internal/MetricSink.ts +51 -1
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Provider.test.ts +17 -0
- package/src/internal/Provider.ts +17 -0
- package/src/internal/Schema.test.ts +13 -0
- package/src/internal/Schema.ts +41 -24
- package/src/internal/Store.test.ts +25 -0
- package/src/internal/Store.ts +46 -0
- package/src/internal/Tidx.local.test.ts +78 -3
- package/src/internal/Tidx.test.ts +212 -18
- package/src/internal/Tidx.ts +112 -32
- package/src/internal/VerifiedTokens.test.ts +15 -0
- package/src/internal/Viem.test.ts +170 -17
- package/src/internal/Viem.ts +111 -28
- package/src/internal/WebhookDestination.ts +25 -23
- package/src/internal/Webhooks.test.ts +59 -0
- package/src/internal/Webhooks.ts +34 -10
- package/src/internal/exchange/Provider.test.ts +216 -0
- package/src/internal/exchange/Provider.ts +326 -0
- package/src/internal/exchange/index.test.ts +6 -0
- package/src/internal/exchange/index.ts +1 -0
- package/src/internal/exchange/providers/uniswap.test.ts +122 -0
- package/src/internal/exchange/providers/uniswap.ts +682 -0
- package/src/internal/funding/Action.test.ts +138 -0
- package/src/internal/funding/Action.ts +117 -0
- package/src/internal/funding/Catalog.test.ts +311 -0
- package/src/internal/funding/Catalog.ts +347 -0
- package/src/internal/funding/Chain.test.ts +79 -0
- package/src/internal/funding/Chain.ts +120 -0
- package/src/internal/funding/Deposit.test.ts +26 -0
- package/src/internal/funding/Deposit.ts +453 -0
- package/src/internal/funding/DepositAddress.test.ts +18 -0
- package/src/internal/funding/DepositAddress.ts +312 -0
- package/src/internal/funding/Evidence.test.ts +297 -0
- package/src/internal/funding/Evidence.ts +430 -0
- package/src/internal/funding/Provider.test.ts +1328 -0
- package/src/internal/funding/Provider.ts +1796 -0
- package/src/internal/funding/Reconciliation.local.test.ts +504 -0
- package/src/internal/funding/Reconciliation.test.ts +2020 -0
- package/src/internal/funding/Reconciliation.ts +930 -0
- package/src/internal/funding/Route.test.ts +66 -0
- package/src/internal/funding/Route.ts +29 -0
- package/src/internal/funding/Subsidy.local.test.ts +152 -0
- package/src/internal/funding/Subsidy.test.ts +75 -0
- package/src/internal/funding/Subsidy.ts +260 -0
- package/src/internal/funding/Token.test.ts +47 -0
- package/src/internal/funding/Token.ts +59 -0
- package/src/internal/funding/Transfer.test.ts +369 -0
- package/src/internal/funding/Transfer.ts +522 -0
- package/src/internal/funding/index.test.ts +20 -0
- package/src/internal/funding/index.ts +12 -0
- package/src/internal/funding/providers/across.ts +149 -0
- package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
- package/src/internal/funding/providers/relay.test.ts +474 -0
- package/src/internal/funding/providers/relay.ts +559 -0
- package/src/internal/funding/providers/rhino.ts +139 -0
- package/src/internal/funding/providers/squid.ts +151 -0
- package/src/internal/funding/providers/symbiosis.ts +221 -0
- package/src/internal/index.test.ts +5 -1
- package/src/internal/index.ts +5 -1
- package/src/internal/webhookDestinations/url.ts +49 -45
- package/src/providers/index.test.ts +14 -0
- package/src/providers/index.ts +54 -0
- package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
- package/dist/apps/data/FundingQuoteProviders.js +0 -775
- package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
- package/dist/internal/FundingQuotes.d.ts +0 -864
- package/dist/internal/FundingQuotes.d.ts.map +0 -1
- package/dist/internal/FundingQuotes.js +0 -672
- package/dist/internal/FundingQuotes.js.map +0 -1
- package/src/apps/data/FundingQuoteProviders.ts +0 -1043
- package/src/internal/FundingQuotes.test.ts +0 -456
- package/src/internal/FundingQuotes.ts +0 -944
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
/** @module-tag localnet */
|
|
2
|
+
|
|
1
3
|
import type * as z from 'zod/mini'
|
|
2
4
|
import { Value as core_Value } from 'ox'
|
|
3
5
|
import { Db, Schema } from 'tapimo'
|
|
4
6
|
import { FxOracle } from 'tapimo/apps'
|
|
7
|
+
import { Addresses } from 'viem/tempo'
|
|
5
8
|
|
|
6
9
|
import * as TestApp from '../../../../test/App.js'
|
|
7
10
|
import * as Runtime from '../../../../test/runtime.js'
|
|
@@ -32,6 +35,50 @@ describe('GET /transfers', () => {
|
|
|
32
35
|
expect(Transfers.schema.getTransfers.Query.safeParse({ include: 'token' }).success).toBe(false)
|
|
33
36
|
})
|
|
34
37
|
|
|
38
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
39
|
+
'excludes historical non-TIP-20 transfers for affected mainnet accounts',
|
|
40
|
+
async () => {
|
|
41
|
+
const client = TestApp.client()
|
|
42
|
+
const cases = [
|
|
43
|
+
{
|
|
44
|
+
address: Schema.Address.parse('0xad511ba481696d73bcf47d411ad9ea4f77023ddc'),
|
|
45
|
+
blockNumber: '17681311',
|
|
46
|
+
expectedCount: 1,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
address: Schema.Address.parse('0x5eb391a6c707ae1168989bbc6c5f5db4a0e06837'),
|
|
50
|
+
blockNumber: '31227810',
|
|
51
|
+
expectedCount: 0,
|
|
52
|
+
},
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
for (const { address, blockNumber, expectedCount } of cases) {
|
|
56
|
+
const response = await client.v1.transfers.$get(
|
|
57
|
+
{
|
|
58
|
+
query: {
|
|
59
|
+
address,
|
|
60
|
+
'blockNumber.from': blockNumber,
|
|
61
|
+
'blockNumber.to': blockNumber,
|
|
62
|
+
chainId: '4217',
|
|
63
|
+
include: 'totalCount',
|
|
64
|
+
limit: '10',
|
|
65
|
+
page: '1',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
TestApp.auth,
|
|
69
|
+
)
|
|
70
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
71
|
+
|
|
72
|
+
expect(response.status).toBe(200)
|
|
73
|
+
expect(body.data).toHaveLength(expectedCount)
|
|
74
|
+
expect(body.data.every((entry) => entry.sourceToken.address.startsWith('0x20c0'))).toBe(
|
|
75
|
+
true,
|
|
76
|
+
)
|
|
77
|
+
expect(body.meta?.totalCount).toBe(expectedCount)
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
)
|
|
81
|
+
|
|
35
82
|
test('degrades unavailable verification data to null valuations', async () => {
|
|
36
83
|
const db = () =>
|
|
37
84
|
Db.postgres({
|
|
@@ -63,9 +110,9 @@ describe('GET /transfers', () => {
|
|
|
63
110
|
const unsupportedResponse = await client.v1.transfers.$get(
|
|
64
111
|
{
|
|
65
112
|
query: {
|
|
66
|
-
denomination: 'JPY',
|
|
67
113
|
limit: '5',
|
|
68
114
|
token: TestApp.tokenWithHolders,
|
|
115
|
+
'valuation.currency': 'JPY',
|
|
69
116
|
},
|
|
70
117
|
},
|
|
71
118
|
TestApp.auth,
|
|
@@ -666,7 +713,7 @@ describe('GET /transfers', () => {
|
|
|
666
713
|
amount: core_Value.format(BigInt(entry.sourceAmount.baseUnits), 6),
|
|
667
714
|
currency: 'USD',
|
|
668
715
|
})
|
|
669
|
-
expect(body.meta?.
|
|
716
|
+
expect(body.meta?.valuation).toBeUndefined()
|
|
670
717
|
})
|
|
671
718
|
|
|
672
719
|
test('values transfer legs in a requested denomination', async () => {
|
|
@@ -676,7 +723,13 @@ describe('GET /transfers', () => {
|
|
|
676
723
|
|
|
677
724
|
// Denominations are case-insensitive.
|
|
678
725
|
const response = await client.v1.transfers.$get(
|
|
679
|
-
{
|
|
726
|
+
{
|
|
727
|
+
query: {
|
|
728
|
+
limit: '5',
|
|
729
|
+
token: TestApp.tokenWithHolders,
|
|
730
|
+
'valuation.currency': 'aud',
|
|
731
|
+
},
|
|
732
|
+
},
|
|
680
733
|
TestApp.auth,
|
|
681
734
|
)
|
|
682
735
|
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
@@ -689,7 +742,7 @@ describe('GET /transfers', () => {
|
|
|
689
742
|
amount: core_Value.format((BigInt(entry.sourceAmount.baseUnits) * 16n) / 10n, 6),
|
|
690
743
|
currency: 'AUD',
|
|
691
744
|
})
|
|
692
|
-
expect(body.meta?.
|
|
745
|
+
expect(body.meta?.valuation).toMatchInlineSnapshot(`
|
|
693
746
|
{
|
|
694
747
|
"asOf": "2026-01-01T00:00:00.000Z",
|
|
695
748
|
"basis": "nominal",
|
|
@@ -751,3 +804,112 @@ describe('GET /transfers', () => {
|
|
|
751
804
|
`)
|
|
752
805
|
})
|
|
753
806
|
})
|
|
807
|
+
|
|
808
|
+
describe('collate', () => {
|
|
809
|
+
/** A minimal transfer row at a `(block, log index)` position. */
|
|
810
|
+
const row = (block: number, logIndex: number) => ({
|
|
811
|
+
block_num: block,
|
|
812
|
+
log_idx: logIndex,
|
|
813
|
+
tx_hash: `0x${'cc'.repeat(32)}`,
|
|
814
|
+
})
|
|
815
|
+
|
|
816
|
+
test('passes a lone engine-paged stream through untouched', () => {
|
|
817
|
+
const rows = [row(40, 4), row(20, 2)]
|
|
818
|
+
expect(
|
|
819
|
+
Transfers.collate([{ rows, sample: false }], { limit: 3, offset: 0, order: 'desc' }),
|
|
820
|
+
).toEqual({
|
|
821
|
+
capped: false,
|
|
822
|
+
rows,
|
|
823
|
+
})
|
|
824
|
+
})
|
|
825
|
+
|
|
826
|
+
test('merges split streams: dedupes, orders globally, applies the window', () => {
|
|
827
|
+
const shared = row(30, 3)
|
|
828
|
+
const { capped, rows } = Transfers.collate(
|
|
829
|
+
[
|
|
830
|
+
{ rows: [row(40, 4), shared], sample: false },
|
|
831
|
+
{ rows: [{ ...shared }, row(10, 1)], sample: false },
|
|
832
|
+
],
|
|
833
|
+
{ limit: 2, offset: 1, order: 'desc' },
|
|
834
|
+
)
|
|
835
|
+
expect(capped).toBe(false)
|
|
836
|
+
expect(rows.map((entry) => entry['block_num'])).toEqual([30, 10])
|
|
837
|
+
})
|
|
838
|
+
|
|
839
|
+
test('orders and pages a below-cap fallback sample', () => {
|
|
840
|
+
const { capped, rows } = Transfers.collate([{ rows: [row(10, 1), row(30, 3)], sample: true }], {
|
|
841
|
+
limit: 2,
|
|
842
|
+
offset: 0,
|
|
843
|
+
order: 'desc',
|
|
844
|
+
})
|
|
845
|
+
expect(capped).toBe(false)
|
|
846
|
+
expect(rows.map((entry) => entry['block_num'])).toEqual([30, 10])
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
test('flags a fallback sample that hit the cap', () => {
|
|
850
|
+
const sample = Array.from({ length: Schema.countCap }, (_, index) => row(index + 1, index))
|
|
851
|
+
const { capped, rows } = Transfers.collate(
|
|
852
|
+
[
|
|
853
|
+
{ rows: [row(40_000, 20_000)], sample: false },
|
|
854
|
+
{ rows: sample, sample: true },
|
|
855
|
+
],
|
|
856
|
+
{ limit: 3, offset: 0, order: 'desc' },
|
|
857
|
+
)
|
|
858
|
+
expect(capped).toBe(true)
|
|
859
|
+
expect(rows.map((entry) => entry['block_num'])).toEqual([40_000, 10_000, 9_999])
|
|
860
|
+
})
|
|
861
|
+
})
|
|
862
|
+
|
|
863
|
+
describe('foldCount', () => {
|
|
864
|
+
const swapper = `0x${'11'.repeat(20)}`
|
|
865
|
+
const recipient = `0x${'22'.repeat(20)}`
|
|
866
|
+
const sourceToken = '0x20c0000000000000000000000000000000000001'
|
|
867
|
+
const destinationToken = '0x20c0000000000000000000000000000000000002'
|
|
868
|
+
/** One `Transfer` leg row within a transaction. */
|
|
869
|
+
const leg = (txHash: string, logIndex: number, from: string, to: string, token: string) => ({
|
|
870
|
+
address: token,
|
|
871
|
+
from,
|
|
872
|
+
log_idx: logIndex,
|
|
873
|
+
to,
|
|
874
|
+
tx_hash: txHash,
|
|
875
|
+
value: '100',
|
|
876
|
+
})
|
|
877
|
+
const plain = leg(`0x${'ee'.repeat(32)}`, 0, swapper, recipient, sourceToken)
|
|
878
|
+
|
|
879
|
+
test('subtracts classified bundle legs', () => {
|
|
880
|
+
const txHash = `0x${'dd'.repeat(32)}`
|
|
881
|
+
// The account server's approve+swap+forward multicall: source into the
|
|
882
|
+
// DEX, swapped token back, delivery to the recipient, plus the fee leg.
|
|
883
|
+
const rows = [
|
|
884
|
+
leg(txHash, 0, swapper, Addresses.stablecoinDex, sourceToken),
|
|
885
|
+
leg(txHash, 1, Addresses.stablecoinDex, swapper, destinationToken),
|
|
886
|
+
leg(txHash, 2, swapper, recipient, destinationToken),
|
|
887
|
+
leg(txHash, 3, swapper, Addresses.feeManager, sourceToken),
|
|
888
|
+
plain,
|
|
889
|
+
]
|
|
890
|
+
expect(Transfers.foldCount(rows, { capped: false })).toEqual({
|
|
891
|
+
totalCount: 2,
|
|
892
|
+
totalCountCapped: false,
|
|
893
|
+
})
|
|
894
|
+
})
|
|
895
|
+
|
|
896
|
+
test('keeps a cap-truncated sample conservative', () => {
|
|
897
|
+
const txHash = `0x${'dd'.repeat(32)}`
|
|
898
|
+
// A partial bundle: the DEX return leg fell outside the cap, defeating
|
|
899
|
+
// classification. The conservative pass still suppresses the plumbing.
|
|
900
|
+
const rows = [
|
|
901
|
+
leg(txHash, 0, swapper, Addresses.stablecoinDex, sourceToken),
|
|
902
|
+
leg(txHash, 2, swapper, recipient, destinationToken),
|
|
903
|
+
leg(txHash, 3, swapper, Addresses.feeManager, sourceToken),
|
|
904
|
+
plain,
|
|
905
|
+
]
|
|
906
|
+
expect(Transfers.foldCount(rows, { capped: false })).toEqual({
|
|
907
|
+
totalCount: 4,
|
|
908
|
+
totalCountCapped: false,
|
|
909
|
+
})
|
|
910
|
+
expect(Transfers.foldCount(rows, { capped: true })).toEqual({
|
|
911
|
+
totalCount: 2,
|
|
912
|
+
totalCountCapped: true,
|
|
913
|
+
})
|
|
914
|
+
})
|
|
915
|
+
})
|
|
@@ -12,7 +12,7 @@ import * as OpenApi from '../../../internal/OpenApi.js'
|
|
|
12
12
|
import * as Response from '../../../internal/Response.js'
|
|
13
13
|
import * as Schema from '../../../internal/Schema.js'
|
|
14
14
|
import * as Store from '../../../internal/Store.js'
|
|
15
|
-
import
|
|
15
|
+
import * as Tidx from '../../../internal/Tidx.js'
|
|
16
16
|
import * as Timing from '../../../internal/Timing.js'
|
|
17
17
|
import * as Ttl from '../../../internal/Ttl.js'
|
|
18
18
|
import * as Value from '../../../internal/Value.js'
|
|
@@ -26,6 +26,13 @@ import * as Valuation from './valuation.js'
|
|
|
26
26
|
// the indexer SQL.
|
|
27
27
|
export const signature = 'event Transfer(address indexed from, address indexed to, uint256 value)'
|
|
28
28
|
|
|
29
|
+
// TIP-20 contracts occupy the deterministic `0x20c0…` range. Full-width
|
|
30
|
+
// bounds compare correctly as PostgreSQL bytea and ClickHouse hex strings.
|
|
31
|
+
const tip20AddressRange = [
|
|
32
|
+
'0x20c0000000000000000000000000000000000000',
|
|
33
|
+
'0x20c1000000000000000000000000000000000000',
|
|
34
|
+
] as const
|
|
35
|
+
|
|
29
36
|
// A memo'd TIP-20 transfer emits `TransferWithMemo` alongside the plain
|
|
30
37
|
// `Transfer`; the two rows match on `(tx_hash, from, to, amount, token)`. A
|
|
31
38
|
// text memo is decoded into `memo`; an MPP attribution fingerprint memo is
|
|
@@ -96,7 +103,7 @@ export namespace schema {
|
|
|
96
103
|
.optional(z.nullable(Valuation.schema.Value))
|
|
97
104
|
.check(
|
|
98
105
|
z.describe(
|
|
99
|
-
'The amount’s nominal value in the requested `
|
|
106
|
+
'The amount’s nominal value in the requested `valuation.currency`. `null` when the token is ' +
|
|
100
107
|
'unverified, its display currency has no rate, or rates were unavailable.',
|
|
101
108
|
),
|
|
102
109
|
),
|
|
@@ -169,13 +176,13 @@ export namespace schema {
|
|
|
169
176
|
'blockNumber.to': Schema.blockNumberBound('transfers', 'to'),
|
|
170
177
|
chainId: Schema.ChainIdQuery,
|
|
171
178
|
cursor: Schema.Cursor,
|
|
172
|
-
denomination: Schema.Denomination,
|
|
173
179
|
include: includeQuery,
|
|
174
180
|
limit: Schema.Limit,
|
|
175
181
|
order: Schema.Order,
|
|
176
182
|
page: Schema.Page,
|
|
177
183
|
'timestamp.from': Schema.timestampBound('transfers', 'from'),
|
|
178
184
|
'timestamp.to': Schema.timestampBound('transfers', 'to'),
|
|
185
|
+
'valuation.currency': Schema.Denomination,
|
|
179
186
|
})
|
|
180
187
|
.check(
|
|
181
188
|
z.refine((query) => !(query.address && (query.sender || query.recipient)), {
|
|
@@ -281,7 +288,7 @@ export namespace schema {
|
|
|
281
288
|
/** Page-level resources: opt-in counts plus valuation rate provenance. */
|
|
282
289
|
export const Meta = z
|
|
283
290
|
.object({
|
|
284
|
-
|
|
291
|
+
valuation: z
|
|
285
292
|
.optional(Valuation.schema.Pricing)
|
|
286
293
|
.check(
|
|
287
294
|
z.describe(
|
|
@@ -343,7 +350,7 @@ export function transfers(options: transfers.Options = {}) {
|
|
|
343
350
|
}),
|
|
344
351
|
Cache.response<App.Environment>({
|
|
345
352
|
cacheControl: Cache.policies.feed,
|
|
346
|
-
name: 'tempo-api:transfers:
|
|
353
|
+
name: 'tempo-api:transfers:v3',
|
|
347
354
|
key: (c) => Cache.urlKey(c, schema.getTransfers.Query),
|
|
348
355
|
}),
|
|
349
356
|
async (c) => {
|
|
@@ -356,7 +363,7 @@ export function transfers(options: transfers.Options = {}) {
|
|
|
356
363
|
|
|
357
364
|
const options = c.req.valid('query')
|
|
358
365
|
const chainId = options.chainId ?? c.get('chainId')
|
|
359
|
-
const denomination = options.
|
|
366
|
+
const denomination = options['valuation.currency'] ?? 'USD'
|
|
360
367
|
|
|
361
368
|
// Cursor pages carry current valuations and curated verification data.
|
|
362
369
|
if (options.cursor !== undefined) Cache.setPolicy(c, Cache.policies.metadata)
|
|
@@ -569,9 +576,16 @@ export function transfers(options: transfers.Options = {}) {
|
|
|
569
576
|
},
|
|
570
577
|
)
|
|
571
578
|
|
|
572
|
-
|
|
579
|
+
// Wait at most 2.5s more for a still-pending count (cold indexer
|
|
580
|
+
// reads have stalled 20s+); a timed-out count omits `meta` counts.
|
|
581
|
+
const counts = countPromise
|
|
582
|
+
? await Promise.race([
|
|
583
|
+
countPromise,
|
|
584
|
+
new Promise<undefined>((resolve) => setTimeout(() => resolve(undefined), 2_500)),
|
|
585
|
+
])
|
|
586
|
+
: undefined
|
|
573
587
|
const meta = {
|
|
574
|
-
...(rates ? {
|
|
588
|
+
...(rates ? { valuation: Valuation.pricing(rates, oracle) } : {}),
|
|
575
589
|
...counts,
|
|
576
590
|
}
|
|
577
591
|
|
|
@@ -630,7 +644,7 @@ export function query(c: Context<App.Environment>, options: query.Options) {
|
|
|
630
644
|
}
|
|
631
645
|
},
|
|
632
646
|
{
|
|
633
|
-
key: `transfers:
|
|
647
|
+
key: `transfers:v2:${chainId}:${options.order}:${options.token ?? ''}:${options.eitherSide ?? ''}:${options.sender ?? ''}:${options.recipient ?? ''}:${options.fromBlock ?? ''}:${options.toBlock ?? ''}:${options.fromTimestamp ?? ''}:${options.toTimestamp ?? ''}:${cursor ? `cursor:${cursor[0]}:${cursor[1]}` : options.page !== undefined && options.page > 1 ? `page:${options.page}` : 'head'}:${options.limit}`,
|
|
634
648
|
store,
|
|
635
649
|
ttl: Ttl.seconds(15),
|
|
636
650
|
},
|
|
@@ -713,35 +727,56 @@ export async function scan(deps: scan.Deps, options: scan.Options): Promise<scan
|
|
|
713
727
|
)
|
|
714
728
|
const addressScoped = address !== undefined
|
|
715
729
|
const window = addressScoped ? (offset ?? 0) + limit + 1 : limit + 1
|
|
730
|
+
// Only one-sided `"from"`/`"to"` equality shapes hit the planner's
|
|
731
|
+
// deterministic top-N kill, so only they take the capped fallback.
|
|
732
|
+
const sideFiltered =
|
|
733
|
+
addressScoped || options.sender !== undefined || options.recipient !== undefined
|
|
716
734
|
const fetchRows = async (side?: 'from' | 'to') => {
|
|
717
735
|
const sideFilters =
|
|
718
736
|
side !== undefined && address !== undefined
|
|
719
737
|
? [`"${side}" = '${address}'`, ...filters]
|
|
720
738
|
: filters
|
|
721
739
|
const where = sideFilters.length > 0 ? `WHERE ${sideFilters.join(' AND ')}` : ''
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
740
|
+
const select = `"from", "to", ${tokenScoped ? 'token AS address, amount AS value' : 'address, value'}, tx_hash, block_num, log_idx, block_timestamp`
|
|
741
|
+
const table = tokenScoped ? 'token_transfers' : 'Transfer'
|
|
742
|
+
try {
|
|
743
|
+
const result = await tidx.fetch({
|
|
744
|
+
chainId,
|
|
745
|
+
...(tokenScoped ? { engine: 'clickhouse' } : { signatures: [signature] }),
|
|
746
|
+
query: `
|
|
747
|
+
SELECT ${select}
|
|
748
|
+
FROM ${table}
|
|
749
|
+
${where}
|
|
750
|
+
ORDER BY block_num ${direction}, log_idx ${direction}
|
|
751
|
+
LIMIT ${window}${!addressScoped && offset !== undefined ? ` OFFSET ${offset}` : ''}
|
|
752
|
+
` as string,
|
|
753
|
+
})
|
|
754
|
+
return { rows: result.rows, sample: false }
|
|
755
|
+
} catch (error) {
|
|
756
|
+
// The planner kills a one-sided top-N walk when its matches sit far
|
|
757
|
+
// from head (422 `db error`). Retry as a plain capped scan, returning
|
|
758
|
+
// the whole sample so truncation stays detectable.
|
|
759
|
+
if (!sideFiltered || !Tidx.isDeterministicError(error)) throw error
|
|
760
|
+
const result = await tidx.fetch({
|
|
761
|
+
chainId,
|
|
762
|
+
...(tokenScoped ? { engine: 'clickhouse' } : { signatures: [signature] }),
|
|
763
|
+
query: `
|
|
764
|
+
SELECT ${select}
|
|
765
|
+
FROM ${table}
|
|
766
|
+
${where}
|
|
767
|
+
LIMIT ${Schema.countCap}
|
|
768
|
+
` as string,
|
|
769
|
+
})
|
|
770
|
+
return { rows: result.rows, sample: true }
|
|
771
|
+
}
|
|
734
772
|
}
|
|
735
773
|
|
|
736
774
|
// TIDX cannot plan `(from = X OR to = X)` over the decoded Transfer table.
|
|
737
|
-
//
|
|
738
|
-
const
|
|
739
|
-
?
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
order,
|
|
743
|
-
})
|
|
744
|
-
: await fetchRows()
|
|
775
|
+
// Fetch one bounded, server-filtered stream per side and collate app-side.
|
|
776
|
+
const fetched = addressScoped
|
|
777
|
+
? await Promise.all([fetchRows('from'), fetchRows('to')])
|
|
778
|
+
: [await fetchRows()]
|
|
779
|
+
const { capped, rows } = collate(fetched, { limit: limit + 1, offset: offset ?? 0, order })
|
|
745
780
|
|
|
746
781
|
// The next page anchors below the last fetched row's `(block, log_idx)`.
|
|
747
782
|
const page = Cursor.paginate({
|
|
@@ -789,13 +824,69 @@ export async function scan(deps: scan.Deps, options: scan.Options): Promise<scan
|
|
|
789
824
|
})
|
|
790
825
|
}
|
|
791
826
|
|
|
792
|
-
|
|
827
|
+
// A truncated sample cannot anchor keyset pagination without silently
|
|
828
|
+
// skipping unseen matches, so the page ends the list instead.
|
|
829
|
+
return {
|
|
830
|
+
capped,
|
|
831
|
+
hasMore: capped ? false : page.hasMore,
|
|
832
|
+
items,
|
|
833
|
+
limit,
|
|
834
|
+
nextCursor: capped ? null : page.nextCursor,
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Collates per-side transfer streams into one ordered page window: split and
|
|
840
|
+
* sampled streams are deduped, globally ordered, and paged app-side, while a
|
|
841
|
+
* lone engine-paged stream passes through. `capped` marks a fallback sample
|
|
842
|
+
* that hit `Schema.countCap`: an arbitrary subset of that side's matches,
|
|
843
|
+
* unfit to anchor pagination or exact counts.
|
|
844
|
+
*/
|
|
845
|
+
export function collate(
|
|
846
|
+
fetched: readonly collate.Stream[],
|
|
847
|
+
options: collate.Options,
|
|
848
|
+
): collate.Result {
|
|
849
|
+
const capped = fetched.some(({ rows, sample }) => sample && rows.length >= Schema.countCap)
|
|
850
|
+
const rows =
|
|
851
|
+
fetched.length > 1 || fetched.some(({ sample }) => sample)
|
|
852
|
+
? mergeTransferRows(
|
|
853
|
+
fetched.flatMap(({ rows }) => rows),
|
|
854
|
+
options,
|
|
855
|
+
)
|
|
856
|
+
: (fetched[0]?.rows ?? [])
|
|
857
|
+
return { capped, rows }
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
export declare namespace collate {
|
|
861
|
+
/** One fetched transfer stream. */
|
|
862
|
+
type Stream = {
|
|
863
|
+
/** Raw TIDX rows. */
|
|
864
|
+
rows: readonly Record<string, unknown>[]
|
|
865
|
+
/** Whether the rows are an unordered, unpaged capped fallback sample. */
|
|
866
|
+
sample: boolean
|
|
867
|
+
}
|
|
868
|
+
/** The page window applied to the merged stream. */
|
|
869
|
+
type Options = {
|
|
870
|
+
/** Maximum merged rows to return. */
|
|
871
|
+
limit: number
|
|
872
|
+
/** Number of globally ordered rows to skip. */
|
|
873
|
+
offset: number
|
|
874
|
+
/** Global transfer ordering. */
|
|
875
|
+
order: 'asc' | 'desc'
|
|
876
|
+
}
|
|
877
|
+
/** The collated page window. */
|
|
878
|
+
type Result = {
|
|
879
|
+
/** Whether any fallback sample hit `Schema.countCap`. */
|
|
880
|
+
capped: boolean
|
|
881
|
+
/** The ordered page window rows. */
|
|
882
|
+
rows: readonly Record<string, unknown>[]
|
|
883
|
+
}
|
|
793
884
|
}
|
|
794
885
|
|
|
795
886
|
/** Deduplicates and globally orders bounded `from`/`to` transfer streams. */
|
|
796
887
|
function mergeTransferRows(
|
|
797
888
|
rows: readonly Record<string, unknown>[],
|
|
798
|
-
options:
|
|
889
|
+
options: collate.Options,
|
|
799
890
|
): Record<string, unknown>[] {
|
|
800
891
|
const positioned: mergeTransferRows.PositionedRow[] = []
|
|
801
892
|
const seen = new Set<string>()
|
|
@@ -817,14 +908,6 @@ function mergeTransferRows(
|
|
|
817
908
|
}
|
|
818
909
|
|
|
819
910
|
declare namespace mergeTransferRows {
|
|
820
|
-
type Options = {
|
|
821
|
-
/** Maximum merged rows to return. */
|
|
822
|
-
limit: number
|
|
823
|
-
/** Number of globally ordered rows to skip. */
|
|
824
|
-
offset: number
|
|
825
|
-
/** Global transfer ordering. */
|
|
826
|
-
order: 'asc' | 'desc'
|
|
827
|
-
}
|
|
828
911
|
type PositionedRow = {
|
|
829
912
|
/** Transfer block number. */
|
|
830
913
|
blockNumber: number
|
|
@@ -852,6 +935,8 @@ export declare namespace scan {
|
|
|
852
935
|
}
|
|
853
936
|
/** A page of scanned `Transfer` rows. */
|
|
854
937
|
type Page = {
|
|
938
|
+
/** Whether the page came from a cap-truncated fallback sample; such a page must not advance a poller cursor. */
|
|
939
|
+
capped: boolean
|
|
855
940
|
hasMore: boolean
|
|
856
941
|
items: readonly Item[]
|
|
857
942
|
limit: number
|
|
@@ -860,13 +945,15 @@ export declare namespace scan {
|
|
|
860
945
|
}
|
|
861
946
|
|
|
862
947
|
/**
|
|
863
|
-
* Builds shared transfer filters.
|
|
864
|
-
*
|
|
948
|
+
* Builds shared transfer filters. Token-scoped queries target `token_transfers`;
|
|
949
|
+
* unscoped queries constrain the decoded `Transfer` emitter to TIP-20 contracts.
|
|
865
950
|
*/
|
|
866
951
|
function filterClauses(options: filterClauses.Options): string[] {
|
|
867
952
|
const { fromBlock, fromTimestamp, recipient, sender, toBlock, toTimestamp, token } = options
|
|
868
|
-
const filters
|
|
869
|
-
|
|
953
|
+
const filters =
|
|
954
|
+
token === undefined
|
|
955
|
+
? [`address >= '${tip20AddressRange[0]}'`, `address < '${tip20AddressRange[1]}'`]
|
|
956
|
+
: [`token = '${token}'`]
|
|
870
957
|
if (sender !== undefined) filters.push(`"from" = '${sender}'`)
|
|
871
958
|
if (recipient !== undefined) filters.push(`"to" = '${recipient}'`)
|
|
872
959
|
if (fromBlock !== undefined) filters.push(`block_num >= ${fromBlock}`)
|
|
@@ -897,7 +984,7 @@ export function count(c: Context<App.Environment>, options: count.Options): Prom
|
|
|
897
984
|
|
|
898
985
|
return Timing.time(c, timing, () =>
|
|
899
986
|
Store.memoize(() => countScan({ tidx }, { chainId, ...rest }), {
|
|
900
|
-
key: `transfers:count:
|
|
987
|
+
key: `transfers:count:v2:${chainId}:${rest.crossToken ? 'fold' : 'raw'}:${rest.token ?? ''}:${rest.eitherSide ?? ''}:${rest.sender ?? ''}:${rest.recipient ?? ''}:${rest.fromBlock ?? ''}:${rest.toBlock ?? ''}:${rest.fromTimestamp ?? ''}:${rest.toTimestamp ?? ''}`,
|
|
901
988
|
store,
|
|
902
989
|
ttl: Ttl.seconds(15),
|
|
903
990
|
}),
|
|
@@ -946,40 +1033,54 @@ export async function countScan(
|
|
|
946
1033
|
// rows, classify each transaction, and subtract the folded-away legs. Bounded
|
|
947
1034
|
// by `countCap` like the raw count, so it stays within the indexer's budget.
|
|
948
1035
|
if (options.crossToken) {
|
|
1036
|
+
// Only one-sided `"from"`/`"to"` equality shapes hit the planner's
|
|
1037
|
+
// deterministic top-N kill, so only they take the capped fallback.
|
|
1038
|
+
const sideFiltered =
|
|
1039
|
+
address !== undefined || options.sender !== undefined || options.recipient !== undefined
|
|
949
1040
|
const fetchRows = async (side?: 'from' | 'to') => {
|
|
950
1041
|
const sideFilters =
|
|
951
1042
|
side !== undefined && address !== undefined
|
|
952
1043
|
? [`"${side}" = '${address}'`, ...filters]
|
|
953
1044
|
: filters
|
|
954
1045
|
const sideWhere = sideFilters.length > 0 ? `WHERE ${sideFilters.join(' AND ')}` : ''
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1046
|
+
const select = `tx_hash, block_num, log_idx, "from", "to", ${tokenScoped ? 'token AS address, amount AS value' : 'address, value'}`
|
|
1047
|
+
const table = tokenScoped ? 'token_transfers' : 'Transfer'
|
|
1048
|
+
try {
|
|
1049
|
+
const result = await tidx.fetch({
|
|
1050
|
+
chainId,
|
|
1051
|
+
...(tokenScoped ? { engine: 'clickhouse' } : { signatures: [signature] }),
|
|
1052
|
+
query: `
|
|
1053
|
+
SELECT ${select}
|
|
1054
|
+
FROM ${table}
|
|
1055
|
+
${sideWhere}
|
|
1056
|
+
ORDER BY block_num, log_idx
|
|
1057
|
+
LIMIT ${Schema.countCap}
|
|
1058
|
+
` as string,
|
|
1059
|
+
})
|
|
1060
|
+
return { rows: result.rows, sample: false }
|
|
1061
|
+
} catch (error) {
|
|
1062
|
+
// Same planner kill as the page's side scan; the folded count is
|
|
1063
|
+
// already capped, so a plain capped scan keeps its semantics.
|
|
1064
|
+
if (!sideFiltered || !Tidx.isDeterministicError(error)) throw error
|
|
1065
|
+
const result = await tidx.fetch({
|
|
1066
|
+
chainId,
|
|
1067
|
+
...(tokenScoped ? { engine: 'clickhouse' } : { signatures: [signature] }),
|
|
1068
|
+
query: `
|
|
1069
|
+
SELECT ${select}
|
|
1070
|
+
FROM ${table}
|
|
1071
|
+
${sideWhere}
|
|
1072
|
+
LIMIT ${Schema.countCap}
|
|
1073
|
+
` as string,
|
|
1074
|
+
})
|
|
1075
|
+
return { rows: result.rows, sample: true }
|
|
1076
|
+
}
|
|
967
1077
|
}
|
|
968
|
-
const
|
|
1078
|
+
const fetched =
|
|
969
1079
|
address !== undefined
|
|
970
|
-
?
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
})
|
|
975
|
-
: await fetchRows()
|
|
976
|
-
const rawCount = rows.length
|
|
977
|
-
let suppressed = 0
|
|
978
|
-
for (const legs of legsByTransaction(rows).values()) {
|
|
979
|
-
const bundle = classifyCrossToken(legs)
|
|
980
|
-
if (bundle) suppressed += bundle.suppressLogIndexes.length
|
|
981
|
-
}
|
|
982
|
-
return { totalCountCapped: rawCount >= Schema.countCap, totalCount: rawCount - suppressed }
|
|
1080
|
+
? await Promise.all([fetchRows('from'), fetchRows('to')])
|
|
1081
|
+
: [await fetchRows()]
|
|
1082
|
+
const { capped, rows } = collate(fetched, { limit: Schema.countCap, offset: 0, order: 'asc' })
|
|
1083
|
+
return foldCount(rows, { capped })
|
|
983
1084
|
}
|
|
984
1085
|
|
|
985
1086
|
const countRows = async (additionalFilters: readonly string[] = []) => {
|
|
@@ -991,7 +1092,7 @@ export async function countScan(
|
|
|
991
1092
|
query: `
|
|
992
1093
|
SELECT count(*) AS total
|
|
993
1094
|
FROM (
|
|
994
|
-
SELECT
|
|
1095
|
+
SELECT DISTINCT tx_hash, log_idx
|
|
995
1096
|
FROM ${tokenScoped ? 'token_transfers' : 'Transfer'}
|
|
996
1097
|
${countWhere}
|
|
997
1098
|
LIMIT ${Schema.countCap}
|
|
@@ -1028,6 +1129,40 @@ export declare namespace countScan {
|
|
|
1028
1129
|
}
|
|
1029
1130
|
}
|
|
1030
1131
|
|
|
1132
|
+
/**
|
|
1133
|
+
* Folds a capped `Transfer` scan into the cross-token count. Classified
|
|
1134
|
+
* bundles subtract their folded-away legs; a cap-truncated sample can hold
|
|
1135
|
+
* partial bundles that defeat classification, so it subtracts every DEX and
|
|
1136
|
+
* fee leg instead, keeping the reported lower bound from overcounting.
|
|
1137
|
+
*/
|
|
1138
|
+
export function foldCount(
|
|
1139
|
+
rows: readonly Record<string, unknown>[],
|
|
1140
|
+
options: foldCount.Options,
|
|
1141
|
+
): count.Result {
|
|
1142
|
+
const { capped } = options
|
|
1143
|
+
let suppressed = 0
|
|
1144
|
+
for (const legs of legsByTransaction(rows).values()) {
|
|
1145
|
+
if (capped) {
|
|
1146
|
+
suppressed += legs.filter(isBundleLeg).length
|
|
1147
|
+
continue
|
|
1148
|
+
}
|
|
1149
|
+
const bundle = classifyCrossToken(legs)
|
|
1150
|
+
if (bundle) suppressed += bundle.suppressLogIndexes.length
|
|
1151
|
+
}
|
|
1152
|
+
return {
|
|
1153
|
+
totalCount: rows.length - suppressed,
|
|
1154
|
+
totalCountCapped: capped || rows.length >= Schema.countCap,
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
export declare namespace foldCount {
|
|
1159
|
+
/** Options for {@link foldCount}. */
|
|
1160
|
+
type Options = {
|
|
1161
|
+
/** Whether the rows include a cap-truncated fallback sample. */
|
|
1162
|
+
capped: boolean
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1031
1166
|
/** `'tx1', 'tx2', …` SQL `IN` list of the page's distinct transaction hashes. */
|
|
1032
1167
|
function txInList(rows: memoMap.Options['rows']): string {
|
|
1033
1168
|
return [...new Set(rows.map((row) => row.transactionHash.toLowerCase()))]
|
|
@@ -1118,6 +1253,15 @@ type Leg = {
|
|
|
1118
1253
|
to: z.output<typeof Schema.Address>
|
|
1119
1254
|
}
|
|
1120
1255
|
|
|
1256
|
+
/** Whether a leg is cross-token bundle plumbing: a DEX leg or the fee leg. */
|
|
1257
|
+
function isBundleLeg(leg: Leg): boolean {
|
|
1258
|
+
return (
|
|
1259
|
+
Address.isEqual(leg.to, Addresses.stablecoinDex) ||
|
|
1260
|
+
Address.isEqual(leg.from, Addresses.stablecoinDex) ||
|
|
1261
|
+
Address.isEqual(leg.to, Addresses.feeManager)
|
|
1262
|
+
)
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1121
1265
|
/** The folded shape of a detected cross-token transfer, anchored on its delivery leg. */
|
|
1122
1266
|
type CrossTokenBundle = {
|
|
1123
1267
|
/** Log index of the delivery leg the transfer folds onto. */
|
|
@@ -1161,13 +1305,7 @@ function classifyCrossToken(legs: readonly Leg[]): CrossTokenBundle | undefined
|
|
|
1161
1305
|
// Require a token change so plain same-token DEX activity is not folded.
|
|
1162
1306
|
if (!delivery || Address.isEqual(toDex.address, delivery.address)) return undefined
|
|
1163
1307
|
const suppressLogIndexes = legs
|
|
1164
|
-
.filter(
|
|
1165
|
-
(leg) =>
|
|
1166
|
-
leg.logIndex !== delivery.logIndex &&
|
|
1167
|
-
(Address.isEqual(leg.to, Addresses.stablecoinDex) ||
|
|
1168
|
-
Address.isEqual(leg.from, Addresses.stablecoinDex) ||
|
|
1169
|
-
Address.isEqual(leg.to, Addresses.feeManager)),
|
|
1170
|
-
)
|
|
1308
|
+
.filter((leg) => leg.logIndex !== delivery.logIndex && isBundleLeg(leg))
|
|
1171
1309
|
.map((leg) => leg.logIndex)
|
|
1172
1310
|
return {
|
|
1173
1311
|
deliveryLogIndex: delivery.logIndex,
|