tapimo 0.12.0 → 0.14.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 +11333 -9563
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +39 -3
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.js +2 -2
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +1064 -924
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +80 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +63 -15
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +2 -1
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +92 -3
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +69 -7
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +7 -7
- 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 -151
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +28 -28
- package/dist/apps/Zones.js +7 -7
- package/dist/apps/data/App.d.ts +2909 -2523
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +26 -21
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +8 -8
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
- package/dist/apps/data/ZoneSelection.js +1 -1
- package/dist/apps/data/ZoneSelection.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +588 -584
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1561 -1239
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +22 -22
- package/dist/apps/data/routes/balances.d.ts +26 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +43 -16
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +44 -44
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +21 -11
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +3 -3
- package/dist/apps/data/routes/earn.d.ts +201 -25
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +434 -75
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +160 -145
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +180 -114
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +18 -19
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +155 -55
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +28 -10
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokens.d.ts +5 -5
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +51 -20
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +37 -17
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +13 -13
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +18 -12
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +31 -31
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +8 -8
- package/dist/apps/data/routes/webhooks.d.ts +816 -113
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +47 -5
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +14 -14
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +466 -44
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/App.js +1 -1
- package/dist/apps/funding/App.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +17 -17
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +17 -12
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +650 -57
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +238 -24
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +5120 -4152
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +17 -1
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +632 -81
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +236 -4
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +76 -76
- package/dist/apps/management/routes/faucet.d.ts +6 -6
- package/dist/apps/management/routes/invitations.d.ts +24 -24
- package/dist/apps/management/routes/invite-links.d.ts +4 -4
- package/dist/apps/management/routes/members.d.ts +16 -16
- package/dist/apps/management/routes/orgs.d.ts +20 -20
- package/dist/apps/management/routes/projects.d.ts +4 -4
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/verified-token-requests.d.ts +17 -17
- package/dist/apps/management/routes/webhooks.d.ts +675 -25
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +21 -21
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +115 -23
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +27 -1
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +34 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +11 -5
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +21 -3
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/db/tables/fundingTransferTransactions.d.ts +38 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -1
- package/dist/db/tables/fundingTransferTransactions.js +44 -3
- package/dist/db/tables/fundingTransferTransactions.js.map +1 -1
- package/dist/db/tables/fundingTransfers.d.ts +17 -0
- package/dist/db/tables/fundingTransfers.d.ts.map +1 -1
- package/dist/db/tables/fundingTransfers.js +21 -0
- package/dist/db/tables/fundingTransfers.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +24 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +27 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +25 -1
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +26 -0
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +44 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +146 -13
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +10 -6
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +9 -6
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +3 -1
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +6 -3
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +3 -3
- package/dist/internal/EarnVaults.js +5 -5
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +4 -2
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +5 -3
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +13 -3
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +1 -1
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Schema.d.ts +6 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +8 -2
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +16 -3
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +82 -16
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +7 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/Viem.d.ts +16 -1
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +12 -2
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/DepositWebhook.d.ts.map +1 -1
- package/dist/internal/funding/DepositWebhook.js +2 -1
- package/dist/internal/funding/DepositWebhook.js.map +1 -1
- package/dist/internal/funding/Evidence.d.ts.map +1 -1
- package/dist/internal/funding/Evidence.js +2 -10
- package/dist/internal/funding/Evidence.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +108 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +34 -8
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/SourceObservation.d.ts.map +1 -1
- package/dist/internal/funding/SourceObservation.js +5 -7
- package/dist/internal/funding/SourceObservation.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +114 -18
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +185 -55
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/TransferReconciliation.d.ts +52 -0
- package/dist/internal/funding/TransferReconciliation.d.ts.map +1 -0
- package/dist/internal/funding/TransferReconciliation.js +192 -0
- package/dist/internal/funding/TransferReconciliation.js.map +1 -0
- package/dist/internal/funding/TransferWebhook.d.ts +21 -0
- package/dist/internal/funding/TransferWebhook.d.ts.map +1 -0
- package/dist/internal/funding/TransferWebhook.js +43 -0
- package/dist/internal/funding/TransferWebhook.js.map +1 -0
- package/dist/internal/funding/index.d.ts +1 -0
- package/dist/internal/funding/index.d.ts.map +1 -1
- package/dist/internal/funding/index.js +1 -0
- package/dist/internal/funding/index.js.map +1 -1
- package/dist/internal/funding/providers/relay.d.ts.map +1 -1
- package/dist/internal/funding/providers/relay.js +3 -12
- package/dist/internal/funding/providers/relay.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +127 -9
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
- package/dist/internal/funding/providers/stargate.js +548 -112
- package/dist/internal/funding/providers/stargate.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
- package/dist/internal/webhookDestinations/slack.js +16 -0
- package/dist/internal/webhookDestinations/slack.js.map +1 -1
- package/package.json +2 -2
- package/src/App.test.ts +100 -0
- package/src/App.ts +43 -3
- package/src/Client.test-d.ts +129 -2
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/Webhooks.ts +2 -2
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +1 -1
- package/src/admin/apps/earn-vaults.ts +2 -1
- package/src/admin/apps/organizations.test.ts +53 -1
- package/src/admin/apps/organizations.ts +90 -5
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/lib/organizations.test.ts +112 -1
- package/src/admin/ui/src/lib/organizations.ts +55 -0
- package/src/admin/ui/src/routes/api-keys.tsx +89 -2
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +116 -0
- package/src/admin/ui.generated.ts +189 -151
- package/src/apps/Zones.test.ts +7 -7
- package/src/apps/Zones.ts +7 -7
- package/src/apps/composition.test.ts +2 -1
- package/src/apps/data/App.test.ts +41 -0
- package/src/apps/data/App.ts +30 -21
- package/src/apps/data/ZoneSelection.test.ts +2 -2
- package/src/apps/data/ZoneSelection.ts +8 -8
- package/src/apps/data/routes/activities.test.ts +1526 -12
- package/src/apps/data/routes/activities.ts +1774 -1356
- package/src/apps/data/routes/balances.ts +133 -97
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +35 -16
- package/src/apps/data/routes/earn.test.ts +373 -16
- package/src/apps/data/routes/earn.ts +548 -79
- package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
- package/src/apps/data/routes/exchanges.test.ts +740 -15
- package/src/apps/data/routes/exchanges.ts +954 -753
- package/src/apps/data/routes/fee-amm.ts +17 -18
- package/src/apps/data/routes/receipts.ts +47 -16
- package/src/apps/data/routes/tokens.test.ts +578 -0
- package/src/apps/data/routes/tokens.ts +283 -225
- package/src/apps/data/routes/transactions.ts +68 -29
- package/src/apps/data/routes/transfers.test.ts +421 -0
- package/src/apps/data/routes/transfers.ts +45 -27
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/webhooks.test.ts +21 -5
- package/src/apps/data/routes/webhooks.ts +63 -8
- package/src/apps/data/routes/zones.test.ts +2 -2
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/App.ts +12 -2
- package/src/apps/funding/routes/deposit-addresses.test.ts +29 -7
- package/src/apps/funding/routes/deposit-addresses.ts +19 -14
- package/src/apps/funding/routes/quotes.test.ts +5 -9
- package/src/apps/funding/routes/transfers.test.ts +901 -23
- package/src/apps/funding/routes/transfers.ts +347 -64
- package/src/apps/management/Billing.ts +18 -5
- package/src/apps/management/routes/api-keys.test.ts +220 -0
- package/src/apps/management/routes/api-keys.ts +280 -3
- package/src/apps/management/routes/webhooks.test.ts +3 -3
- package/src/apps/management/routes/webhooks.ts +24 -25
- package/src/apps/relay/App.test.ts +212 -1
- package/src/apps/relay/App.ts +158 -29
- package/src/apps/relay/Sponsorships.ts +24 -1
- package/src/db/Db.ts +48 -1
- package/src/db/Schema.ts +22 -4
- package/src/db/tables/earnVaults.test.ts +9 -9
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/db/tables/fundingTransferTransactions.test.ts +43 -0
- package/src/db/tables/fundingTransferTransactions.ts +79 -3
- package/src/db/tables/fundingTransfers.test.ts +26 -0
- package/src/db/tables/fundingTransfers.ts +36 -0
- package/src/db/tables/organizations.test.ts +41 -0
- package/src/db/tables/organizations.ts +49 -0
- package/src/db/tables/projects.test.ts +55 -0
- package/src/db/tables/projects.ts +46 -1
- package/src/db/tables/sponsoredTransactions.test.ts +338 -0
- package/src/db/tables/sponsoredTransactions.ts +197 -13
- package/src/db/tables/webhookSubscriptions.ts +18 -11
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +12 -4
- package/src/internal/EarnVaults.capabilities.test.ts +2 -2
- package/src/internal/EarnVaults.test.ts +1 -1
- package/src/internal/EarnVaults.ts +5 -5
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test-d.ts +2 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +22 -5
- package/src/internal/OpenApi.ts +14 -4
- package/src/internal/Response.ts +1 -1
- package/src/internal/Schema.test.ts +2 -0
- package/src/internal/Schema.ts +12 -2
- package/src/internal/Store.test.ts +178 -0
- package/src/internal/Store.ts +104 -18
- package/src/internal/Tidx.test.ts +2 -1
- package/src/internal/Tidx.ts +7 -2
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/Viem.ts +39 -3
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/Webhooks.test.ts +45 -0
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/DepositWebhook.ts +2 -1
- package/src/internal/funding/Evidence.ts +2 -13
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +125 -28
- package/src/internal/funding/SourceObservation.ts +5 -9
- package/src/internal/funding/Transfer.test.ts +155 -0
- package/src/internal/funding/Transfer.ts +387 -147
- package/src/internal/funding/TransferReconciliation.test.ts +147 -0
- package/src/internal/funding/TransferReconciliation.ts +264 -0
- package/src/internal/funding/TransferWebhook.test.ts +128 -0
- package/src/internal/funding/TransferWebhook.ts +67 -0
- package/src/internal/funding/index.test.ts +1 -0
- package/src/internal/funding/index.ts +1 -0
- package/src/internal/funding/providers/index.test.ts +4 -167
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/relay.ts +3 -15
- package/src/internal/funding/providers/stargate.test.ts +328 -0
- package/src/internal/funding/providers/stargate.ts +807 -135
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/internal/webhookDestinations/slack.ts +15 -0
|
@@ -310,11 +310,11 @@ function privateResourceAccess(access: Webhooks.Access) {
|
|
|
310
310
|
)
|
|
311
311
|
return (eb: ExpressionBuilder<Db.Database, 'webhook_subscriptions'>) =>
|
|
312
312
|
eb.or([
|
|
313
|
-
eb('eventType'
|
|
313
|
+
sql<boolean>`${eb.ref('eventType')} not like ${'funding:%'}`,
|
|
314
314
|
...(fundingRead
|
|
315
315
|
? [
|
|
316
316
|
eb.and([
|
|
317
|
-
eb('eventType'
|
|
317
|
+
sql<boolean>`${eb.ref('eventType')} like ${'funding:%'}`,
|
|
318
318
|
eb('environment', '=', access.environment),
|
|
319
319
|
...(access.projectId === undefined ? [] : [eb('projectId', '=', access.projectId)]),
|
|
320
320
|
]),
|
|
@@ -390,41 +390,48 @@ export declare namespace listActiveForChain {
|
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
/** Lists live funding
|
|
394
|
-
export async function
|
|
393
|
+
/** Lists live funding subscriptions visible to one resource owner. */
|
|
394
|
+
export async function listActiveForFundingEvent(
|
|
395
395
|
db: Db.Db,
|
|
396
|
-
options:
|
|
396
|
+
options: listActiveForFundingEvent.Options,
|
|
397
397
|
): Promise<Webhooks.Subscription[]> {
|
|
398
398
|
let query = db.kysely
|
|
399
399
|
.selectFrom('webhook_subscriptions')
|
|
400
400
|
.selectAll()
|
|
401
401
|
.where('chainId', '=', options.chainId)
|
|
402
402
|
.where('environment', '=', options.environment)
|
|
403
|
-
.where('eventType', '=',
|
|
403
|
+
.where('eventType', '=', options.eventType)
|
|
404
404
|
.where('ownerId', '=', options.orgId)
|
|
405
405
|
.where('ownerType', '=', 'api_key')
|
|
406
406
|
.where('status', '=', 'active')
|
|
407
407
|
.where(live(options.now))
|
|
408
|
+
if (options.eventCreatedAt !== undefined)
|
|
409
|
+
query = query.where('createdAt', '<=', options.eventCreatedAt)
|
|
408
410
|
const projectId = options.projectId
|
|
409
411
|
query =
|
|
410
412
|
projectId === undefined
|
|
411
413
|
? query.where('projectId', 'is', null)
|
|
412
414
|
: query.where((eb) => eb.or([eb('projectId', 'is', null), eb('projectId', '=', projectId)]))
|
|
413
|
-
|
|
415
|
+
// Keep subscriptions present until their staged queue events commit.
|
|
416
|
+
return (await query.orderBy('id').forKeyShare().execute()).map(toSubscription)
|
|
414
417
|
}
|
|
415
418
|
|
|
416
|
-
export declare namespace
|
|
417
|
-
/** Ownership scope and chain for a funding
|
|
419
|
+
export declare namespace listActiveForFundingEvent {
|
|
420
|
+
/** Ownership scope and chain for a funding resource event. */
|
|
418
421
|
type Options = {
|
|
419
422
|
/** Destination Tempo chain id. */
|
|
420
423
|
chainId: number
|
|
421
|
-
/**
|
|
424
|
+
/** Resource API-key environment. */
|
|
422
425
|
environment: 'production' | 'sandbox'
|
|
426
|
+
/** Event timestamp used to keep subscriptions future-only, when supplied. */
|
|
427
|
+
eventCreatedAt?: string | undefined
|
|
428
|
+
/** Funding event type to match. */
|
|
429
|
+
eventType: Extract<Webhooks.EventType, `funding:${string}`>
|
|
423
430
|
/** ISO timestamp used to exclude expired subscriptions. */
|
|
424
431
|
now: string
|
|
425
432
|
/** Owning organization id. */
|
|
426
433
|
orgId: string
|
|
427
|
-
/** Attributed
|
|
434
|
+
/** Attributed funding resource project, when present. */
|
|
428
435
|
projectId?: string | undefined
|
|
429
436
|
}
|
|
430
437
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { RpcRequest } from 'ox'
|
|
2
|
+
|
|
3
|
+
import * as Utils from './utils.js'
|
|
4
|
+
|
|
5
|
+
const request = RpcRequest.from({ id: 1, method: 'eth_sendRawTransaction', params: ['0x'] })
|
|
6
|
+
|
|
7
|
+
describe('rpcErrorJson', () => {
|
|
8
|
+
test('maps upstream expired transactions to a transaction-rejected error', () => {
|
|
9
|
+
const error = {
|
|
10
|
+
cause: {
|
|
11
|
+
code: -32603,
|
|
12
|
+
message:
|
|
13
|
+
'Revm error: transaction expired: current block timestamp 1755616740 >= validBefore 1755616739',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
expect(Utils.rpcErrorJson(request, error)).toMatchInlineSnapshot(`
|
|
18
|
+
{
|
|
19
|
+
"error": {
|
|
20
|
+
"code": -32003,
|
|
21
|
+
"data": {
|
|
22
|
+
"code": "transaction_expired",
|
|
23
|
+
},
|
|
24
|
+
"message": "Transaction expired.",
|
|
25
|
+
},
|
|
26
|
+
"id": 1,
|
|
27
|
+
"jsonrpc": "2.0",
|
|
28
|
+
}
|
|
29
|
+
`)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('preserves unrelated upstream internal errors', () => {
|
|
33
|
+
const error = {
|
|
34
|
+
code: -32603,
|
|
35
|
+
data: { reason: 'database unavailable' },
|
|
36
|
+
message: 'Revm error: database unavailable',
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
expect(Utils.rpcErrorJson(request, error)).toMatchInlineSnapshot(`
|
|
40
|
+
{
|
|
41
|
+
"error": {
|
|
42
|
+
"code": -32603,
|
|
43
|
+
"data": {
|
|
44
|
+
"reason": "database unavailable",
|
|
45
|
+
},
|
|
46
|
+
"message": "Revm error: database unavailable",
|
|
47
|
+
},
|
|
48
|
+
"id": 1,
|
|
49
|
+
"jsonrpc": "2.0",
|
|
50
|
+
}
|
|
51
|
+
`)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -127,6 +127,21 @@ export function rpcErrorJson(request: RpcRequest.RpcRequest, error: unknown) {
|
|
|
127
127
|
{ request },
|
|
128
128
|
)
|
|
129
129
|
|
|
130
|
+
if (
|
|
131
|
+
inner.code === RpcResponse.InternalError.code &&
|
|
132
|
+
/^Revm error: transaction expired(?:\.|: .+)?$/.test(inner.message)
|
|
133
|
+
)
|
|
134
|
+
return RpcResponse.from(
|
|
135
|
+
{
|
|
136
|
+
error: {
|
|
137
|
+
code: RpcResponse.TransactionRejectedError.code,
|
|
138
|
+
data: { code: 'transaction_expired' },
|
|
139
|
+
message: 'Transaction expired.',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{ request },
|
|
143
|
+
)
|
|
144
|
+
|
|
130
145
|
const { code, data, message } = inner
|
|
131
146
|
return RpcResponse.from(
|
|
132
147
|
{
|
package/src/internal/Auth.ts
CHANGED
|
@@ -676,7 +676,10 @@ export declare namespace middleware {
|
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
/** MPP payment options used by auth middleware. */
|
|
679
|
-
type MppOptions = Omit<
|
|
679
|
+
type MppOptions = Omit<
|
|
680
|
+
Parameters<typeof Mppx.create<readonly [ReturnType<typeof tempo.session>]>>[0],
|
|
681
|
+
'methods'
|
|
682
|
+
> & {
|
|
680
683
|
/** Paid-request quota per access principal. Defaults to 100 per minute. */
|
|
681
684
|
rateLimit?: RateLimit.Limit | undefined
|
|
682
685
|
/** Global Tempo Session options passed to the MPP method instantiator. */
|
|
@@ -1451,8 +1454,8 @@ export function require<environment extends Environment = Environment>(
|
|
|
1451
1454
|
return proceed()
|
|
1452
1455
|
}
|
|
1453
1456
|
|
|
1454
|
-
const
|
|
1455
|
-
if (!
|
|
1457
|
+
const apiKey_resolved = await auth.apiKey?.resolve(c, credential.token)
|
|
1458
|
+
if (!apiKey_resolved) {
|
|
1456
1459
|
// A bearer session token is indistinguishable from an API key at the
|
|
1457
1460
|
// header, so a failed key lookup falls through to the session lane
|
|
1458
1461
|
// before rejecting.
|
|
@@ -1470,6 +1473,10 @@ export function require<environment extends Environment = Environment>(
|
|
|
1470
1473
|
})
|
|
1471
1474
|
}
|
|
1472
1475
|
|
|
1476
|
+
const scopes = Scope.expandAliases(apiKey_resolved.scopes)
|
|
1477
|
+
const apiKey =
|
|
1478
|
+
scopes === apiKey_resolved.scopes ? apiKey_resolved : { ...apiKey_resolved, scopes }
|
|
1479
|
+
|
|
1473
1480
|
// Sandbox keys are testnet-only. A sandbox key that explicitly targets
|
|
1474
1481
|
// mainnet (`?chainId`) is rejected with a clear message rather than
|
|
1475
1482
|
// steered or downgraded to anonymous, so the caller learns their key does
|
|
@@ -1847,7 +1854,8 @@ function getRequestId(c: hono_Context) {
|
|
|
1847
1854
|
return typeof variables['requestId'] === 'string' ? variables['requestId'] : undefined
|
|
1848
1855
|
}
|
|
1849
1856
|
|
|
1850
|
-
|
|
1857
|
+
/** True when the request carries an `Authorization: Payment` MPP credential. */
|
|
1858
|
+
export function hasPaymentCredential(c: hono_Context) {
|
|
1851
1859
|
const authorization = c.req.header('authorization')
|
|
1852
1860
|
if (!authorization) return false
|
|
1853
1861
|
return !!Credential.extractPaymentScheme(authorization)
|
|
@@ -21,8 +21,8 @@ describe('deriveZoneId', () => {
|
|
|
21
21
|
test('derives IDs from mainnet and testnet Zone chain schemes', () => {
|
|
22
22
|
expect([
|
|
23
23
|
EarnVaults.deriveZoneId(421_700_006),
|
|
24
|
-
EarnVaults.deriveZoneId(
|
|
25
|
-
]).toStrictEqual([6,
|
|
24
|
+
EarnVaults.deriveZoneId(1_424_310_003),
|
|
25
|
+
]).toStrictEqual([6, 3])
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
test('rejects a source chain ID', () => {
|
|
@@ -245,7 +245,7 @@ describe('resolveZoneRoutes', () => {
|
|
|
245
245
|
zones: [TestEarn.zone],
|
|
246
246
|
}),
|
|
247
247
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
248
|
-
`[EarnVaults.InvalidRegistryError: Zone
|
|
248
|
+
`[EarnVaults.InvalidRegistryError: Zone 1424310003 is configured more than once.]`,
|
|
249
249
|
)
|
|
250
250
|
await expect(
|
|
251
251
|
EarnVaults.resolveZoneRoutes({
|
|
@@ -157,7 +157,7 @@ export namespace schema {
|
|
|
157
157
|
),
|
|
158
158
|
vaultAddress: Schema.Address.check(
|
|
159
159
|
z.describe('Earn vault contract address.'),
|
|
160
|
-
z.meta({ examples: ['
|
|
160
|
+
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
161
161
|
),
|
|
162
162
|
})
|
|
163
163
|
.check(z.describe('Onchain identity of an Earn vault.'))
|
|
@@ -167,7 +167,7 @@ export namespace schema {
|
|
|
167
167
|
.strictObject({
|
|
168
168
|
chainId: Schema.ChainId.check(
|
|
169
169
|
z.describe('Private Zone chain id.'),
|
|
170
|
-
z.meta({ examples: [
|
|
170
|
+
z.meta({ examples: [421700001] }),
|
|
171
171
|
),
|
|
172
172
|
deploymentBlock: z
|
|
173
173
|
.number()
|
|
@@ -175,11 +175,11 @@ export namespace schema {
|
|
|
175
175
|
z.int(),
|
|
176
176
|
z.nonnegative(),
|
|
177
177
|
z.describe('Parent-chain block that deployed the Earn router.'),
|
|
178
|
-
z.meta({ examples: [
|
|
178
|
+
z.meta({ examples: [35816964] }),
|
|
179
179
|
),
|
|
180
180
|
earnRouter: Schema.Address.check(
|
|
181
181
|
z.describe('Parent-chain router for this Zone and Earn vault.'),
|
|
182
|
-
z.meta({ examples: ['
|
|
182
|
+
z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
|
|
183
183
|
),
|
|
184
184
|
})
|
|
185
185
|
.check(z.describe('Curated Earn route through one private Zone.'))
|
|
@@ -239,7 +239,7 @@ export namespace schema {
|
|
|
239
239
|
state,
|
|
240
240
|
vaultAddress: Schema.Address.check(
|
|
241
241
|
z.describe('Earn vault contract address.'),
|
|
242
|
-
z.meta({ examples: ['
|
|
242
|
+
z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
|
|
243
243
|
),
|
|
244
244
|
})
|
|
245
245
|
.check(z.describe('Live state resolved from an Earn vault.'))
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as http from 'node:http'
|
|
2
|
+
|
|
3
|
+
import * as Fetch from './Fetch.js'
|
|
4
|
+
|
|
5
|
+
describe('withTimeout', () => {
|
|
6
|
+
test('aborts a fetch after the configured duration', async () => {
|
|
7
|
+
const server = http.createServer(() => {})
|
|
8
|
+
const url = await listen(server)
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const fetch = Fetch.withTimeout(globalThis.fetch, { timeout: 10 })
|
|
12
|
+
await expect(fetch(url)).rejects.toMatchObject({ name: 'TimeoutError' })
|
|
13
|
+
} finally {
|
|
14
|
+
server.closeAllConnections()
|
|
15
|
+
await close(server)
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
describe('resolveSignal', () => {
|
|
21
|
+
test('preserves caller and Request signals', () => {
|
|
22
|
+
const signal = AbortSignal.timeout(1_000)
|
|
23
|
+
const request = new Request('https://api.tempo.xyz', { signal })
|
|
24
|
+
|
|
25
|
+
expect(Fetch.resolveSignal('https://api.tempo.xyz', { init: { signal }, timeout: 10 })).toBe(
|
|
26
|
+
signal,
|
|
27
|
+
)
|
|
28
|
+
expect(Fetch.resolveSignal(request, { timeout: 10 })).toBe(request.signal)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function close(server: http.Server): Promise<void> {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
server.close((error) => (error ? reject(error) : resolve()))
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function listen(server: http.Server): Promise<string> {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
server.listen(0, '127.0.0.1', () => {
|
|
41
|
+
const address = server.address()
|
|
42
|
+
if (!address || typeof address === 'string') throw new Error('Expected a TCP server address.')
|
|
43
|
+
resolve(`http://127.0.0.1:${address.port}`)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as Timeout from './Timeout.js'
|
|
2
|
+
|
|
3
|
+
/** Installs the default outbound fetch timeout once for this runtime. */
|
|
4
|
+
export function install(): void {
|
|
5
|
+
if (isInstalled(globalThis.fetch)) return
|
|
6
|
+
|
|
7
|
+
const fetch = withTimeout(globalThis.fetch.bind(globalThis), { timeout: Timeout.duration })
|
|
8
|
+
Object.defineProperty(fetch, timeoutMarker, { value: true })
|
|
9
|
+
globalThis.fetch = fetch
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Adds a default maximum duration to fetch calls that do not carry a signal. */
|
|
13
|
+
export function withTimeout(
|
|
14
|
+
fetch: typeof globalThis.fetch,
|
|
15
|
+
options: withTimeout.Options,
|
|
16
|
+
): typeof globalThis.fetch {
|
|
17
|
+
return ((input, init) => {
|
|
18
|
+
const signal = resolveSignal(input, { init, timeout: options.timeout })
|
|
19
|
+
return fetch(input, { ...init, signal })
|
|
20
|
+
}) as typeof globalThis.fetch
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Resolves a caller signal or creates the default fetch deadline signal. */
|
|
24
|
+
export function resolveSignal(
|
|
25
|
+
input: Parameters<typeof globalThis.fetch>[0],
|
|
26
|
+
options: resolveSignal.Options,
|
|
27
|
+
): AbortSignal {
|
|
28
|
+
return (
|
|
29
|
+
options.init?.signal ??
|
|
30
|
+
(input instanceof Request ? input.signal : Timeout.signal({ timeout: options.timeout }))
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export declare namespace resolveSignal {
|
|
35
|
+
/** Options for {@link resolveSignal}. */
|
|
36
|
+
type Options = {
|
|
37
|
+
/** Optional fetch initialization carrying a caller signal. */
|
|
38
|
+
init?: Parameters<typeof globalThis.fetch>[1]
|
|
39
|
+
/** Default maximum duration in milliseconds. */
|
|
40
|
+
timeout: number
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare namespace withTimeout {
|
|
45
|
+
/** Options for {@link withTimeout}. */
|
|
46
|
+
type Options = {
|
|
47
|
+
/** Maximum fetch duration in milliseconds. */
|
|
48
|
+
timeout: number
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const timeoutMarker = Symbol.for('tempo.api.fetch.timeout')
|
|
53
|
+
|
|
54
|
+
function isInstalled(fetch: typeof globalThis.fetch): boolean {
|
|
55
|
+
return timeoutMarker in fetch
|
|
56
|
+
}
|
|
@@ -29,6 +29,8 @@ test('bounds sponsorship diagnostics', () => {
|
|
|
29
29
|
'fee_token_unsupported',
|
|
30
30
|
'internal_error',
|
|
31
31
|
'production_api_key_required',
|
|
32
|
+
'project_id_invalid',
|
|
33
|
+
'project_id_required',
|
|
32
34
|
'spend_limit_exceeded',
|
|
33
35
|
'tx_fee_limit_exceeded',
|
|
34
36
|
] as const satisfies readonly Log.SponsorshipReason[]
|
package/src/internal/Log.test.ts
CHANGED
|
@@ -457,6 +457,27 @@ describe('middleware', () => {
|
|
|
457
457
|
`)
|
|
458
458
|
})
|
|
459
459
|
|
|
460
|
+
test('preserves the request error and unfinished stages', async () => {
|
|
461
|
+
const entries: Log.Entry[] = []
|
|
462
|
+
const causes: Error[] = []
|
|
463
|
+
const api = app({
|
|
464
|
+
emit: (entry, cause) => {
|
|
465
|
+
entries.push(entry)
|
|
466
|
+
if (cause) causes.push(cause)
|
|
467
|
+
},
|
|
468
|
+
})
|
|
469
|
+
const cause = new Error('Memoized cache-miss flight timed out after 15000ms.')
|
|
470
|
+
api.get('/activities', (c) => {
|
|
471
|
+
void Timing.time(c, 'transaction_activity_mpp', () => new Promise(() => {}))
|
|
472
|
+
return Response.upstream(c, cause)
|
|
473
|
+
})
|
|
474
|
+
|
|
475
|
+
await api.request('/activities')
|
|
476
|
+
|
|
477
|
+
expect(causes[0]).toBe(cause)
|
|
478
|
+
expect(entries[0]?.pendingTimings?.['transaction_activity_mpp']).toBeGreaterThanOrEqual(0)
|
|
479
|
+
})
|
|
480
|
+
|
|
460
481
|
test('includes bounded funding provider attempts', async () => {
|
|
461
482
|
const entries: Log.Entry[] = []
|
|
462
483
|
const api = app({ emit: (entry) => void entries.push(entry) })
|
package/src/internal/Log.ts
CHANGED
|
@@ -104,6 +104,8 @@ export type SponsorshipReason =
|
|
|
104
104
|
| 'fee_token_unsupported'
|
|
105
105
|
| 'internal_error'
|
|
106
106
|
| 'production_api_key_required'
|
|
107
|
+
| 'project_id_invalid'
|
|
108
|
+
| 'project_id_required'
|
|
107
109
|
| 'spend_limit_exceeded'
|
|
108
110
|
| 'tx_fee_limit_exceeded'
|
|
109
111
|
|
|
@@ -151,6 +153,8 @@ export type Entry = {
|
|
|
151
153
|
path: string
|
|
152
154
|
/** MPP payment reason when the request was paid per call. */
|
|
153
155
|
payment?: Auth.Payment['reason'] | undefined
|
|
156
|
+
/** Operations still running when the response completed, with elapsed milliseconds. */
|
|
157
|
+
pendingTimings?: Record<string, number> | undefined
|
|
154
158
|
/** Bounded outcome for an MPP relay operation. */
|
|
155
159
|
mpp?: {
|
|
156
160
|
/** Resolved Tempo chain selected by the credential. */
|
|
@@ -228,7 +232,7 @@ export type Entry = {
|
|
|
228
232
|
}
|
|
229
233
|
|
|
230
234
|
/** Sink receiving one {@link Entry} per request. */
|
|
231
|
-
export type Emit = (entry: Entry) => Promise<void> | void
|
|
235
|
+
export type Emit = (entry: Entry, cause?: Error) => Promise<void> | void
|
|
232
236
|
|
|
233
237
|
/**
|
|
234
238
|
* Emits one canonical structured log entry per request, after the response is
|
|
@@ -258,7 +262,8 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
258
262
|
// Hono cannot resolve variable types through the generic `environment`,
|
|
259
263
|
// so shared-variable reads are cast from the environment contract above
|
|
260
264
|
// (the same pattern EdgeCache uses for its cross-layer reads).
|
|
261
|
-
const
|
|
265
|
+
const cause = c.error
|
|
266
|
+
const error = cause as (Error & ErrorMetadata) | undefined
|
|
262
267
|
const principal = c.get('principal' as never) as Auth.Principal | undefined
|
|
263
268
|
const errorCaptured = c.get('errorCaptured' as never) as boolean | undefined
|
|
264
269
|
const chainId = c.get('chainId' as never) as number | undefined
|
|
@@ -279,7 +284,6 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
279
284
|
error?.providerFailures ?? (c.get('providerFailures' as never) as Entry['providerFailures'])
|
|
280
285
|
const rpc = c.get('rpcResponse' as never) as Entry['rpc']
|
|
281
286
|
const sponsorship = c.get('sponsorship' as never) as Entry['sponsorship']
|
|
282
|
-
|
|
283
287
|
// The `request` total metric duplicates `duration` (measured here, one
|
|
284
288
|
// layer further out), so only operation timings are kept.
|
|
285
289
|
const metrics = (c.get('serverTiming' as never) as Timing.Metric[] | undefined)?.filter(
|
|
@@ -295,6 +299,17 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
295
299
|
}, new Map<string, number>()),
|
|
296
300
|
)
|
|
297
301
|
: undefined
|
|
302
|
+
const activeTimings = c.get('activeTimings' as never) as Timing.Active[] | undefined
|
|
303
|
+
const pendingTimings = activeTimings?.length
|
|
304
|
+
? Object.fromEntries(
|
|
305
|
+
activeTimings.reduce((result, timing) => {
|
|
306
|
+
const duration = round(performance.now() - timing.start)
|
|
307
|
+
const existing = result.get(timing.name)
|
|
308
|
+
if (existing === undefined || duration > existing) result.set(timing.name, duration)
|
|
309
|
+
return result
|
|
310
|
+
}, new Map<string, number>()),
|
|
311
|
+
)
|
|
312
|
+
: undefined
|
|
298
313
|
|
|
299
314
|
const rateLimit = (() => {
|
|
300
315
|
const limit = c.res.headers.get('RateLimit-Limit')
|
|
@@ -310,7 +325,7 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
310
325
|
}
|
|
311
326
|
})()
|
|
312
327
|
|
|
313
|
-
const
|
|
328
|
+
const entry = {
|
|
314
329
|
...(c.get('edgeCacheStatus' as never) === 'hit' ? { cache: 'hit' as const } : {}),
|
|
315
330
|
...(chainId === undefined ? {} : { chainId }),
|
|
316
331
|
duration: round(duration),
|
|
@@ -333,6 +348,7 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
333
348
|
...(mpp === undefined ? {} : { mpp }),
|
|
334
349
|
path: url.pathname,
|
|
335
350
|
...(principal?.payment === undefined ? {} : { payment: principal.payment.reason }),
|
|
351
|
+
...(pendingTimings === undefined ? {} : { pendingTimings }),
|
|
336
352
|
...(principal === undefined
|
|
337
353
|
? {}
|
|
338
354
|
: {
|
|
@@ -360,7 +376,8 @@ export function middleware<environment extends Environment = Environment>(
|
|
|
360
376
|
...(sponsorship === undefined ? {} : { sponsorship }),
|
|
361
377
|
status,
|
|
362
378
|
...(timings === undefined ? {} : { timings }),
|
|
363
|
-
}
|
|
379
|
+
} satisfies Entry
|
|
380
|
+
const result = fn(entry, cause)
|
|
364
381
|
|
|
365
382
|
if (result instanceof Promise) {
|
|
366
383
|
const promise = result.catch((error) => console.error('request log sink failed', error))
|
package/src/internal/OpenApi.ts
CHANGED
|
@@ -148,6 +148,7 @@ export const errorCodes = {
|
|
|
148
148
|
500: ['internal_error'],
|
|
149
149
|
501: ['billing_unconfigured'],
|
|
150
150
|
502: ['upstream_error'],
|
|
151
|
+
504: ['request_timeout'],
|
|
151
152
|
} as const satisfies Record<number, readonly [string, ...string[]]>
|
|
152
153
|
|
|
153
154
|
/**
|
|
@@ -220,6 +221,7 @@ const standardErrorNames = {
|
|
|
220
221
|
500: 'InternalError',
|
|
221
222
|
501: 'NotImplementedError',
|
|
222
223
|
502: 'UpstreamError',
|
|
224
|
+
504: 'RequestTimeoutError',
|
|
223
225
|
} as const satisfies Record<keyof typeof errorCodes, string>
|
|
224
226
|
|
|
225
227
|
const reservedErrorNames = new Set<string>(Object.values(standardErrorNames))
|
|
@@ -300,12 +302,12 @@ export const paymentChallenge = {
|
|
|
300
302
|
headers: { 'WWW-Authenticate': headerRef('WwwAuthenticate') },
|
|
301
303
|
} as const
|
|
302
304
|
|
|
303
|
-
type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited'
|
|
305
|
+
type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited' | 'RequestTimeout'
|
|
304
306
|
|
|
305
307
|
/**
|
|
306
308
|
* Reusable responses registered under `components.responses` (see `App.create`)
|
|
307
|
-
* and `$ref`-erenced from operations, so the uniform `402`/`429`/`500`
|
|
308
|
-
* are defined once instead of inlined on every operation.
|
|
309
|
+
* and `$ref`-erenced from operations, so the uniform `402`/`429`/`500`/`504`
|
|
310
|
+
* responses are defined once instead of inlined on every operation.
|
|
309
311
|
*/
|
|
310
312
|
export function responseComponents(): ResponsesWithResolver {
|
|
311
313
|
return {
|
|
@@ -320,6 +322,11 @@ export function responseComponents(): ResponsesWithResolver {
|
|
|
320
322
|
'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
|
|
321
323
|
headers: { ...rateLimitHeaders },
|
|
322
324
|
},
|
|
325
|
+
RequestTimeout: {
|
|
326
|
+
content: errorContent(504, errorCodes[504], 'Request timed out'),
|
|
327
|
+
description:
|
|
328
|
+
'Request timed out. The request did not complete within the 60-second deadline; retry it.',
|
|
329
|
+
},
|
|
323
330
|
}
|
|
324
331
|
}
|
|
325
332
|
|
|
@@ -344,6 +351,7 @@ export function standardError(
|
|
|
344
351
|
): ResponsesWithResolver[string] {
|
|
345
352
|
if (status === 429) return responseRef('RateLimited')
|
|
346
353
|
if (status === 500) return responseRef('InternalError')
|
|
354
|
+
if (status === 504) return responseRef('RequestTimeout')
|
|
347
355
|
return { content: errorContent(status, mergeErrorCodes(status, codes), description), description }
|
|
348
356
|
}
|
|
349
357
|
|
|
@@ -352,7 +360,8 @@ export function standardError(
|
|
|
352
360
|
* pre-filled, plus the success response (with rate-limit headers):
|
|
353
361
|
*
|
|
354
362
|
* - `400` invalid request, `401` missing/invalid key, `403` forbidden, `429`
|
|
355
|
-
* rate limited, `500` internal error,
|
|
363
|
+
* rate limited, `500` internal error, `502` upstream failure, and `504`
|
|
364
|
+
* request timeout on every operation;
|
|
356
365
|
* - `404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
|
|
357
366
|
*
|
|
358
367
|
* `error.code` is enumerated per status from {@link errorCodes}. Operation-level
|
|
@@ -404,6 +413,7 @@ export function responses<schema extends z.ZodMiniType>(
|
|
|
404
413
|
500: responseRef('InternalError'),
|
|
405
414
|
...(errors?.[501] && { 501: error(501, 'Not implemented.') }),
|
|
406
415
|
502: error(502, 'Upstream data failure.'),
|
|
416
|
+
504: responseRef('RequestTimeout'),
|
|
407
417
|
}
|
|
408
418
|
}
|
|
409
419
|
|
package/src/internal/Response.ts
CHANGED
|
@@ -142,7 +142,7 @@ export declare namespace error {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/** HTTP status code accepted by the public error helper. */
|
|
145
|
-
type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503
|
|
145
|
+
type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503 | 504
|
|
146
146
|
|
|
147
147
|
/** Options for creating a JSON error response. */
|
|
148
148
|
type Options<status extends Status = Status, code extends string = string> = {
|
|
@@ -6,6 +6,8 @@ describe('ChainId', () => {
|
|
|
6
6
|
test('resolves aliases to their chain id', () => {
|
|
7
7
|
expect(Schema.ChainId.parse('mainnet')).toMatchInlineSnapshot(`4217`)
|
|
8
8
|
expect(Schema.ChainId.parse('testnet')).toMatchInlineSnapshot(`42431`)
|
|
9
|
+
expect(Schema.ChainId.parse('1424310001')).toMatchInlineSnapshot(`1424310003`)
|
|
10
|
+
expect(Schema.ChainId.parse(1_424_310_001)).toMatchInlineSnapshot(`1424310003`)
|
|
9
11
|
})
|
|
10
12
|
|
|
11
13
|
test('accepts numeric chain ids as numbers or strings', () => {
|
package/src/internal/Schema.ts
CHANGED
|
@@ -90,12 +90,19 @@ export function tokenAddress(example: core_Hex.Hex) {
|
|
|
90
90
|
)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
/** Maps
|
|
93
|
+
/** Maps caller-facing chain aliases to their current Tempo chain id. */
|
|
94
94
|
export const chainIdAlias = {
|
|
95
|
+
// TODO: Remove this alias after clients migrate to chain 1424310003.
|
|
96
|
+
1_424_310_001: 1_424_310_003,
|
|
95
97
|
mainnet: 4217,
|
|
96
98
|
testnet: 42431,
|
|
97
99
|
} as const
|
|
98
100
|
|
|
101
|
+
/** Resolves a numeric chain id through the caller-facing alias map. */
|
|
102
|
+
export function resolveChainId(chainId: number): number {
|
|
103
|
+
return chainIdAlias[chainId as keyof typeof chainIdAlias] ?? chainId
|
|
104
|
+
}
|
|
105
|
+
|
|
99
106
|
/**
|
|
100
107
|
* Tempo chain id. Accepts a chain alias (`mainnet`/`testnet`) or any positive
|
|
101
108
|
* integer chain id (a number or numeric string), normalizing all forms to a
|
|
@@ -110,7 +117,10 @@ export const ChainId = z
|
|
|
110
117
|
z.enum(['mainnet', 'testnet']),
|
|
111
118
|
z.transform((alias) => chainIdAlias[alias]),
|
|
112
119
|
),
|
|
113
|
-
z.
|
|
120
|
+
z.pipe(
|
|
121
|
+
z.coerce.number(),
|
|
122
|
+
z.transform((chainId) => resolveChainId(chainId)),
|
|
123
|
+
),
|
|
114
124
|
]),
|
|
115
125
|
z.number().check(z.int(), z.positive()),
|
|
116
126
|
)
|