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
|
@@ -36,6 +36,9 @@ const row = {
|
|
|
36
36
|
rate_limit_scope: null,
|
|
37
37
|
request_id: 'req-1',
|
|
38
38
|
route: '/v1/transactions',
|
|
39
|
+
rpc_error_code: null,
|
|
40
|
+
rpc_error_count: 0,
|
|
41
|
+
rpc_error_data_code: null,
|
|
39
42
|
service: 'api',
|
|
40
43
|
status: 200,
|
|
41
44
|
timestamp: '2026-01-01 00:00:00.000',
|
|
@@ -211,6 +214,9 @@ describe('createQueueSink', () => {
|
|
|
211
214
|
rate_limit_scope: row.rate_limit_scope,
|
|
212
215
|
request_id: row.request_id,
|
|
213
216
|
route: row.route,
|
|
217
|
+
rpc_error_code: row.rpc_error_code,
|
|
218
|
+
rpc_error_count: row.rpc_error_count,
|
|
219
|
+
rpc_error_data_code: row.rpc_error_data_code,
|
|
214
220
|
service: row.service,
|
|
215
221
|
status: row.status,
|
|
216
222
|
timestamp: '<timestamp>',
|
|
@@ -229,6 +235,9 @@ describe('createQueueSink', () => {
|
|
|
229
235
|
"rate_limit_scope": null,
|
|
230
236
|
"request_id": "req-1",
|
|
231
237
|
"route": "/v1/transactions",
|
|
238
|
+
"rpc_error_code": null,
|
|
239
|
+
"rpc_error_count": 0,
|
|
240
|
+
"rpc_error_data_code": null,
|
|
232
241
|
"service": "api",
|
|
233
242
|
"status": 200,
|
|
234
243
|
"timestamp": "<timestamp>",
|
|
@@ -272,6 +281,24 @@ describe('createQueueSink', () => {
|
|
|
272
281
|
})
|
|
273
282
|
})
|
|
274
283
|
|
|
284
|
+
test('records JSON-RPC error metadata', async () => {
|
|
285
|
+
const send = vi.fn<(message: Analytics.Event) => Promise<void>>().mockResolvedValue(undefined)
|
|
286
|
+
const sink = Analytics.createQueueSink({ send })(context)
|
|
287
|
+
|
|
288
|
+
await sink({
|
|
289
|
+
...entry,
|
|
290
|
+
level: 'warn',
|
|
291
|
+
rpc: { code: -32602, dataCode: 'billing_required', errors: 2 },
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
expect(send.mock.calls[0]![0]).toMatchObject({
|
|
295
|
+
rpc_error_code: -32602,
|
|
296
|
+
rpc_error_count: 2,
|
|
297
|
+
rpc_error_data_code: 'billing_required',
|
|
298
|
+
status: 200,
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
|
|
275
302
|
test('rethrows when the retry also fails', async () => {
|
|
276
303
|
const send = vi
|
|
277
304
|
.fn<(message: Analytics.Event) => Promise<void>>()
|
|
@@ -399,6 +426,7 @@ describe('readProjectUsage', () => {
|
|
|
399
426
|
expect(query).toContain(`key_environment = 'sandbox'`)
|
|
400
427
|
expect(query).not.toContain('key_id IN')
|
|
401
428
|
expect(query).toContain('LIMIT 100')
|
|
429
|
+
expect(query).toContain('status >= 400 OR rpc_error_count > 0')
|
|
402
430
|
expect(new URL(String(fetch.mock.calls[0]![0])).searchParams.get('query')).toBeNull()
|
|
403
431
|
expect(usage).toMatchObject({
|
|
404
432
|
from: '2026-01-01T00:00:00.000Z',
|
|
@@ -408,6 +436,29 @@ describe('readProjectUsage', () => {
|
|
|
408
436
|
})
|
|
409
437
|
})
|
|
410
438
|
|
|
439
|
+
test('includes JSON-RPC failures in the error breakdown', async () => {
|
|
440
|
+
const fetch = vi.fn<typeof globalThis.fetch>().mockResolvedValue(
|
|
441
|
+
new Response(JSON.stringify({ data: [{ code: 'billing_required', requests: '2' }] }), {
|
|
442
|
+
status: 200,
|
|
443
|
+
}),
|
|
444
|
+
)
|
|
445
|
+
vi.stubGlobal('fetch', fetch)
|
|
446
|
+
|
|
447
|
+
const breakdown = await RequestEvents.readErrorBreakdown(Analytics.clickhouse(clickHouse), {
|
|
448
|
+
attributions: [{ projectId: 'prj_1' }],
|
|
449
|
+
from: '2026-01-01T00:00:00.000Z',
|
|
450
|
+
interval: 'day',
|
|
451
|
+
orgId: 'org_1',
|
|
452
|
+
to: '2026-01-02T00:00:00.000Z',
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
expect(fetch.mock.calls[0]![1]?.body).toEqual(expect.stringContaining('rpc_error_data_code'))
|
|
456
|
+
expect(fetch.mock.calls[0]![1]?.body).toEqual(
|
|
457
|
+
expect.stringContaining('status >= 400 OR rpc_error_count > 0'),
|
|
458
|
+
)
|
|
459
|
+
expect(breakdown).toEqual([{ code: 'billing_required', requests: 2 }])
|
|
460
|
+
})
|
|
461
|
+
|
|
411
462
|
test('keeps legacy rows scoped to project keys without global org filtering', async () => {
|
|
412
463
|
const fetch = vi
|
|
413
464
|
.fn<typeof globalThis.fetch>()
|
|
@@ -525,3 +576,35 @@ describe('readProjectUsage', () => {
|
|
|
525
576
|
})
|
|
526
577
|
})
|
|
527
578
|
})
|
|
579
|
+
|
|
580
|
+
describe('readLastUsedAt', () => {
|
|
581
|
+
test('returns the latest request timestamp for each requested key', async () => {
|
|
582
|
+
const fetch = vi.fn<typeof globalThis.fetch>().mockImplementation(async (_url, init) => {
|
|
583
|
+
const sql = init?.body
|
|
584
|
+
if (typeof sql !== 'string') throw new Error('Expected a SQL request body.')
|
|
585
|
+
expect(sql).toContain("key_id IN ('key_1', 'key_2')")
|
|
586
|
+
expect(sql).toContain('max(timestamp)')
|
|
587
|
+
return new Response(
|
|
588
|
+
JSON.stringify({
|
|
589
|
+
data: [{ key_id: 'key_1', lastUsedAt: '2026-07-21T12:34:56.000Z' }],
|
|
590
|
+
}),
|
|
591
|
+
{ status: 200 },
|
|
592
|
+
)
|
|
593
|
+
})
|
|
594
|
+
vi.stubGlobal('fetch', fetch)
|
|
595
|
+
|
|
596
|
+
await expect(
|
|
597
|
+
RequestEvents.readLastUsedAt(Analytics.clickhouse(clickHouse), ['key_1', 'key_2']),
|
|
598
|
+
).resolves.toEqual([{ apiKeyId: 'key_1', lastUsedAt: '2026-07-21T12:34:56.000Z' }])
|
|
599
|
+
})
|
|
600
|
+
|
|
601
|
+
test('skips the analytics query when no keys are requested', async () => {
|
|
602
|
+
const fetch = vi.fn<typeof globalThis.fetch>()
|
|
603
|
+
vi.stubGlobal('fetch', fetch)
|
|
604
|
+
|
|
605
|
+
await expect(
|
|
606
|
+
RequestEvents.readLastUsedAt(Analytics.clickhouse(clickHouse), []),
|
|
607
|
+
).resolves.toEqual([])
|
|
608
|
+
expect(fetch).not.toHaveBeenCalled()
|
|
609
|
+
})
|
|
610
|
+
})
|
|
@@ -131,6 +131,9 @@ export const migrations: readonly Migration[] = [
|
|
|
131
131
|
project_id Nullable(String),
|
|
132
132
|
rate_limit_scope Nullable(String),
|
|
133
133
|
error_code Nullable(String),
|
|
134
|
+
rpc_error_code Nullable(Int32),
|
|
135
|
+
rpc_error_data_code Nullable(String),
|
|
136
|
+
rpc_error_count UInt16 DEFAULT 0,
|
|
134
137
|
request_id Nullable(String),
|
|
135
138
|
billing_active Nullable(UInt8)
|
|
136
139
|
)
|
|
@@ -156,6 +159,23 @@ export const migrations: readonly Migration[] = [
|
|
|
156
159
|
ADD COLUMN IF NOT EXISTS billing_active Nullable(UInt8)
|
|
157
160
|
`,
|
|
158
161
|
},
|
|
162
|
+
{
|
|
163
|
+
name: '0003_request_events_rpc_errors',
|
|
164
|
+
// Patches tables created before RPC columns entered the baseline. Fresh
|
|
165
|
+
// tables include them, allowing scoped preview users without ALTER to skip.
|
|
166
|
+
guard: `
|
|
167
|
+
SELECT toUInt8(count() = 3) FROM system.columns
|
|
168
|
+
WHERE database = currentDatabase()
|
|
169
|
+
AND table = 'request_events'
|
|
170
|
+
AND name IN ('rpc_error_code', 'rpc_error_data_code', 'rpc_error_count')
|
|
171
|
+
`,
|
|
172
|
+
sql: `
|
|
173
|
+
ALTER TABLE request_events
|
|
174
|
+
ADD COLUMN IF NOT EXISTS rpc_error_code Nullable(Int32),
|
|
175
|
+
ADD COLUMN IF NOT EXISTS rpc_error_data_code Nullable(String),
|
|
176
|
+
ADD COLUMN IF NOT EXISTS rpc_error_count UInt16 DEFAULT 0
|
|
177
|
+
`,
|
|
178
|
+
},
|
|
159
179
|
]
|
|
160
180
|
|
|
161
181
|
/**
|
|
@@ -30,6 +30,12 @@ export type Table = {
|
|
|
30
30
|
principal_type: 'api_key' | 'public' | 'session' | 'super_admin' | 'unknown'
|
|
31
31
|
/** Rate-limit bucket scope, when a rate limit was applied. */
|
|
32
32
|
rate_limit_scope: string | null
|
|
33
|
+
/** Numeric JSON-RPC error code when every failed response shares one code. */
|
|
34
|
+
rpc_error_code: number | null
|
|
35
|
+
/** Stable application error code from JSON-RPC `error.data.code`. */
|
|
36
|
+
rpc_error_data_code: string | null
|
|
37
|
+
/** Number of failed JSON-RPC responses in the request. */
|
|
38
|
+
rpc_error_count: number
|
|
33
39
|
/** Stable per-request id (`entry.requestId`); dedups the billing count via `uniqExact`. */
|
|
34
40
|
request_id: string | null
|
|
35
41
|
/** Bounded matched route pattern. */
|
|
@@ -79,6 +85,14 @@ export type KeyBreakdown = {
|
|
|
79
85
|
requests: number
|
|
80
86
|
}
|
|
81
87
|
|
|
88
|
+
/** Latest authenticated request timestamp for one API key. */
|
|
89
|
+
export type LastUsedAt = {
|
|
90
|
+
/** API key id (`key_…`). */
|
|
91
|
+
apiKeyId: string
|
|
92
|
+
/** Latest request completion timestamp (ISO 8601). */
|
|
93
|
+
lastUsedAt: string
|
|
94
|
+
}
|
|
95
|
+
|
|
82
96
|
/** Time bucket size for the usage series. */
|
|
83
97
|
export type Interval = 'day' | 'hour'
|
|
84
98
|
|
|
@@ -227,6 +241,32 @@ export declare namespace insertMessages {
|
|
|
227
241
|
}
|
|
228
242
|
}
|
|
229
243
|
|
|
244
|
+
/**
|
|
245
|
+
* Reads the latest authenticated request timestamp for each requested API key.
|
|
246
|
+
* Keys with no request events are omitted.
|
|
247
|
+
*/
|
|
248
|
+
export async function readLastUsedAt(
|
|
249
|
+
analytics: Analytics.Analytics,
|
|
250
|
+
apiKeyIds: readonly string[],
|
|
251
|
+
): Promise<LastUsedAt[]> {
|
|
252
|
+
if (apiKeyIds.length === 0) return []
|
|
253
|
+
const rows = await analytics.query<LastUsedAtRow>(
|
|
254
|
+
`
|
|
255
|
+
SELECT
|
|
256
|
+
key_id,
|
|
257
|
+
formatDateTime(max(timestamp), '%Y-%m-%dT%H:%i:%S.000Z', 'UTC') AS lastUsedAt
|
|
258
|
+
FROM ${table}
|
|
259
|
+
WHERE principal_type = 'api_key'
|
|
260
|
+
AND key_id IN (${apiKeyIds.map(literal).join(', ')})
|
|
261
|
+
GROUP BY key_id
|
|
262
|
+
`,
|
|
263
|
+
)
|
|
264
|
+
return rows.map((row) => ({
|
|
265
|
+
apiKeyId: String(row.key_id),
|
|
266
|
+
lastUsedAt: String(row.lastUsedAt),
|
|
267
|
+
}))
|
|
268
|
+
}
|
|
269
|
+
|
|
230
270
|
/**
|
|
231
271
|
* Reads request usage for one project from the `request_events` table.
|
|
232
272
|
*
|
|
@@ -247,7 +287,7 @@ export async function readProjectUsage(
|
|
|
247
287
|
SELECT
|
|
248
288
|
key_id,
|
|
249
289
|
count() AS requests,
|
|
250
|
-
countIf(status >= 400) AS errors,
|
|
290
|
+
countIf(status >= 400 OR rpc_error_count > 0) AS errors,
|
|
251
291
|
${average} AS averageDurationMs
|
|
252
292
|
FROM ${table}
|
|
253
293
|
WHERE ${where} AND key_id IS NOT NULL
|
|
@@ -261,7 +301,7 @@ export async function readProjectUsage(
|
|
|
261
301
|
SELECT
|
|
262
302
|
route,
|
|
263
303
|
count() AS requests,
|
|
264
|
-
countIf(status >= 400) AS errors,
|
|
304
|
+
countIf(status >= 400 OR rpc_error_count > 0) AS errors,
|
|
265
305
|
${average} AS averageDurationMs
|
|
266
306
|
FROM ${table}
|
|
267
307
|
WHERE ${where}
|
|
@@ -286,7 +326,7 @@ export async function readProjectUsage(
|
|
|
286
326
|
SELECT
|
|
287
327
|
formatDateTime(${bucket}, '%Y-%m-%dT%H:%i:%S.000Z', 'UTC') AS time,
|
|
288
328
|
count() AS requests,
|
|
289
|
-
countIf(status >= 400) AS errors
|
|
329
|
+
countIf(status >= 400 OR rpc_error_count > 0) AS errors
|
|
290
330
|
FROM ${table}
|
|
291
331
|
WHERE ${where}
|
|
292
332
|
GROUP BY ${bucket}
|
|
@@ -297,7 +337,7 @@ export async function readProjectUsage(
|
|
|
297
337
|
`
|
|
298
338
|
SELECT
|
|
299
339
|
count() AS requests,
|
|
300
|
-
countIf(status >= 400) AS errors,
|
|
340
|
+
countIf(status >= 400 OR rpc_error_count > 0) AS errors,
|
|
301
341
|
${average} AS averageDurationMs
|
|
302
342
|
FROM ${table}
|
|
303
343
|
WHERE ${where}
|
|
@@ -347,11 +387,16 @@ export async function readErrorBreakdown(
|
|
|
347
387
|
const rows = await analytics.query<ErrorRow>(
|
|
348
388
|
`
|
|
349
389
|
SELECT
|
|
350
|
-
coalesce(
|
|
390
|
+
coalesce(
|
|
391
|
+
error_code,
|
|
392
|
+
rpc_error_data_code,
|
|
393
|
+
if(rpc_error_count > 0 AND rpc_error_code IS NOT NULL, concat('rpc_', toString(rpc_error_code)), NULL),
|
|
394
|
+
if(rpc_error_count > 0, 'rpc_multiple', 'unknown')
|
|
395
|
+
) AS code,
|
|
351
396
|
count() AS requests
|
|
352
397
|
FROM ${table}
|
|
353
|
-
WHERE ${usageWhere(options)} AND status >= 400
|
|
354
|
-
GROUP BY
|
|
398
|
+
WHERE ${usageWhere(options)} AND (status >= 400 OR rpc_error_count > 0)
|
|
399
|
+
GROUP BY code
|
|
355
400
|
ORDER BY requests DESC, code ASC
|
|
356
401
|
LIMIT 25
|
|
357
402
|
`,
|
|
@@ -434,6 +479,11 @@ type KeyRow = {
|
|
|
434
479
|
requests: number | string
|
|
435
480
|
}
|
|
436
481
|
|
|
482
|
+
type LastUsedAtRow = {
|
|
483
|
+
key_id: string
|
|
484
|
+
lastUsedAt: string
|
|
485
|
+
}
|
|
486
|
+
|
|
437
487
|
type ErrorRow = {
|
|
438
488
|
code: string
|
|
439
489
|
requests: number | string
|
|
@@ -480,6 +530,9 @@ function event(entry: Log.Entry, context: Metrics.cloudflare.Context): Table {
|
|
|
480
530
|
rate_limit_scope: entry.rateLimit?.scope ?? null,
|
|
481
531
|
request_id: entry.requestId ?? null,
|
|
482
532
|
route: entry.route,
|
|
533
|
+
rpc_error_code: entry.rpc?.code ?? null,
|
|
534
|
+
rpc_error_count: entry.rpc?.errors ?? 0,
|
|
535
|
+
rpc_error_data_code: entry.rpc?.dataCode ?? null,
|
|
483
536
|
service: context.service ?? 'unknown',
|
|
484
537
|
status: entry.status,
|
|
485
538
|
timestamp: timestamp(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { App, Store } from 'tapimo'
|
|
2
|
-
import { data, management, relay } from 'tapimo/apps'
|
|
2
|
+
import { data, management, mpp, relay } from 'tapimo/apps'
|
|
3
3
|
import { Hono } from 'hono'
|
|
4
4
|
import { describeRoute } from 'hono-openapi'
|
|
5
5
|
import * as TestApp from '../../test/App.js'
|
|
@@ -190,7 +190,7 @@ describe('data()', () => {
|
|
|
190
190
|
})
|
|
191
191
|
|
|
192
192
|
describe('relay()', () => {
|
|
193
|
-
test('mounts the relay after data()
|
|
193
|
+
test('mounts the relay after data() without documenting RPC routes', async () => {
|
|
194
194
|
const composed = App.create({ db: TestApp.database() }).route('/', data()).route('/', relay())
|
|
195
195
|
|
|
196
196
|
// Mounted but default-closed and hidden: unauthenticated requests are
|
|
@@ -209,6 +209,15 @@ describe('relay()', () => {
|
|
|
209
209
|
})
|
|
210
210
|
})
|
|
211
211
|
|
|
212
|
+
describe('mpp()', () => {
|
|
213
|
+
test('mounts documented MPP routes independently', async () => {
|
|
214
|
+
const app = App.create({ db: TestApp.database() }).route('/', mpp())
|
|
215
|
+
|
|
216
|
+
expect((await paths(app)).some((path) => path.startsWith('/v1/mpp'))).toBe(true)
|
|
217
|
+
expect((await app.request('/rpc/relay')).status).toBe(404)
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
|
|
212
221
|
describe('management()', () => {
|
|
213
222
|
test('mounts management routes and omits data routes', async () => {
|
|
214
223
|
const app = App.create({
|
|
@@ -254,7 +254,7 @@ describe('zone chain gate', () => {
|
|
|
254
254
|
for (const path of [
|
|
255
255
|
`/v1/tokens?chainId=${zone}`,
|
|
256
256
|
`/v1/addresses/0x0000000000000000000000000000000000000001/activities?chainId=${zone}`,
|
|
257
|
-
`/v1/transfers?chainId=${zone}&include=token`,
|
|
257
|
+
`/v1/transfers?chainId=${zone}&include=token.verified`,
|
|
258
258
|
]) {
|
|
259
259
|
const response = await app.request(path)
|
|
260
260
|
const body = (await response.json()) as { error: { code: string; message: string } }
|
package/src/apps/data/App.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as Tidx from '../../internal/Tidx.js'
|
|
|
14
14
|
import * as Viem from '../../internal/Viem.js'
|
|
15
15
|
import * as Scope from '../../Scope.js'
|
|
16
16
|
import * as Metadata from '../metadata.js'
|
|
17
|
+
import type * as FxOracle from './FxOracle.js'
|
|
17
18
|
|
|
18
19
|
import { transactions as transactionActivities } from './routes/activities.js'
|
|
19
20
|
import { addresses } from './routes/addresses.js'
|
|
@@ -42,6 +43,12 @@ import { schema as webhookSchema, webhooks } from './routes/webhooks.js'
|
|
|
42
43
|
*/
|
|
43
44
|
export function data(options: data.Options = {}) {
|
|
44
45
|
const { assets, tidx } = options
|
|
46
|
+
const webhook =
|
|
47
|
+
options.webhook === false
|
|
48
|
+
? undefined
|
|
49
|
+
: (options.webhook ?? {
|
|
50
|
+
supportedChainIds: [Viem.chainId.mainnet, Viem.chainId.testnet],
|
|
51
|
+
})
|
|
45
52
|
|
|
46
53
|
// Zone endpoints are explicit trust boundaries; the API never derives them.
|
|
47
54
|
const zones = new Map((options.zones ?? []).map((zone) => [zone.chainId, zone]))
|
|
@@ -66,7 +73,7 @@ export function data(options: data.Options = {}) {
|
|
|
66
73
|
c.set('supportedChainIds', supportedChainIds)
|
|
67
74
|
c.set('tidx', tidx)
|
|
68
75
|
c.set('verifiedTokens', options.verifiedTokens === false ? undefined : (options.verifiedTokens ?? {})) // prettier-ignore
|
|
69
|
-
c.set('webhook',
|
|
76
|
+
c.set('webhook', webhook)
|
|
70
77
|
c.set('zones', zones)
|
|
71
78
|
await next()
|
|
72
79
|
})
|
|
@@ -158,18 +165,18 @@ export function data(options: data.Options = {}) {
|
|
|
158
165
|
'Content-Type': asset.contentType,
|
|
159
166
|
})
|
|
160
167
|
})
|
|
161
|
-
.route('/', addresses())
|
|
168
|
+
.route('/', addresses({ fx: options.fx }))
|
|
162
169
|
.route('/', blocks())
|
|
163
|
-
.route('/', exchanges())
|
|
170
|
+
.route('/', exchanges({ fx: options.fx }))
|
|
164
171
|
.route('/', feeAmm())
|
|
165
172
|
.route('/', funding(options.funding))
|
|
166
173
|
.route('/', indexer())
|
|
167
|
-
.route('/', receipts())
|
|
174
|
+
.route('/', receipts({ fx: options.fx }))
|
|
168
175
|
.route('/', tokenlist())
|
|
169
176
|
.route('/', tokens())
|
|
170
177
|
.route('/', transactions())
|
|
171
|
-
.route('/', transactionActivities())
|
|
172
|
-
.route('/', transfers())
|
|
178
|
+
.route('/', transactionActivities({ fx: options.fx }))
|
|
179
|
+
.route('/', transfers({ fx: options.fx }))
|
|
173
180
|
.route('/', verifiedTokens())
|
|
174
181
|
.route('/', webhooks({ enabled: options.webhook !== false }))
|
|
175
182
|
.route('/', rpc())
|
|
@@ -206,6 +213,8 @@ export declare namespace data {
|
|
|
206
213
|
assets?: Assets.Assets | undefined
|
|
207
214
|
/** Funding quote provider configuration. */
|
|
208
215
|
funding?: funding.Options | undefined
|
|
216
|
+
/** FX configuration for the valuation endpoint. */
|
|
217
|
+
fx?: Fx | undefined
|
|
209
218
|
/** TIDX query client options. */
|
|
210
219
|
tidx?: Tidx.getClient.Tidx | undefined
|
|
211
220
|
/** Verified-token feature configuration. Enabled by default (token rows live in `db`; empty until published); pass `false` to always serve an empty verified list. */
|
|
@@ -219,6 +228,12 @@ export declare namespace data {
|
|
|
219
228
|
zones?: readonly Zone[] | undefined
|
|
220
229
|
}
|
|
221
230
|
|
|
231
|
+
/** FX configuration for the valuation endpoint. */
|
|
232
|
+
type Fx = {
|
|
233
|
+
/** FX rate oracle backing currency conversion. Defaults to the ECB daily reference rates (`FxOracle.ecb()`). */
|
|
234
|
+
oracle?: FxOracle.Oracle | undefined
|
|
235
|
+
}
|
|
236
|
+
|
|
222
237
|
/** One zone chain served by this deployment. */
|
|
223
238
|
type Zone = {
|
|
224
239
|
/** Zone chain id. Consumer-supplied literal; the API never derives zone chain ids. */
|
|
@@ -238,14 +253,7 @@ export declare namespace data {
|
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
/** Webhook feature configuration. */
|
|
241
|
-
type Webhook =
|
|
242
|
-
/**
|
|
243
|
-
* Maximum active subscriptions per owner; creation is rejected with
|
|
244
|
-
* `403 limit_exceeded` once reached. Defaults to 100, bounding the spam/SSRF
|
|
245
|
-
* and delivery-cost surface per owner.
|
|
246
|
-
*/
|
|
247
|
-
maxPerOwner?: number | undefined
|
|
248
|
-
}
|
|
256
|
+
type Webhook = App.Webhook
|
|
249
257
|
}
|
|
250
258
|
|
|
251
259
|
function resolveChainSelector(options: {
|