tapimo 0.5.3 → 0.7.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/dist/App.d.ts +15830 -7220
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +9 -1
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +4 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +5 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +1011 -412
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +4 -0
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +2 -1
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/early-access.d.ts +148 -0
- package/dist/admin/apps/early-access.d.ts.map +1 -0
- package/dist/admin/apps/early-access.js +133 -0
- package/dist/admin/apps/early-access.js.map +1 -0
- package/dist/admin/apps/organizations.d.ts +124 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +97 -6
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +526 -1
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +214 -1
- 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 +95 -75
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +20 -0
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +18 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +36 -7
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +6260 -4924
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +11 -6
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts +34 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.js +194 -16
- package/dist/apps/data/FundingQuoteProviders.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +71 -0
- package/dist/apps/data/FxOracle.d.ts.map +1 -0
- package/dist/apps/data/FxOracle.js +97 -0
- package/dist/apps/data/FxOracle.js.map +1 -0
- package/dist/apps/data/index.d.ts +1 -0
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +1 -0
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +3599 -1382
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +250 -88
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +872 -251
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/addresses.js +11 -9
- package/dist/apps/data/routes/addresses.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +77 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +88 -45
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +39 -39
- package/dist/apps/data/routes/coingecko.d.ts +54 -54
- package/dist/apps/data/routes/exchanges.d.ts +856 -105
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +518 -76
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +81 -67
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +76 -91
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/funding.d.ts +80 -36
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +65 -31
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +392 -315
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +152 -77
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +167 -174
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +15 -13
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +277 -536
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +96 -77
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +157 -81
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +272 -130
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +307 -0
- package/dist/apps/data/routes/valuation.d.ts.map +1 -0
- package/dist/apps/data/routes/valuation.js +292 -0
- package/dist/apps/data/routes/valuation.js.map +1 -0
- package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +7 -5
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +103 -123
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +124 -25
- package/dist/apps/data/routes/webhooks.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 +8554 -1692
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +12 -1
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +7 -0
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +17 -3
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +157 -162
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +31 -23
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +232 -0
- package/dist/apps/management/routes/faucet.d.ts.map +1 -0
- package/dist/apps/management/routes/faucet.js +154 -0
- package/dist/apps/management/routes/faucet.js.map +1 -0
- package/dist/apps/management/routes/invitations.d.ts +60 -60
- package/dist/apps/management/routes/invite-links.d.ts +49 -20
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +26 -1
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +6 -6
- package/dist/apps/management/routes/orgs.d.ts +42 -42
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +5 -0
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +44 -44
- package/dist/apps/management/routes/usage.d.ts +3 -0
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +4 -0
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +697 -0
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -0
- package/dist/apps/management/routes/verified-token-requests.js +271 -0
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -0
- package/dist/apps/management/routes/webhooks.d.ts +6977 -0
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -0
- package/dist/apps/management/routes/webhooks.js +573 -0
- package/dist/apps/management/routes/webhooks.js.map +1 -0
- package/dist/apps/mpp/App.d.ts +363 -0
- package/dist/apps/mpp/App.d.ts.map +1 -0
- package/dist/apps/mpp/App.js +72 -0
- package/dist/apps/mpp/App.js.map +1 -0
- package/dist/apps/mpp/Mpp.d.ts +178 -0
- package/dist/apps/mpp/Mpp.d.ts.map +1 -0
- package/dist/apps/mpp/Mpp.js +183 -0
- package/dist/apps/mpp/Mpp.js.map +1 -0
- package/dist/apps/mpp/index.d.ts +3 -0
- package/dist/apps/mpp/index.d.ts.map +1 -0
- package/dist/apps/mpp/index.js +3 -0
- package/dist/apps/mpp/index.js.map +1 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +56 -9
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/db/Db.d.ts +6 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +110 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +53 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +56 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earlyAccess.d.ts +50 -0
- package/dist/db/tables/earlyAccess.d.ts.map +1 -0
- package/dist/db/tables/earlyAccess.js +63 -0
- package/dist/db/tables/earlyAccess.js.map +1 -0
- package/dist/db/tables/enabledBillingSources.d.ts +73 -0
- package/dist/db/tables/enabledBillingSources.d.ts.map +1 -0
- package/dist/db/tables/enabledBillingSources.js +69 -0
- package/dist/db/tables/enabledBillingSources.js.map +1 -0
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +3 -0
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/inviteLinks.d.ts +10 -2
- package/dist/db/tables/inviteLinks.d.ts.map +1 -1
- package/dist/db/tables/inviteLinks.js +10 -1
- package/dist/db/tables/inviteLinks.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +5 -2
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +13 -2
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +2 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +2 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/verifiedTokenRequests.d.ts +94 -0
- package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokenRequests.js +120 -0
- package/dist/db/tables/verifiedTokenRequests.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +14 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +16 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts +1 -16
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +17 -6
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +37 -5
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +14 -47
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/FundingQuotes.d.ts +147 -47
- package/dist/internal/FundingQuotes.d.ts.map +1 -1
- package/dist/internal/FundingQuotes.js +119 -33
- package/dist/internal/FundingQuotes.js.map +1 -1
- package/dist/internal/Log.d.ts +37 -5
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +52 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +24 -0
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +2 -2
- 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/Response.d.ts +2 -2
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +12 -4
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +14 -5
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +23 -5
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Value.d.ts +18 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +11 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +10 -1
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +24 -3
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +34 -8
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +7 -2
- package/src/App.test.ts +9 -4
- package/src/App.ts +23 -3
- package/src/Client.test-d.ts +733 -20
- package/src/Scope.ts +5 -0
- package/src/admin/App.test.ts +4 -0
- package/src/admin/App.ts +4 -0
- package/src/admin/apps/early-access.test.ts +125 -0
- package/src/admin/apps/early-access.ts +176 -0
- package/src/admin/apps/organizations.test.ts +86 -2
- package/src/admin/apps/organizations.ts +155 -31
- package/src/admin/apps/scopes.test.ts +5 -0
- package/src/admin/apps/verified-tokens.test.ts +201 -0
- package/src/admin/apps/verified-tokens.ts +532 -286
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/lib/early-access.ts +63 -0
- package/src/admin/ui/src/lib/organizations.test.ts +81 -1
- package/src/admin/ui/src/lib/organizations.ts +92 -0
- package/src/admin/ui/src/lib/verified-tokens.ts +79 -0
- package/src/admin/ui/src/routeTree.gen.ts +33 -2
- package/src/admin/ui/src/routes/__root.tsx +2 -1
- package/src/admin/ui/src/routes/api-keys.tsx +1 -1
- package/src/admin/ui/src/routes/early-access.tsx +162 -0
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +103 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +230 -19
- package/src/admin/ui.generated.ts +95 -94
- package/src/analytics/Analytics.test.ts +83 -0
- package/src/analytics/Analytics.ts +20 -0
- package/src/analytics/tables/requestEvents.ts +60 -7
- package/src/apps/composition.test.ts +11 -2
- package/src/apps/data/App.test.ts +1 -1
- package/src/apps/data/App.ts +22 -14
- package/src/apps/data/FundingQuoteProviders.test.ts +297 -4
- package/src/apps/data/FundingQuoteProviders.ts +255 -29
- package/src/apps/data/FxOracle.test.ts +118 -0
- package/src/apps/data/FxOracle.ts +153 -0
- package/src/apps/data/index.ts +1 -0
- package/src/apps/data/routes/activities.test.ts +177 -3
- package/src/apps/data/routes/activities.ts +441 -132
- package/src/apps/data/routes/addresses.ts +19 -9
- package/src/apps/data/routes/balances.test.ts +148 -11
- package/src/apps/data/routes/balances.ts +140 -51
- package/src/apps/data/routes/exchanges.test.ts +544 -9
- package/src/apps/data/routes/exchanges.ts +690 -103
- package/src/apps/data/routes/fee-amm.test.ts +47 -23
- package/src/apps/data/routes/fee-amm.ts +98 -119
- package/src/apps/data/routes/funding.test.ts +113 -8
- package/src/apps/data/routes/funding.ts +77 -51
- package/src/apps/data/routes/receipts.test.ts +129 -23
- package/src/apps/data/routes/receipts.ts +205 -100
- package/src/apps/data/routes/tokens.test.ts +43 -0
- package/src/apps/data/routes/tokens.ts +28 -13
- package/src/apps/data/routes/transactions.test.ts +72 -19
- package/src/apps/data/routes/transactions.ts +162 -92
- package/src/apps/data/routes/transfers.test.ts +341 -31
- package/src/apps/data/routes/transfers.ts +358 -158
- package/src/apps/data/routes/valuation.test.ts +437 -0
- package/src/apps/data/routes/valuation.ts +423 -0
- package/src/apps/data/routes/verified-tokens.ts +14 -2
- package/src/apps/data/routes/webhooks.test.ts +56 -8
- package/src/apps/data/routes/webhooks.ts +144 -27
- package/src/apps/index.ts +2 -1
- package/src/apps/management/App.ts +13 -0
- package/src/apps/management/routes/api-keys.test.ts +14 -0
- package/src/apps/management/routes/api-keys.ts +27 -3
- package/src/apps/management/routes/billing.test.ts +152 -20
- package/src/apps/management/routes/billing.ts +34 -18
- package/src/apps/management/routes/faucet.test.ts +87 -0
- package/src/apps/management/routes/faucet.ts +201 -0
- package/src/apps/management/routes/invite-links.test.ts +117 -0
- package/src/apps/management/routes/invite-links.ts +43 -1
- package/src/apps/management/routes/me.test.ts +9 -99
- package/src/apps/management/routes/orgs.test.ts +45 -2
- package/src/apps/management/routes/orgs.ts +6 -0
- package/src/apps/management/routes/scopes.test.ts +1 -0
- package/src/apps/management/routes/usage.test.ts +6 -0
- package/src/apps/management/routes/usage.ts +7 -0
- package/src/apps/management/routes/verified-token-requests.test.ts +377 -0
- package/src/apps/management/routes/verified-token-requests.ts +397 -0
- package/src/apps/management/routes/webhooks.test.ts +426 -0
- package/src/apps/management/routes/webhooks.ts +672 -0
- package/src/apps/mpp/App.ts +86 -0
- package/src/apps/mpp/Mpp.test.ts +193 -0
- package/src/apps/mpp/Mpp.ts +353 -0
- package/src/apps/mpp/index.ts +2 -0
- package/src/apps/mpp/internal/Adapter.ts +11 -0
- package/src/apps/mpp/internal/Error.ts +9 -0
- package/src/apps/mpp/internal/Idempotency.ts +7 -0
- package/src/apps/mpp/internal/Screening.ts +10 -0
- package/src/apps/relay/App.test.ts +88 -6
- package/src/apps/relay/App.ts +61 -9
- package/src/db/Db.test.ts +19 -0
- package/src/db/Db.ts +125 -0
- package/src/db/Schema.ts +68 -0
- package/src/db/tables/earlyAccess.ts +86 -0
- package/src/db/tables/enabledBillingSources.test.ts +303 -0
- package/src/db/tables/enabledBillingSources.ts +118 -0
- package/src/db/tables/invitations.ts +3 -0
- package/src/db/tables/inviteLinks.ts +22 -3
- package/src/db/tables/organizations.test.ts +103 -0
- package/src/db/tables/organizations.ts +18 -2
- package/src/db/tables/sponsoredTransactions.ts +4 -0
- package/src/db/tables/verifiedTokenRequests.test.ts +200 -0
- package/src/db/tables/verifiedTokenRequests.ts +182 -0
- package/src/db/tables/webhookSubscriptions.ts +31 -0
- package/src/handlers/internal/utils.ts +22 -6
- package/src/handlers/relay.errors.test.ts +153 -0
- package/src/handlers/relay.ts +42 -7
- package/src/internal/Auth.test.ts +3 -3
- package/src/internal/Auth.ts +15 -47
- package/src/internal/FundingQuotes.test.ts +161 -6
- package/src/internal/FundingQuotes.ts +141 -39
- package/src/internal/Log.test-d.ts +21 -0
- package/src/internal/Log.test.ts +141 -0
- package/src/internal/Log.ts +93 -6
- package/src/internal/MetricSink.test.ts +215 -0
- package/src/internal/MetricSink.ts +24 -0
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Response.test.ts +28 -0
- package/src/internal/Response.ts +12 -4
- package/src/internal/Schema.ts +50 -5
- package/src/internal/Value.test.ts +20 -0
- package/src/internal/Value.ts +24 -1
- package/src/internal/VerifiedTokens.ts +9 -1
- package/src/internal/Webhooks.test.ts +140 -0
- package/src/internal/Webhooks.ts +53 -9
|
@@ -1,12 +1,81 @@
|
|
|
1
1
|
import type * as z from 'zod/mini'
|
|
2
|
-
import {
|
|
2
|
+
import { Value as core_Value } from 'ox'
|
|
3
|
+
import { Db, Schema } from 'tapimo'
|
|
4
|
+
import { FxOracle } from 'tapimo/apps'
|
|
3
5
|
|
|
4
6
|
import * as TestApp from '../../../../test/App.js'
|
|
5
7
|
import * as Runtime from '../../../../test/runtime.js'
|
|
6
8
|
import * as Transfers from './transfers.js'
|
|
7
9
|
|
|
10
|
+
// Deterministic EUR-based rate set so conversion math is exact in assertions.
|
|
11
|
+
const fixed = FxOracle.from({
|
|
12
|
+
name: 'fixed',
|
|
13
|
+
rates: async () => ({
|
|
14
|
+
asOf: '2026-01-01T00:00:00.000Z',
|
|
15
|
+
base: 'EUR',
|
|
16
|
+
rates: { AUD: '1.6', USD: '1.0' },
|
|
17
|
+
}),
|
|
18
|
+
})
|
|
19
|
+
|
|
8
20
|
describe('GET /transfers', () => {
|
|
9
|
-
test('
|
|
21
|
+
test('parses granular token includes', () => {
|
|
22
|
+
expect(
|
|
23
|
+
Transfers.schema.getTransfers.Query.parse({
|
|
24
|
+
include: 'token.logoUri,token.verified',
|
|
25
|
+
}).include,
|
|
26
|
+
).toMatchInlineSnapshot(`
|
|
27
|
+
[
|
|
28
|
+
"token.logoUri",
|
|
29
|
+
"token.verified",
|
|
30
|
+
]
|
|
31
|
+
`)
|
|
32
|
+
expect(Transfers.schema.getTransfers.Query.safeParse({ include: 'token' }).success).toBe(false)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('degrades unavailable verification data to null valuations', async () => {
|
|
36
|
+
const db = () =>
|
|
37
|
+
Db.postgres({
|
|
38
|
+
connectionString: 'postgresql://postgres:postgres@127.0.0.1:1/none',
|
|
39
|
+
})
|
|
40
|
+
const client = TestApp.client({ db, fx: { oracle: fixed } })
|
|
41
|
+
|
|
42
|
+
const response = await client.v1.transfers.$get(
|
|
43
|
+
{ query: { limit: '5', token: TestApp.tokenWithHolders } },
|
|
44
|
+
TestApp.auth,
|
|
45
|
+
)
|
|
46
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
47
|
+
|
|
48
|
+
expect(response.status).toBe(200)
|
|
49
|
+
expect(body.data.length).toBeGreaterThan(0)
|
|
50
|
+
for (const entry of body.data) expect(entry.sourceAmount.valuation).toBeNull()
|
|
51
|
+
|
|
52
|
+
const emptyResponse = await client.v1.transfers.$get(
|
|
53
|
+
{ query: { limit: '5', token: `0x${'11'.repeat(20)}` } },
|
|
54
|
+
TestApp.auth,
|
|
55
|
+
)
|
|
56
|
+
const empty = await TestApp.json(emptyResponse, Transfers.schema.getTransfers.Response)
|
|
57
|
+
expect(emptyResponse.status).toBe(200)
|
|
58
|
+
expect(empty.data).toMatchInlineSnapshot(`[]`)
|
|
59
|
+
expect(emptyResponse.headers.get('server-timing')?.includes('verified_tokens;dur=')).not.toBe(
|
|
60
|
+
true,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const unsupportedResponse = await client.v1.transfers.$get(
|
|
64
|
+
{
|
|
65
|
+
query: {
|
|
66
|
+
denomination: 'JPY',
|
|
67
|
+
limit: '5',
|
|
68
|
+
token: TestApp.tokenWithHolders,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
TestApp.auth,
|
|
72
|
+
)
|
|
73
|
+
const unsupported = await TestApp.json(unsupportedResponse, Schema.ErrorResponse)
|
|
74
|
+
expect(unsupportedResponse.status).toBe(400)
|
|
75
|
+
expect(unsupported.error.code).toBe('query_invalid')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('returns an unscoped transfer page with token metadata', async () => {
|
|
10
79
|
const client = TestApp.client()
|
|
11
80
|
const baseResponse = await client.v1.transfers.$get({ query: { limit: '5' } }, TestApp.auth)
|
|
12
81
|
const base = await TestApp.json(baseResponse, Transfers.schema.getTransfers.Response)
|
|
@@ -23,7 +92,14 @@ describe('GET /transfers', () => {
|
|
|
23
92
|
base.data.every(
|
|
24
93
|
(entry) =>
|
|
25
94
|
/^0x[0-9a-f]{40}$/.test(entry.sourceToken.address) &&
|
|
26
|
-
/^\d+$/.test(entry.
|
|
95
|
+
/^\d+$/.test(entry.sourceAmount.baseUnits) &&
|
|
96
|
+
typeof entry.sourceAmount.currency === 'string' &&
|
|
97
|
+
Number.isInteger(entry.sourceAmount.decimals) &&
|
|
98
|
+
typeof entry.sourceAmount.formatted === 'string' &&
|
|
99
|
+
typeof entry.sourceToken.currency === 'string' &&
|
|
100
|
+
Number.isInteger(entry.sourceToken.decimals) &&
|
|
101
|
+
typeof entry.sourceToken.name === 'string' &&
|
|
102
|
+
typeof entry.sourceToken.symbol === 'string' &&
|
|
27
103
|
Number.isInteger(entry.blockNumber) &&
|
|
28
104
|
/^0x[0-9a-f]{40}$/.test(entry.sender) &&
|
|
29
105
|
/^0x[0-9a-f]{40}$/.test(entry.recipient) &&
|
|
@@ -34,28 +110,35 @@ describe('GET /transfers', () => {
|
|
|
34
110
|
// Transfers default to newest-first (descending block number).
|
|
35
111
|
const blocks = base.data.map((entry) => entry.blockNumber)
|
|
36
112
|
expect(blocks.every((block, index) => index === 0 || blocks[index - 1]! >= block)).toBe(true)
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
113
|
+
// Quantities live beside the token reference; curated fields remain opt-in.
|
|
114
|
+
expect(
|
|
115
|
+
base.data.every(
|
|
116
|
+
(entry) =>
|
|
117
|
+
!('amount' in entry.sourceToken) &&
|
|
118
|
+
!('valuation' in entry.sourceToken) &&
|
|
119
|
+
entry.sourceToken.logoUri === undefined &&
|
|
120
|
+
entry.sourceToken.verified === undefined,
|
|
121
|
+
),
|
|
122
|
+
).toBe(true)
|
|
40
123
|
|
|
41
124
|
const includedResponse = await client.v1.transfers.$get(
|
|
42
|
-
{ query: { limit: '5', include: 'token' } },
|
|
125
|
+
{ query: { limit: '5', include: 'token.logoUri,token.verified' } },
|
|
43
126
|
TestApp.auth,
|
|
44
127
|
)
|
|
45
128
|
const included = await TestApp.json(includedResponse, Transfers.schema.getTransfers.Response)
|
|
46
129
|
|
|
47
130
|
expect(includedResponse.status).toBe(200)
|
|
48
|
-
//
|
|
49
|
-
// it is spread alongside. Resolution is best-effort, so a row whose
|
|
50
|
-
// metadata is unavailable simply omits the metadata fields.
|
|
131
|
+
// Curated fields remain optional without moving quantities back into the token.
|
|
51
132
|
expect(
|
|
52
133
|
included.data.every(
|
|
53
134
|
(entry) =>
|
|
54
135
|
/^0x[0-9a-f]{40}$/.test(entry.sourceToken.address) &&
|
|
55
|
-
/^\d+$/.test(entry.
|
|
56
|
-
(entry.sourceToken
|
|
57
|
-
|
|
58
|
-
|
|
136
|
+
/^\d+$/.test(entry.sourceAmount.baseUnits) &&
|
|
137
|
+
!('amount' in entry.sourceToken) &&
|
|
138
|
+
!('valuation' in entry.sourceToken) &&
|
|
139
|
+
typeof entry.sourceToken.symbol === 'string' &&
|
|
140
|
+
Number.isInteger(entry.sourceToken.decimals) &&
|
|
141
|
+
typeof entry.sourceToken.verified === 'boolean',
|
|
59
142
|
),
|
|
60
143
|
).toBe(true)
|
|
61
144
|
})
|
|
@@ -74,24 +157,156 @@ describe('GET /transfers', () => {
|
|
|
74
157
|
|
|
75
158
|
test('narrows transfers by address (either side)', async () => {
|
|
76
159
|
const client = TestApp.client()
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{ query: { limit: '5', address: account } },
|
|
160
|
+
const runtime = Runtime.get()
|
|
161
|
+
const address = Schema.Address.parse(
|
|
162
|
+
runtime.mode === 'testnet'
|
|
163
|
+
? '0xb1f382bd6deed37895528a6387bae4cd9569ac3c'
|
|
164
|
+
: runtime.fixtures!.fundedAccounts[0]!,
|
|
165
|
+
)
|
|
166
|
+
const response = await client.v1.transfers.$get(
|
|
167
|
+
{ query: { address, include: 'totalCount', limit: '10' } },
|
|
86
168
|
TestApp.auth,
|
|
87
169
|
)
|
|
88
|
-
const
|
|
89
|
-
|
|
170
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
171
|
+
|
|
172
|
+
expect(response.status).toBe(200)
|
|
90
173
|
expect(
|
|
91
|
-
|
|
174
|
+
body.data.every((entry) => entry.sender === address || entry.recipient === address),
|
|
92
175
|
).toBe(true)
|
|
176
|
+
expect(body.meta!.totalCount).toBeGreaterThanOrEqual(body.data.length)
|
|
177
|
+
expect(body.meta!.totalCountCapped).toBe(body.meta!.totalCount! >= Schema.countCap)
|
|
93
178
|
})
|
|
94
179
|
|
|
180
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
181
|
+
'merges both address sides before paginating',
|
|
182
|
+
async () => {
|
|
183
|
+
const client = TestApp.client()
|
|
184
|
+
const address = '0xabb0023644c54a20d0fe92becfa764dacaf59ba9'
|
|
185
|
+
const toBlock = '27608730'
|
|
186
|
+
const [senderResponse, recipientResponse, addressResponse] = await Promise.all([
|
|
187
|
+
client.v1.transfers.$get(
|
|
188
|
+
{
|
|
189
|
+
query: { 'blockNumber.to': toBlock, limit: '10', order: 'desc', sender: address },
|
|
190
|
+
},
|
|
191
|
+
TestApp.auth,
|
|
192
|
+
),
|
|
193
|
+
client.v1.transfers.$get(
|
|
194
|
+
{
|
|
195
|
+
query: { 'blockNumber.to': toBlock, limit: '10', order: 'desc', recipient: address },
|
|
196
|
+
},
|
|
197
|
+
TestApp.auth,
|
|
198
|
+
),
|
|
199
|
+
client.v1.transfers.$get(
|
|
200
|
+
{
|
|
201
|
+
query: { address, 'blockNumber.to': toBlock, limit: '10', order: 'desc' },
|
|
202
|
+
},
|
|
203
|
+
TestApp.auth,
|
|
204
|
+
),
|
|
205
|
+
])
|
|
206
|
+
const sender = await TestApp.json(senderResponse, Transfers.schema.getTransfers.Response)
|
|
207
|
+
const recipient = await TestApp.json(
|
|
208
|
+
recipientResponse,
|
|
209
|
+
Transfers.schema.getTransfers.Response,
|
|
210
|
+
)
|
|
211
|
+
const combined = await TestApp.json(addressResponse, Transfers.schema.getTransfers.Response)
|
|
212
|
+
|
|
213
|
+
expect([senderResponse.status, recipientResponse.status, addressResponse.status]).toEqual([
|
|
214
|
+
200, 200, 200,
|
|
215
|
+
])
|
|
216
|
+
const seen = new Set<string>()
|
|
217
|
+
const expected = [...sender.data, ...recipient.data]
|
|
218
|
+
.sort((a, b) => b.blockNumber - a.blockNumber || b.logIndex - a.logIndex)
|
|
219
|
+
.filter((entry) => {
|
|
220
|
+
if (seen.has(entry.id)) return false
|
|
221
|
+
seen.add(entry.id)
|
|
222
|
+
return true
|
|
223
|
+
})
|
|
224
|
+
.slice(0, 10)
|
|
225
|
+
expect(expected).toHaveLength(10)
|
|
226
|
+
expect(combined.data.map(({ id }) => id)).toEqual(expected.map(({ id }) => id))
|
|
227
|
+
|
|
228
|
+
const firstResponse = await client.v1.transfers.$get(
|
|
229
|
+
{
|
|
230
|
+
query: { address, 'blockNumber.to': toBlock, limit: '5', order: 'desc' },
|
|
231
|
+
},
|
|
232
|
+
TestApp.auth,
|
|
233
|
+
)
|
|
234
|
+
const first = await TestApp.json(firstResponse, Transfers.schema.getTransfers.Response)
|
|
235
|
+
expect(firstResponse.status).toBe(200)
|
|
236
|
+
expect(first.nextCursor).not.toBeNull()
|
|
237
|
+
if (!first.nextCursor) return
|
|
238
|
+
|
|
239
|
+
const [cursorResponse, positionalResponse] = await Promise.all([
|
|
240
|
+
client.v1.transfers.$get(
|
|
241
|
+
{
|
|
242
|
+
query: {
|
|
243
|
+
address,
|
|
244
|
+
'blockNumber.to': toBlock,
|
|
245
|
+
cursor: first.nextCursor,
|
|
246
|
+
limit: '5',
|
|
247
|
+
order: 'desc',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
TestApp.auth,
|
|
251
|
+
),
|
|
252
|
+
client.v1.transfers.$get(
|
|
253
|
+
{
|
|
254
|
+
query: {
|
|
255
|
+
address,
|
|
256
|
+
'blockNumber.to': toBlock,
|
|
257
|
+
limit: '5',
|
|
258
|
+
order: 'desc',
|
|
259
|
+
page: '2',
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
TestApp.auth,
|
|
263
|
+
),
|
|
264
|
+
])
|
|
265
|
+
const cursor = await TestApp.json(cursorResponse, Transfers.schema.getTransfers.Response)
|
|
266
|
+
const positional = await TestApp.json(
|
|
267
|
+
positionalResponse,
|
|
268
|
+
Transfers.schema.getTransfers.Response,
|
|
269
|
+
)
|
|
270
|
+
const expectedSecondPage = expected.slice(5, 10).map(({ id }) => id)
|
|
271
|
+
|
|
272
|
+
expect([cursorResponse.status, positionalResponse.status]).toEqual([200, 200])
|
|
273
|
+
expect([...first.data, ...cursor.data].map(({ id }) => id)).toEqual(
|
|
274
|
+
expected.map(({ id }) => id),
|
|
275
|
+
)
|
|
276
|
+
expect(positional.data.map(({ id }) => id)).toEqual(expectedSecondPage)
|
|
277
|
+
},
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
281
|
+
'deduplicates self-transfers in address pages and counts',
|
|
282
|
+
async () => {
|
|
283
|
+
const client = TestApp.client()
|
|
284
|
+
const address = '0xabb0023644c54a20d0fe92becfa764dacaf59ba9'
|
|
285
|
+
const transactionHash = '0x915a11bcf4b5e667c631f9fb09ac8729f3b436f24eb0b552e54ec13a490ef57f'
|
|
286
|
+
const response = await client.v1.transfers.$get(
|
|
287
|
+
{
|
|
288
|
+
query: {
|
|
289
|
+
address,
|
|
290
|
+
'blockNumber.from': '27608730',
|
|
291
|
+
'blockNumber.to': '27608730',
|
|
292
|
+
include: 'totalCount',
|
|
293
|
+
limit: '50',
|
|
294
|
+
token: '0x20c0000000000000000000000000000000000003',
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
TestApp.auth,
|
|
298
|
+
)
|
|
299
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
300
|
+
|
|
301
|
+
expect(response.status).toBe(200)
|
|
302
|
+
expect(body.data.filter(({ id }) => id === `${transactionHash}-233`)).toHaveLength(1)
|
|
303
|
+
expect(body.meta).toMatchObject({
|
|
304
|
+
totalCount: body.data.length,
|
|
305
|
+
totalCountCapped: false,
|
|
306
|
+
})
|
|
307
|
+
},
|
|
308
|
+
)
|
|
309
|
+
|
|
95
310
|
test('narrows transfers by sender and recipient independently', async () => {
|
|
96
311
|
const client = TestApp.client()
|
|
97
312
|
const seedResponse = await client.v1.transfers.$get({ query: { limit: '5' } }, TestApp.auth)
|
|
@@ -147,6 +362,9 @@ describe('GET /transfers', () => {
|
|
|
147
362
|
const second = await TestApp.json(secondResponse, Transfers.schema.getTransfers.Response)
|
|
148
363
|
|
|
149
364
|
expect(secondResponse.status).toBe(200)
|
|
365
|
+
expect(secondResponse.headers.get('cache-control')).toMatchInlineSnapshot(
|
|
366
|
+
`"private, max-age=60, stale-while-revalidate=300"`,
|
|
367
|
+
)
|
|
150
368
|
expect(second.data.length).toBeGreaterThan(0)
|
|
151
369
|
// Each row's identity on the unscoped feed is `(blockNumber, txHash,
|
|
152
370
|
// sourceToken, sender, recipient, amount)` — a single transaction can
|
|
@@ -154,7 +372,7 @@ describe('GET /transfers', () => {
|
|
|
154
372
|
// `(txHash, blockNumber)` shortcut is not unique here.
|
|
155
373
|
type Entry = z.output<typeof Transfers.schema.getTransfers.Transfer>
|
|
156
374
|
const keyOf = (entry: Entry) =>
|
|
157
|
-
`${entry.blockNumber}:${entry.transactionHash}:${entry.sourceToken.address}:${entry.sender}:${entry.recipient}:${entry.
|
|
375
|
+
`${entry.blockNumber}:${entry.transactionHash}:${entry.sourceToken.address}:${entry.sender}:${entry.recipient}:${entry.sourceAmount.baseUnits}`
|
|
158
376
|
const firstKeys = new Set(first.data.map(keyOf))
|
|
159
377
|
expect(second.data.every((entry) => !firstKeys.has(keyOf(entry)))).toBe(true)
|
|
160
378
|
})
|
|
@@ -202,7 +420,7 @@ describe('GET /transfers', () => {
|
|
|
202
420
|
|
|
203
421
|
type Entry = z.output<typeof Transfers.schema.getTransfers.Transfer>
|
|
204
422
|
const keyOf = (entry: Entry) =>
|
|
205
|
-
`${entry.blockNumber}:${entry.transactionHash}:${entry.sourceToken.address}:${entry.sender}:${entry.recipient}:${entry.
|
|
423
|
+
`${entry.blockNumber}:${entry.transactionHash}:${entry.sourceToken.address}:${entry.sender}:${entry.recipient}:${entry.sourceAmount.baseUnits}`
|
|
206
424
|
expect(page.data.map(keyOf)).toEqual(head.data.slice(5, 10).map(keyOf))
|
|
207
425
|
// Offset pages still return a keyset cursor so clients can switch to deep
|
|
208
426
|
// cursor traversal from a positional jump.
|
|
@@ -285,7 +503,7 @@ describe('GET /transfers', () => {
|
|
|
285
503
|
expect(Number.isInteger(body.meta?.totalCount)).toBe(true)
|
|
286
504
|
expect(body.meta!.totalCount).toBeGreaterThanOrEqual(body.data.length)
|
|
287
505
|
expect(body.meta!.totalCount).toBeLessThanOrEqual(Schema.countCap)
|
|
288
|
-
expect(body.meta!.totalCountCapped).toBe(body.meta!.totalCount >= Schema.countCap)
|
|
506
|
+
expect(body.meta!.totalCountCapped).toBe(body.meta!.totalCount! >= Schema.countCap)
|
|
289
507
|
})
|
|
290
508
|
|
|
291
509
|
test('embeds a capped token-scoped total count on demand', async () => {
|
|
@@ -309,7 +527,7 @@ describe('GET /transfers', () => {
|
|
|
309
527
|
expect(typeof body.meta?.totalCountCapped).toBe('boolean')
|
|
310
528
|
// The count never exceeds the cap; `totalCountCapped` is set iff the cap was hit.
|
|
311
529
|
expect(body.meta!.totalCount).toBeLessThanOrEqual(Schema.countCap)
|
|
312
|
-
expect(body.meta!.totalCountCapped).toBe(body.meta!.totalCount >= Schema.countCap)
|
|
530
|
+
expect(body.meta!.totalCountCapped).toBe(body.meta!.totalCount! >= Schema.countCap)
|
|
313
531
|
|
|
314
532
|
// Without `include=totalCount`, the same page omits `meta` entirely and
|
|
315
533
|
// does not run the count query.
|
|
@@ -319,7 +537,10 @@ describe('GET /transfers', () => {
|
|
|
319
537
|
)
|
|
320
538
|
const bare = await TestApp.json(bareResponse, Transfers.schema.getTransfers.Response)
|
|
321
539
|
expect(bareResponse.status).toBe(200)
|
|
322
|
-
|
|
540
|
+
// Without the include, counts are omitted (`meta` carries at most rate
|
|
541
|
+
// provenance).
|
|
542
|
+
expect(bare.meta?.totalCount).toBeUndefined()
|
|
543
|
+
expect(bare.meta?.totalCountCapped).toBeUndefined()
|
|
323
544
|
expect(bareResponse.headers.get('server-timing')?.includes('transfers_count;dur=')).toBe(false)
|
|
324
545
|
})
|
|
325
546
|
|
|
@@ -351,6 +572,10 @@ describe('GET /transfers', () => {
|
|
|
351
572
|
expect(transfer.recipient).toBe(crossToken.recipient)
|
|
352
573
|
expect(transfer.sourceToken.address).toBe(crossToken.sourceToken)
|
|
353
574
|
expect(transfer.destinationToken?.address).toBe(crossToken.destinationToken)
|
|
575
|
+
expect(transfer.sourceAmount.baseUnits).toMatch(/^\d+$/)
|
|
576
|
+
expect(transfer.destinationAmount?.baseUnits).toMatch(/^\d+$/)
|
|
577
|
+
expect('amount' in transfer.sourceToken).toBe(false)
|
|
578
|
+
expect('amount' in transfer.destinationToken!).toBe(false)
|
|
354
579
|
|
|
355
580
|
// Without `include=crossToken`, the transaction stays as its raw per-log
|
|
356
581
|
// legs (more than one row) and no row carries `destinationToken`.
|
|
@@ -422,6 +647,91 @@ describe('GET /transfers', () => {
|
|
|
422
647
|
},
|
|
423
648
|
)
|
|
424
649
|
|
|
650
|
+
test('values verified transfer legs in the default denomination', async () => {
|
|
651
|
+
const db = TestApp.database()
|
|
652
|
+
await TestApp.verifiedSeed(db, Runtime.get().chainId)
|
|
653
|
+
const client = TestApp.client({ db })
|
|
654
|
+
|
|
655
|
+
// pathUSD is curated USD, so its legs value at identity with no rates.
|
|
656
|
+
const response = await client.v1.transfers.$get(
|
|
657
|
+
{ query: { limit: '5', token: TestApp.tokenWithHolders } },
|
|
658
|
+
TestApp.auth,
|
|
659
|
+
)
|
|
660
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
661
|
+
|
|
662
|
+
expect(response.status).toBe(200)
|
|
663
|
+
expect(body.data.length).toBeGreaterThan(0)
|
|
664
|
+
for (const entry of body.data)
|
|
665
|
+
expect(entry.sourceAmount.valuation).toEqual({
|
|
666
|
+
amount: core_Value.format(BigInt(entry.sourceAmount.baseUnits), 6),
|
|
667
|
+
currency: 'USD',
|
|
668
|
+
})
|
|
669
|
+
expect(body.meta?.pricing).toBeUndefined()
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
test('values transfer legs in a requested denomination', async () => {
|
|
673
|
+
const db = TestApp.database()
|
|
674
|
+
await TestApp.verifiedSeed(db, Runtime.get().chainId)
|
|
675
|
+
const client = TestApp.client({ db, fx: { oracle: fixed } })
|
|
676
|
+
|
|
677
|
+
// Denominations are case-insensitive.
|
|
678
|
+
const response = await client.v1.transfers.$get(
|
|
679
|
+
{ query: { denomination: 'aud', limit: '5', token: TestApp.tokenWithHolders } },
|
|
680
|
+
TestApp.auth,
|
|
681
|
+
)
|
|
682
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
683
|
+
|
|
684
|
+
expect(response.status).toBe(200)
|
|
685
|
+
expect(body.data.length).toBeGreaterThan(0)
|
|
686
|
+
// USD -> AUD at the fixed 1.6 cross rate, floored to 6 dp.
|
|
687
|
+
for (const entry of body.data)
|
|
688
|
+
expect(entry.sourceAmount.valuation).toEqual({
|
|
689
|
+
amount: core_Value.format((BigInt(entry.sourceAmount.baseUnits) * 16n) / 10n, 6),
|
|
690
|
+
currency: 'AUD',
|
|
691
|
+
})
|
|
692
|
+
expect(body.meta?.pricing).toMatchInlineSnapshot(`
|
|
693
|
+
{
|
|
694
|
+
"asOf": "2026-01-01T00:00:00.000Z",
|
|
695
|
+
"basis": "nominal",
|
|
696
|
+
"source": "fixed",
|
|
697
|
+
}
|
|
698
|
+
`)
|
|
699
|
+
})
|
|
700
|
+
|
|
701
|
+
test.skipIf(Runtime.get().mode !== 'localnet')(
|
|
702
|
+
'nulls leg values for unverified tokens',
|
|
703
|
+
async () => {
|
|
704
|
+
// Curate only pathUSD so the faucet token queried below is unverified
|
|
705
|
+
// for this app, and its legs never value.
|
|
706
|
+
const db = TestApp.database()
|
|
707
|
+
await TestApp.verifiedSeed(db, Runtime.get().chainId, {
|
|
708
|
+
tokens: [
|
|
709
|
+
{
|
|
710
|
+
address: TestApp.tokenWithHolders,
|
|
711
|
+
currency: 'USD',
|
|
712
|
+
decimals: 6,
|
|
713
|
+
name: 'PathUSD',
|
|
714
|
+
symbol: 'pathUSD',
|
|
715
|
+
},
|
|
716
|
+
],
|
|
717
|
+
})
|
|
718
|
+
const client = TestApp.client({ db })
|
|
719
|
+
|
|
720
|
+
const token = Runtime.get().fixtures!.transferTokenAddresses.find(
|
|
721
|
+
(address) => address.toLowerCase() !== TestApp.tokenWithHolders,
|
|
722
|
+
)!
|
|
723
|
+
const response = await client.v1.transfers.$get(
|
|
724
|
+
{ query: { limit: '5', token } },
|
|
725
|
+
TestApp.auth,
|
|
726
|
+
)
|
|
727
|
+
const body = await TestApp.json(response, Transfers.schema.getTransfers.Response)
|
|
728
|
+
|
|
729
|
+
expect(response.status).toBe(200)
|
|
730
|
+
expect(body.data.length).toBeGreaterThan(0)
|
|
731
|
+
for (const entry of body.data) expect(entry.sourceAmount.valuation).toBeNull()
|
|
732
|
+
},
|
|
733
|
+
)
|
|
734
|
+
|
|
425
735
|
test('surfaces a 502 when transfer data is unavailable', async () => {
|
|
426
736
|
// Point at an unreachable indexer so the upstream query fails deterministically.
|
|
427
737
|
const client = TestApp.client({ tidx: { baseUrl: 'http://127.0.0.1:1' } })
|