tapimo 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ApiKeys.d.ts +24 -7
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +17 -5
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +12104 -7861
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +191 -128
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +10 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +17 -4
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +19 -8
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +25 -9
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +1 -1
- package/dist/admin/App.d.ts +601 -20
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +12 -2
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +94 -11
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +141 -32
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +1069 -0
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -0
- package/dist/admin/apps/earn-vaults.js +409 -0
- package/dist/admin/apps/earn-vaults.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +166 -166
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +151 -95
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts +2 -0
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +18 -2
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +22 -1
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +59 -39
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/Zones.d.ts +8335 -0
- package/dist/apps/Zones.d.ts.map +1 -0
- package/dist/apps/Zones.js +38 -0
- package/dist/apps/Zones.js.map +1 -0
- package/dist/apps/data/App.d.ts +14377 -10165
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +91 -19
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +1 -1
- package/dist/apps/data/FxOracle.d.ts.map +1 -1
- package/dist/apps/data/index.d.ts +0 -1
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +0 -1
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +32 -32
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +130 -65
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +312 -312
- package/dist/apps/data/routes/balances.d.ts +18 -18
- package/dist/apps/data/routes/balances.js +5 -5
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +176 -176
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
- package/dist/apps/data/routes/coingecko.js +62 -35
- package/dist/apps/data/routes/coingecko.js.map +1 -1
- package/dist/apps/data/routes/earn.d.ts +2144 -0
- package/dist/apps/data/routes/earn.d.ts.map +1 -0
- package/dist/apps/data/routes/earn.js +947 -0
- package/dist/apps/data/routes/earn.js.map +1 -0
- package/dist/apps/data/routes/exchanges.d.ts +1231 -324
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +656 -193
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +59 -8
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/funding.d.ts +4092 -387
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +1403 -256
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +5 -5
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +19 -2
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +265 -265
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +11 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts +5 -5
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +211 -22
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +36 -36
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +49 -9
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +116 -88
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +198 -91
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +55 -55
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +78 -39
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +78 -29
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +165 -67
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +10 -10
- package/dist/apps/data/routes/valuation.js +2 -2
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +34 -9
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +5 -3
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +175 -65
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +281 -0
- package/dist/apps/data/routes/zones.d.ts.map +1 -0
- package/dist/apps/data/routes/zones.js +252 -0
- package/dist/apps/data/routes/zones.js.map +1 -0
- package/dist/apps/docs/reference.js +6 -5
- package/dist/apps/docs/reference.js.map +1 -1
- package/dist/apps/index.d.ts +2 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +2 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +670 -670
- package/dist/apps/management/Billing.d.ts +8 -0
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +12 -0
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/Error.d.ts +12 -0
- package/dist/apps/management/Error.d.ts.map +1 -0
- package/dist/apps/management/Error.js +10 -0
- package/dist/apps/management/Error.js.map +1 -0
- package/dist/apps/management/routes/api-keys.d.ts +5 -5
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +2 -8
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +119 -119
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/invitations.d.ts +62 -62
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +4 -10
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +30 -30
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +78 -78
- package/dist/apps/management/routes/orgs.d.ts +48 -48
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +2 -8
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +9 -9
- package/dist/apps/management/routes/scopes.js +2 -2
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +80 -80
- package/dist/apps/management/routes/verified-token-requests.d.ts +36 -36
- package/dist/apps/management/routes/webhooks.d.ts +50 -50
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +15 -3
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/App.d.ts +55 -56
- package/dist/apps/mpp/App.d.ts.map +1 -1
- package/dist/apps/mpp/App.js +192 -27
- package/dist/apps/mpp/App.js.map +1 -1
- package/dist/apps/mpp/Mpp.d.ts +0 -20
- package/dist/apps/mpp/Mpp.d.ts.map +1 -1
- package/dist/apps/mpp/Mpp.js +0 -24
- package/dist/apps/mpp/Mpp.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +40 -0
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Adapter.js +66 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -0
- package/dist/apps/mpp/internal/Error.d.ts +4 -0
- package/dist/apps/mpp/internal/Error.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Error.js +41 -0
- package/dist/apps/mpp/internal/Error.js.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts +33 -0
- package/dist/apps/mpp/internal/Idempotency.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Idempotency.js +28 -0
- package/dist/apps/mpp/internal/Idempotency.js.map +1 -0
- package/dist/apps/mpp/internal/Policy.d.ts +46 -0
- package/dist/apps/mpp/internal/Policy.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Policy.js +57 -0
- package/dist/apps/mpp/internal/Policy.js.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts +27 -0
- package/dist/apps/mpp/internal/ScreenManager.d.ts.map +1 -0
- package/dist/apps/mpp/internal/ScreenManager.js +18 -0
- package/dist/apps/mpp/internal/ScreenManager.js.map +1 -0
- package/dist/apps/mpp/internal/Screening.d.ts +35 -0
- package/dist/apps/mpp/internal/Screening.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Screening.js +20 -0
- package/dist/apps/mpp/internal/Screening.js.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts +36 -0
- package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Sponsorship.js +103 -0
- package/dist/apps/mpp/internal/Sponsorship.js.map +1 -0
- package/dist/apps/mpp/internal/Utils.d.ts +7 -0
- package/dist/apps/mpp/internal/Utils.d.ts.map +1 -0
- package/dist/apps/mpp/internal/Utils.js +24 -0
- package/dist/apps/mpp/internal/Utils.js.map +1 -0
- package/dist/apps/relay/App.js +184 -24
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/apps/relay/Sponsorships.d.ts +4 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
- package/dist/apps/relay/Sponsorships.js +16 -7
- package/dist/apps/relay/Sponsorships.js.map +1 -1
- package/dist/db/Db.d.ts +20 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +342 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +921 -1
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +269 -1
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +68 -0
- package/dist/db/tables/earnVaults.d.ts.map +1 -0
- package/dist/db/tables/earnVaults.js +72 -0
- package/dist/db/tables/earnVaults.js.map +1 -0
- package/dist/db/tables/fundingCatalog.d.ts +56 -0
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -0
- package/dist/db/tables/fundingCatalog.js +85 -0
- package/dist/db/tables/fundingCatalog.js.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts +159 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -0
- package/dist/db/tables/fundingDepositAddresses.js +206 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -0
- package/dist/db/tables/fundingDeposits.d.ts +115 -0
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -0
- package/dist/db/tables/fundingDeposits.js +100 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -0
- package/dist/db/tables/fundingIdempotency.d.ts +91 -0
- package/dist/db/tables/fundingIdempotency.d.ts.map +1 -0
- package/dist/db/tables/fundingIdempotency.js +103 -0
- package/dist/db/tables/fundingIdempotency.js.map +1 -0
- package/dist/db/tables/fundingTransferEvents.d.ts +12 -0
- package/dist/db/tables/fundingTransferEvents.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferEvents.js +18 -0
- package/dist/db/tables/fundingTransferEvents.js.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts +15 -0
- package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -0
- package/dist/db/tables/fundingTransferTransactions.js +27 -0
- package/dist/db/tables/fundingTransferTransactions.js.map +1 -0
- package/dist/db/tables/fundingTransfers.d.ts +82 -0
- package/dist/db/tables/fundingTransfers.d.ts.map +1 -0
- package/dist/db/tables/fundingTransfers.js +89 -0
- package/dist/db/tables/fundingTransfers.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +8 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +35 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +8 -0
- package/dist/db/tables/projects.d.ts.map +1 -1
- package/dist/db/tables/projects.js +16 -0
- package/dist/db/tables/projects.js.map +1 -1
- package/dist/db/tables/requestUsage.d.ts +13 -0
- package/dist/db/tables/requestUsage.d.ts.map +1 -1
- package/dist/db/tables/requestUsage.js +16 -0
- package/dist/db/tables/requestUsage.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +4 -2
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +14 -4
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/users.d.ts +8 -0
- package/dist/db/tables/users.d.ts.map +1 -1
- package/dist/db/tables/users.js +16 -0
- package/dist/db/tables/users.js.map +1 -1
- package/dist/db/tables/verifiedTokens.d.ts +14 -7
- package/dist/db/tables/verifiedTokens.d.ts.map +1 -1
- package/dist/db/tables/verifiedTokens.js +9 -7
- package/dist/db/tables/verifiedTokens.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +31 -1
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +24 -3
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/relay.js +108 -108
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +26 -0
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +35 -2
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +16 -10
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/Cursor.js +1 -1
- package/dist/internal/Cursor.js.map +1 -1
- package/dist/internal/EarnRates.d.ts +89 -0
- package/dist/internal/EarnRates.d.ts.map +1 -0
- package/dist/internal/EarnRates.js +266 -0
- package/dist/internal/EarnRates.js.map +1 -0
- package/dist/internal/EarnVaults.d.ts +171 -0
- package/dist/internal/EarnVaults.d.ts.map +1 -0
- package/dist/internal/EarnVaults.js +547 -0
- package/dist/internal/EarnVaults.js.map +1 -0
- package/dist/internal/EdgeCache.d.ts +9 -2
- package/dist/internal/EdgeCache.d.ts.map +1 -1
- package/dist/internal/EdgeCache.js +36 -9
- package/dist/internal/EdgeCache.js.map +1 -1
- package/dist/internal/Id.d.ts +11 -0
- package/dist/internal/Id.d.ts.map +1 -1
- package/dist/internal/Id.js +13 -0
- package/dist/internal/Id.js.map +1 -1
- package/dist/internal/Idempotency.d.ts +83 -0
- package/dist/internal/Idempotency.d.ts.map +1 -0
- package/dist/internal/Idempotency.js +113 -0
- package/dist/internal/Idempotency.js.map +1 -0
- package/dist/internal/Log.d.ts +64 -9
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +29 -7
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +47 -1
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +1 -1
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Provider.d.ts +14 -0
- package/dist/internal/Provider.d.ts.map +1 -0
- package/dist/internal/Provider.js +5 -0
- package/dist/internal/Provider.js.map +1 -0
- package/dist/internal/Schema.d.ts +8 -3
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +24 -13
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +6 -0
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +35 -0
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +43 -24
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +79 -11
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Viem.d.ts +82 -65
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +83 -12
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +34 -28
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +9 -0
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +15 -10
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/exchange/Provider.d.ts +219 -0
- package/dist/internal/exchange/Provider.d.ts.map +1 -0
- package/dist/internal/exchange/Provider.js +117 -0
- package/dist/internal/exchange/Provider.js.map +1 -0
- package/dist/internal/exchange/index.d.ts +2 -0
- package/dist/internal/exchange/index.d.ts.map +1 -0
- package/dist/internal/exchange/index.js +2 -0
- package/dist/internal/exchange/index.js.map +1 -0
- package/dist/internal/exchange/providers/uniswap.d.ts +57 -0
- package/dist/internal/exchange/providers/uniswap.d.ts.map +1 -0
- package/dist/internal/exchange/providers/uniswap.js +553 -0
- package/dist/internal/exchange/providers/uniswap.js.map +1 -0
- package/dist/internal/funding/Action.d.ts +55 -0
- package/dist/internal/funding/Action.d.ts.map +1 -0
- package/dist/internal/funding/Action.js +74 -0
- package/dist/internal/funding/Action.js.map +1 -0
- package/dist/internal/funding/Catalog.d.ts +107 -0
- package/dist/internal/funding/Catalog.d.ts.map +1 -0
- package/dist/internal/funding/Catalog.js +270 -0
- package/dist/internal/funding/Catalog.js.map +1 -0
- package/dist/internal/funding/Chain.d.ts +76 -0
- package/dist/internal/funding/Chain.d.ts.map +1 -0
- package/dist/internal/funding/Chain.js +38 -0
- package/dist/internal/funding/Chain.js.map +1 -0
- package/dist/internal/funding/Deposit.d.ts +366 -0
- package/dist/internal/funding/Deposit.d.ts.map +1 -0
- package/dist/internal/funding/Deposit.js +286 -0
- package/dist/internal/funding/Deposit.js.map +1 -0
- package/dist/internal/funding/DepositAddress.d.ts +345 -0
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -0
- package/dist/internal/funding/DepositAddress.js +189 -0
- package/dist/internal/funding/DepositAddress.js.map +1 -0
- package/dist/internal/funding/Evidence.d.ts +52 -0
- package/dist/internal/funding/Evidence.d.ts.map +1 -0
- package/dist/internal/funding/Evidence.js +314 -0
- package/dist/internal/funding/Evidence.js.map +1 -0
- package/dist/internal/funding/Provider.d.ts +1186 -0
- package/dist/internal/funding/Provider.d.ts.map +1 -0
- package/dist/internal/funding/Provider.js +1081 -0
- package/dist/internal/funding/Provider.js.map +1 -0
- package/dist/internal/funding/Reconciliation.d.ts +113 -0
- package/dist/internal/funding/Reconciliation.d.ts.map +1 -0
- package/dist/internal/funding/Reconciliation.js +676 -0
- package/dist/internal/funding/Reconciliation.js.map +1 -0
- package/dist/internal/funding/Route.d.ts +21 -0
- package/dist/internal/funding/Route.d.ts.map +1 -0
- package/dist/internal/funding/Route.js +5 -0
- package/dist/internal/funding/Route.js.map +1 -0
- package/dist/internal/funding/Subsidy.d.ts +113 -0
- package/dist/internal/funding/Subsidy.d.ts.map +1 -0
- package/dist/internal/funding/Subsidy.js +138 -0
- package/dist/internal/funding/Subsidy.js.map +1 -0
- package/dist/internal/funding/Token.d.ts +41 -0
- package/dist/internal/funding/Token.d.ts.map +1 -0
- package/dist/internal/funding/Token.js +22 -0
- package/dist/internal/funding/Token.js.map +1 -0
- package/dist/internal/funding/Transfer.d.ts +643 -0
- package/dist/internal/funding/Transfer.d.ts.map +1 -0
- package/dist/internal/funding/Transfer.js +332 -0
- package/dist/internal/funding/Transfer.js.map +1 -0
- package/dist/internal/funding/index.d.ts +13 -0
- package/dist/internal/funding/index.d.ts.map +1 -0
- package/dist/internal/funding/index.js +13 -0
- package/dist/internal/funding/index.js.map +1 -0
- package/dist/internal/funding/providers/across.d.ts +21 -0
- package/dist/internal/funding/providers/across.d.ts.map +1 -0
- package/dist/internal/funding/providers/across.js +117 -0
- package/dist/internal/funding/providers/across.js.map +1 -0
- package/dist/internal/funding/providers/relay.d.ts +46 -0
- package/dist/internal/funding/providers/relay.d.ts.map +1 -0
- package/dist/internal/funding/providers/relay.js +464 -0
- package/dist/internal/funding/providers/relay.js.map +1 -0
- package/dist/internal/funding/providers/rhino.d.ts +15 -0
- package/dist/internal/funding/providers/rhino.d.ts.map +1 -0
- package/dist/internal/funding/providers/rhino.js +116 -0
- package/dist/internal/funding/providers/rhino.js.map +1 -0
- package/dist/internal/funding/providers/squid.d.ts +19 -0
- package/dist/internal/funding/providers/squid.d.ts.map +1 -0
- package/dist/internal/funding/providers/squid.js +120 -0
- package/dist/internal/funding/providers/squid.js.map +1 -0
- package/dist/internal/funding/providers/symbiosis.d.ts +20 -0
- package/dist/internal/funding/providers/symbiosis.d.ts.map +1 -0
- package/dist/internal/funding/providers/symbiosis.js +176 -0
- package/dist/internal/funding/providers/symbiosis.js.map +1 -0
- package/dist/internal/index.d.ts +5 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +5 -1
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/webhookDestinations/url.js +61 -57
- package/dist/internal/webhookDestinations/url.js.map +1 -1
- package/dist/providers/index.d.ts +43 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +19 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +9 -4
- package/src/ApiKeys.test.ts +11 -7
- package/src/ApiKeys.ts +37 -9
- package/src/App.test.ts +85 -10
- package/src/App.ts +224 -137
- package/src/Assets.ts +29 -4
- package/src/Client.test-d.ts +650 -30
- package/src/Scope.test.ts +19 -0
- package/src/Scope.ts +28 -11
- package/src/Webhooks.test.ts +25 -0
- package/src/Webhooks.ts +1 -1
- package/src/admin/App.test.ts +9 -2
- package/src/admin/App.ts +32 -9
- package/src/admin/apps/api-keys.test.ts +167 -23
- package/src/admin/apps/api-keys.ts +166 -28
- package/src/admin/apps/earn-vaults.test.ts +338 -0
- package/src/admin/apps/earn-vaults.ts +572 -0
- package/src/admin/apps/scopes.test.ts +16 -1
- package/src/admin/ui/plugin.ts +2 -2
- package/src/admin/ui/src/components/EarnVaultForm.tsx +137 -0
- package/src/admin/ui/src/components/MobileProfile.tsx +2 -2
- package/src/admin/ui/src/components/Page.tsx +1 -1
- package/src/admin/ui/src/components/ThemeToggle.tsx +1 -1
- package/src/admin/ui/src/lib/api-keys.ts +37 -7
- package/src/admin/ui/src/lib/client.ts +1 -1
- package/src/admin/ui/src/lib/config.ts +1 -1
- package/src/admin/ui/src/lib/early-access.ts +8 -9
- package/src/admin/ui/src/lib/earn-vaults.ts +207 -0
- package/src/admin/ui/src/lib/format.ts +13 -0
- package/src/admin/ui/src/lib/organizations.test.ts +14 -4
- package/src/admin/ui/src/lib/organizations.ts +7 -1
- package/src/admin/ui/src/lib/response.ts +22 -0
- package/src/admin/ui/src/lib/scopes.test.ts +19 -11
- package/src/admin/ui/src/lib/scopes.ts +28 -7
- package/src/admin/ui/src/lib/verified-tokens.ts +10 -9
- package/src/admin/ui/src/routeTree.gen.ts +70 -7
- package/src/admin/ui/src/router.tsx +2 -2
- package/src/admin/ui/src/routes/__root.tsx +9 -8
- package/src/admin/ui/src/routes/api-keys.tsx +475 -64
- package/src/admin/ui/src/routes/early-access.tsx +5 -12
- package/src/admin/ui/src/routes/earn.vaults.tsx +348 -0
- package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +154 -0
- package/src/admin/ui/src/routes/earn.vaults_.new.tsx +190 -0
- package/src/admin/ui/src/routes/organizations.tsx +4 -7
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +56 -54
- package/src/admin/ui/src/routes/verified-tokens.tsx +4 -4
- package/src/admin/ui/vite.config.ts +4 -1
- package/src/admin/ui.generated.ts +189 -95
- package/src/analytics/Analytics.test.ts +69 -10
- package/src/analytics/Analytics.ts +20 -1
- package/src/analytics/tables/requestEvents.ts +79 -37
- package/src/apps/Zones.test.ts +33 -0
- package/src/apps/Zones.ts +40 -0
- package/src/apps/composition.test.ts +84 -1
- package/src/apps/data/App.test.ts +38 -9
- package/src/apps/data/App.ts +96 -33
- package/src/apps/data/FxOracle.ts +1 -1
- package/src/apps/data/index.ts +0 -1
- package/src/apps/data/routes/activities.test.ts +82 -6
- package/src/apps/data/routes/activities.ts +131 -71
- package/src/apps/data/routes/balances.test.ts +50 -37
- package/src/apps/data/routes/balances.ts +5 -5
- package/src/apps/data/routes/blocks.test.ts +2 -0
- package/src/apps/data/routes/coingecko.test.ts +22 -0
- package/src/apps/data/routes/coingecko.ts +84 -48
- package/src/apps/data/routes/earn.test.ts +1108 -0
- package/src/apps/data/routes/earn.ts +1391 -0
- package/src/apps/data/routes/exchanges.test.ts +82 -33
- package/src/apps/data/routes/exchanges.ts +842 -227
- package/src/apps/data/routes/fee-amm.test.ts +4 -6
- package/src/apps/data/routes/fee-amm.ts +69 -12
- package/src/apps/data/routes/funding.test.ts +2712 -221
- package/src/apps/data/routes/funding.ts +1604 -387
- package/src/apps/data/routes/indexer.test.ts +43 -34
- package/src/apps/data/routes/indexer.ts +19 -2
- package/src/apps/data/routes/receipts.test.ts +5 -3
- package/src/apps/data/routes/receipts.ts +13 -11
- package/src/apps/data/routes/rpc.test.ts +446 -28
- package/src/apps/data/routes/rpc.ts +243 -25
- package/src/apps/data/routes/tokenlist.test.ts +15 -0
- package/src/apps/data/routes/tokenlist.ts +88 -22
- package/src/apps/data/routes/tokens.ts +262 -86
- package/src/apps/data/routes/transactions.test.ts +2 -0
- package/src/apps/data/routes/transactions.ts +77 -42
- package/src/apps/data/routes/transfers.test.ts +166 -4
- package/src/apps/data/routes/transfers.ts +216 -78
- package/src/apps/data/routes/valuation.test.ts +62 -9
- package/src/apps/data/routes/valuation.ts +2 -2
- package/src/apps/data/routes/verified-tokens.test.ts +51 -0
- package/src/apps/data/routes/verified-tokens.ts +52 -15
- package/src/apps/data/routes/webhooks.test.ts +432 -33
- package/src/apps/data/routes/webhooks.ts +189 -79
- package/src/apps/data/routes/zones.test.ts +473 -0
- package/src/apps/data/routes/zones.ts +338 -0
- package/src/apps/docs/reference.ts +8 -6
- package/src/apps/index.ts +2 -1
- package/src/apps/management/Billing.test.ts +29 -0
- package/src/apps/management/Billing.ts +23 -0
- package/src/apps/management/Error.ts +12 -0
- package/src/apps/management/routes/api-keys.test.ts +5 -3
- package/src/apps/management/routes/api-keys.ts +2 -9
- package/src/apps/management/routes/invitations.ts +4 -11
- package/src/apps/management/routes/orgs.ts +2 -9
- package/src/apps/management/routes/scopes.test.ts +7 -2
- package/src/apps/management/routes/scopes.ts +2 -2
- package/src/apps/management/routes/webhooks.test.ts +6 -1
- package/src/apps/management/routes/webhooks.ts +15 -3
- package/src/apps/mpp/App.ts +276 -29
- package/src/apps/mpp/Mpp.test.ts +631 -26
- package/src/apps/mpp/Mpp.ts +0 -42
- package/src/apps/mpp/internal/Adapter.ts +108 -3
- package/src/apps/mpp/internal/Error.test.ts +33 -0
- package/src/apps/mpp/internal/Error.ts +44 -6
- package/src/apps/mpp/internal/Idempotency.test.ts +213 -0
- package/src/apps/mpp/internal/Idempotency.ts +59 -5
- package/src/apps/mpp/internal/Policy.test.ts +122 -0
- package/src/apps/mpp/internal/Policy.ts +98 -0
- package/src/apps/mpp/internal/ScreenManager.test.ts +68 -0
- package/src/apps/mpp/internal/ScreenManager.ts +41 -0
- package/src/apps/mpp/internal/Screening.ts +40 -3
- package/src/apps/mpp/internal/Sponsorship.ts +144 -0
- package/src/apps/mpp/internal/Utils.ts +30 -0
- package/src/apps/relay/App.test.ts +495 -64
- package/src/apps/relay/App.ts +234 -24
- package/src/apps/relay/Sponsorships.test.ts +51 -0
- package/src/apps/relay/Sponsorships.ts +19 -7
- package/src/db/Db.ts +439 -0
- package/src/db/Schema.ts +325 -2
- package/src/db/tables/earnVaults.test.ts +185 -0
- package/src/db/tables/earnVaults.ts +151 -0
- package/src/db/tables/fundingCatalog.test.ts +108 -0
- package/src/db/tables/fundingCatalog.ts +157 -0
- package/src/db/tables/fundingDepositAddresses.test.ts +580 -0
- package/src/db/tables/fundingDepositAddresses.ts +376 -0
- package/src/db/tables/fundingDeposits.test.ts +261 -0
- package/src/db/tables/fundingDeposits.ts +229 -0
- package/src/db/tables/fundingIdempotency.test.ts +182 -0
- package/src/db/tables/fundingIdempotency.ts +180 -0
- package/src/db/tables/fundingTransferEvents.ts +28 -0
- package/src/db/tables/fundingTransferTransactions.test.ts +69 -0
- package/src/db/tables/fundingTransferTransactions.ts +37 -0
- package/src/db/tables/fundingTransfers.test.ts +89 -0
- package/src/db/tables/fundingTransfers.ts +153 -0
- package/src/db/tables/organizations.test.ts +88 -0
- package/src/db/tables/organizations.ts +42 -1
- package/src/db/tables/projects.ts +16 -0
- package/src/db/tables/requestUsage.ts +23 -0
- package/src/db/tables/sponsoredTransactions.test.ts +52 -2
- package/src/db/tables/sponsoredTransactions.ts +18 -6
- package/src/db/tables/users.ts +16 -0
- package/src/db/tables/verifiedTokens.ts +19 -14
- package/src/db/tables/webhookSubscriptions.ts +58 -3
- package/src/handlers/relay.test.ts +2 -0
- package/src/handlers/relay.ts +95 -99
- package/src/internal/Auth.test.ts +48 -0
- package/src/internal/Auth.ts +61 -2
- package/src/internal/Cache.ts +13 -9
- package/src/internal/Cursor.test.ts +2 -2
- package/src/internal/Cursor.ts +1 -1
- package/src/internal/EarnRates.test.ts +125 -0
- package/src/internal/EarnRates.ts +409 -0
- package/src/internal/EarnVaults.test.ts +195 -0
- package/src/internal/EarnVaults.ts +876 -0
- package/src/internal/EdgeCache.test.ts +37 -5
- package/src/internal/EdgeCache.ts +39 -7
- package/src/internal/Id.ts +14 -0
- package/src/internal/Idempotency.test.ts +109 -0
- package/src/internal/Idempotency.ts +237 -0
- package/src/internal/Log.test-d.ts +41 -8
- package/src/internal/Log.test.ts +189 -8
- package/src/internal/Log.ts +124 -17
- package/src/internal/MetricSink.test.ts +244 -4
- package/src/internal/MetricSink.ts +51 -1
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Provider.test.ts +17 -0
- package/src/internal/Provider.ts +17 -0
- package/src/internal/Schema.test.ts +13 -0
- package/src/internal/Schema.ts +41 -24
- package/src/internal/Store.test.ts +25 -0
- package/src/internal/Store.ts +46 -0
- package/src/internal/Tidx.local.test.ts +78 -3
- package/src/internal/Tidx.test.ts +212 -18
- package/src/internal/Tidx.ts +112 -32
- package/src/internal/VerifiedTokens.test.ts +15 -0
- package/src/internal/Viem.test.ts +170 -17
- package/src/internal/Viem.ts +111 -28
- package/src/internal/WebhookDestination.ts +25 -23
- package/src/internal/Webhooks.test.ts +59 -0
- package/src/internal/Webhooks.ts +34 -10
- package/src/internal/exchange/Provider.test.ts +216 -0
- package/src/internal/exchange/Provider.ts +326 -0
- package/src/internal/exchange/index.test.ts +6 -0
- package/src/internal/exchange/index.ts +1 -0
- package/src/internal/exchange/providers/uniswap.test.ts +122 -0
- package/src/internal/exchange/providers/uniswap.ts +682 -0
- package/src/internal/funding/Action.test.ts +138 -0
- package/src/internal/funding/Action.ts +117 -0
- package/src/internal/funding/Catalog.test.ts +311 -0
- package/src/internal/funding/Catalog.ts +347 -0
- package/src/internal/funding/Chain.test.ts +79 -0
- package/src/internal/funding/Chain.ts +120 -0
- package/src/internal/funding/Deposit.test.ts +26 -0
- package/src/internal/funding/Deposit.ts +453 -0
- package/src/internal/funding/DepositAddress.test.ts +18 -0
- package/src/internal/funding/DepositAddress.ts +312 -0
- package/src/internal/funding/Evidence.test.ts +297 -0
- package/src/internal/funding/Evidence.ts +430 -0
- package/src/internal/funding/Provider.test.ts +1328 -0
- package/src/internal/funding/Provider.ts +1796 -0
- package/src/internal/funding/Reconciliation.local.test.ts +504 -0
- package/src/internal/funding/Reconciliation.test.ts +2020 -0
- package/src/internal/funding/Reconciliation.ts +930 -0
- package/src/internal/funding/Route.test.ts +66 -0
- package/src/internal/funding/Route.ts +29 -0
- package/src/internal/funding/Subsidy.local.test.ts +152 -0
- package/src/internal/funding/Subsidy.test.ts +75 -0
- package/src/internal/funding/Subsidy.ts +260 -0
- package/src/internal/funding/Token.test.ts +47 -0
- package/src/internal/funding/Token.ts +59 -0
- package/src/internal/funding/Transfer.test.ts +369 -0
- package/src/internal/funding/Transfer.ts +522 -0
- package/src/internal/funding/index.test.ts +20 -0
- package/src/internal/funding/index.ts +12 -0
- package/src/internal/funding/providers/across.ts +149 -0
- package/src/{apps/data/FundingQuoteProviders.test.ts → internal/funding/providers/index.test.ts} +178 -157
- package/src/internal/funding/providers/relay.test.ts +474 -0
- package/src/internal/funding/providers/relay.ts +559 -0
- package/src/internal/funding/providers/rhino.ts +139 -0
- package/src/internal/funding/providers/squid.ts +151 -0
- package/src/internal/funding/providers/symbiosis.ts +221 -0
- package/src/internal/index.test.ts +5 -1
- package/src/internal/index.ts +5 -1
- package/src/internal/webhookDestinations/url.ts +49 -45
- package/src/providers/index.test.ts +14 -0
- package/src/providers/index.ts +54 -0
- package/dist/apps/data/FundingQuoteProviders.d.ts +0 -174
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +0 -1
- package/dist/apps/data/FundingQuoteProviders.js +0 -775
- package/dist/apps/data/FundingQuoteProviders.js.map +0 -1
- package/dist/internal/FundingQuotes.d.ts +0 -864
- package/dist/internal/FundingQuotes.d.ts.map +0 -1
- package/dist/internal/FundingQuotes.js +0 -672
- package/dist/internal/FundingQuotes.js.map +0 -1
- package/src/apps/data/FundingQuoteProviders.ts +0 -1043
- package/src/internal/FundingQuotes.test.ts +0 -456
- package/src/internal/FundingQuotes.ts +0 -944
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { ZoneRpcAuthentication } from 'ox/tempo'
|
|
2
|
+
import { defineChain, type Chain } from 'viem'
|
|
3
|
+
import { tempoTestnet } from 'viem/tempo/chains'
|
|
4
|
+
|
|
1
5
|
import type * as Auth from './Auth.js'
|
|
2
6
|
import * as Viem from './Viem.js'
|
|
3
7
|
|
|
@@ -11,6 +15,21 @@ const apiKeyPrincipal: Auth.Principal = {
|
|
|
11
15
|
orgId: 'org_test',
|
|
12
16
|
type: 'api_key',
|
|
13
17
|
}
|
|
18
|
+
const zone = defineChain({
|
|
19
|
+
...tempoTestnet,
|
|
20
|
+
contracts: {
|
|
21
|
+
...tempoTestnet.contracts,
|
|
22
|
+
messenger: { address: '0x0000000000000000000000000000000000000001' },
|
|
23
|
+
portal: { address: '0x0000000000000000000000000000000000000002' },
|
|
24
|
+
},
|
|
25
|
+
id: 421_700_001,
|
|
26
|
+
name: 'Zone E',
|
|
27
|
+
rpcUrls: {
|
|
28
|
+
default: { http: ['https://zone.rpc.test'] },
|
|
29
|
+
internal: { http: ['https://internal.zone.rpc.test'] },
|
|
30
|
+
},
|
|
31
|
+
sourceId: tempoTestnet.id,
|
|
32
|
+
}) satisfies Chain
|
|
14
33
|
|
|
15
34
|
describe('isMainnet', () => {
|
|
16
35
|
test('is true only for the mainnet chain id', () => {
|
|
@@ -24,15 +43,41 @@ describe('isMainnet', () => {
|
|
|
24
43
|
})
|
|
25
44
|
})
|
|
26
45
|
|
|
27
|
-
describe('
|
|
46
|
+
describe('configuredChainIds', () => {
|
|
47
|
+
test('returns ids from object and serialized URL maps', () => {
|
|
48
|
+
expect(Viem.configuredChainIds({ 31_318: 'https://nextfork.tidx.test' })).toEqual([31_318])
|
|
49
|
+
expect(
|
|
50
|
+
Viem.configuredChainIds(
|
|
51
|
+
JSON.stringify({
|
|
52
|
+
31_318: 'https://nextfork.tidx.test',
|
|
53
|
+
421_700_002: 'https://zone.tidx.test',
|
|
54
|
+
}),
|
|
55
|
+
),
|
|
56
|
+
).toEqual([31_318, 421_700_002])
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('returns no ids for shared URLs and dynamic resolvers', () => {
|
|
60
|
+
expect(Viem.configuredChainIds('https://tidx.test')).toEqual([])
|
|
61
|
+
expect(Viem.configuredChainIds(() => 'https://tidx.test')).toEqual([])
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('rejects malformed chain-id maps', () => {
|
|
65
|
+
for (const chainId of ['-1', '0', '031318', '0x7a56', '1e3', '9007199254740992', 'devnet'])
|
|
66
|
+
expect(() =>
|
|
67
|
+
Viem.configuredChainIds(JSON.stringify({ [chainId]: 'https://tidx.test' })),
|
|
68
|
+
).toThrow('Expected a URL or a chain-id-to-URL JSON object.')
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe('resolveRpc', () => {
|
|
28
73
|
test('defaults to the per-chain RPC URL', () => {
|
|
29
|
-
expect(Viem.
|
|
74
|
+
expect(Viem.resolveRpc(undefined, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
|
|
30
75
|
{
|
|
31
76
|
"basicAuth": undefined,
|
|
32
77
|
"url": "https://rpc.tempo.xyz",
|
|
33
78
|
}
|
|
34
79
|
`)
|
|
35
|
-
expect(Viem.
|
|
80
|
+
expect(Viem.resolveRpc(undefined, { chainId: 42431, principal: null })).toMatchInlineSnapshot(`
|
|
36
81
|
{
|
|
37
82
|
"basicAuth": undefined,
|
|
38
83
|
"url": "https://rpc.testnet.tempo.xyz",
|
|
@@ -42,8 +87,8 @@ describe('resolve', () => {
|
|
|
42
87
|
|
|
43
88
|
test('uses a static config override', () => {
|
|
44
89
|
expect(
|
|
45
|
-
Viem.
|
|
46
|
-
{
|
|
90
|
+
Viem.resolveRpc(
|
|
91
|
+
{ auth: 'user:pass', url: (chainId) => `https://${chainId}.rpc.test` },
|
|
47
92
|
{ chainId: 4217, principal: null },
|
|
48
93
|
),
|
|
49
94
|
).toMatchInlineSnapshot(`
|
|
@@ -54,15 +99,62 @@ describe('resolve', () => {
|
|
|
54
99
|
`)
|
|
55
100
|
})
|
|
56
101
|
|
|
102
|
+
test('selects RPC URLs by chain id', () => {
|
|
103
|
+
const rpc = {
|
|
104
|
+
publicZoneUrl: JSON.stringify({ 421_700_001: 'https://public.zone.rpc.test' }),
|
|
105
|
+
url: JSON.stringify({ 4217: 'https://mainnet.rpc.test' }),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
|
|
109
|
+
{
|
|
110
|
+
"basicAuth": undefined,
|
|
111
|
+
"url": "https://mainnet.rpc.test",
|
|
112
|
+
}
|
|
113
|
+
`)
|
|
114
|
+
expect(Viem.resolveRpc(rpc, { chainId: zone.id, principal: null, zone }))
|
|
115
|
+
.toMatchInlineSnapshot(`
|
|
116
|
+
{
|
|
117
|
+
"basicAuth": undefined,
|
|
118
|
+
"publicZoneUrl": "https://public.zone.rpc.test",
|
|
119
|
+
"url": "https://internal.zone.rpc.test",
|
|
120
|
+
}
|
|
121
|
+
`)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
test('selects auth and scheme by chain id', () => {
|
|
125
|
+
const rpc = { auth: { 4217: 'mainnet:secret', 42431: 'testnet-token' } }
|
|
126
|
+
|
|
127
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null }).basicAuth).toBe(
|
|
128
|
+
'mainnet:secret',
|
|
129
|
+
)
|
|
130
|
+
expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: null }).bearerAuth).toBe(
|
|
131
|
+
'testnet-token',
|
|
132
|
+
)
|
|
133
|
+
expect(
|
|
134
|
+
Viem.resolveRpc(rpc, { chainId: 421_700_001, principal: null }).basicAuth,
|
|
135
|
+
).toBeUndefined()
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('parses serialized Basic auth by chain id', () => {
|
|
139
|
+
const rpc = { auth: JSON.stringify({ 4217: 'mainnet:secret' }) }
|
|
140
|
+
|
|
141
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null }).basicAuth).toBe(
|
|
142
|
+
'mainnet:secret',
|
|
143
|
+
)
|
|
144
|
+
expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: null }).basicAuth).toBeUndefined()
|
|
145
|
+
})
|
|
146
|
+
|
|
57
147
|
test('the static form ignores the principal', () => {
|
|
58
|
-
const rpc = {
|
|
59
|
-
expect(Viem.
|
|
148
|
+
const rpc = { auth: 'user:pass', url: () => 'https://internal.rpc' }
|
|
149
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: publicPrincipal }))
|
|
150
|
+
.toMatchInlineSnapshot(`
|
|
60
151
|
{
|
|
61
152
|
"basicAuth": "user:pass",
|
|
62
153
|
"url": "https://internal.rpc",
|
|
63
154
|
}
|
|
64
155
|
`)
|
|
65
|
-
expect(Viem.
|
|
156
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: apiKeyPrincipal }))
|
|
157
|
+
.toMatchInlineSnapshot(`
|
|
66
158
|
{
|
|
67
159
|
"basicAuth": "user:pass",
|
|
68
160
|
"url": "https://internal.rpc",
|
|
@@ -71,17 +163,19 @@ describe('resolve', () => {
|
|
|
71
163
|
})
|
|
72
164
|
|
|
73
165
|
test('the resolver form routes anonymous callers to a separate upstream', () => {
|
|
74
|
-
const rpc = ({ principal }: Viem.
|
|
166
|
+
const rpc = ({ principal }: Viem.resolveRpc.Context) =>
|
|
75
167
|
principal?.type === 'public'
|
|
76
168
|
? { url: 'https://rpc.tempo.xyz' }
|
|
77
|
-
: {
|
|
78
|
-
expect(Viem.
|
|
169
|
+
: { auth: 'user:pass', url: 'https://internal.rpc' }
|
|
170
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: publicPrincipal }))
|
|
171
|
+
.toMatchInlineSnapshot(`
|
|
79
172
|
{
|
|
80
173
|
"basicAuth": undefined,
|
|
81
174
|
"url": "https://rpc.tempo.xyz",
|
|
82
175
|
}
|
|
83
176
|
`)
|
|
84
|
-
expect(Viem.
|
|
177
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: apiKeyPrincipal }))
|
|
178
|
+
.toMatchInlineSnapshot(`
|
|
85
179
|
{
|
|
86
180
|
"basicAuth": "user:pass",
|
|
87
181
|
"url": "https://internal.rpc",
|
|
@@ -90,11 +184,11 @@ describe('resolve', () => {
|
|
|
90
184
|
})
|
|
91
185
|
|
|
92
186
|
test('a null principal (trusted poller) takes the non-public branch', () => {
|
|
93
|
-
const rpc = ({ principal }: Viem.
|
|
187
|
+
const rpc = ({ principal }: Viem.resolveRpc.Context) =>
|
|
94
188
|
principal?.type === 'public'
|
|
95
189
|
? { url: 'https://rpc.tempo.xyz' }
|
|
96
|
-
: {
|
|
97
|
-
expect(Viem.
|
|
190
|
+
: { auth: 'user:pass', url: 'https://internal.rpc' }
|
|
191
|
+
expect(Viem.resolveRpc(rpc, { chainId: 4217, principal: null })).toMatchInlineSnapshot(`
|
|
98
192
|
{
|
|
99
193
|
"basicAuth": "user:pass",
|
|
100
194
|
"url": "https://internal.rpc",
|
|
@@ -104,7 +198,7 @@ describe('resolve', () => {
|
|
|
104
198
|
|
|
105
199
|
test('a resolver that omits url falls back to the built-in public host', () => {
|
|
106
200
|
const rpc = () => ({})
|
|
107
|
-
expect(Viem.
|
|
201
|
+
expect(Viem.resolveRpc(rpc, { chainId: 42431, principal: publicPrincipal }))
|
|
108
202
|
.toMatchInlineSnapshot(`
|
|
109
203
|
{
|
|
110
204
|
"basicAuth": undefined,
|
|
@@ -112,6 +206,65 @@ describe('resolve', () => {
|
|
|
112
206
|
}
|
|
113
207
|
`)
|
|
114
208
|
})
|
|
209
|
+
|
|
210
|
+
test('a resolver that omits url falls back to the Zone internal host', () => {
|
|
211
|
+
expect(Viem.resolveRpc(() => ({}), { chainId: zone.id, principal: publicPrincipal, zone }))
|
|
212
|
+
.toMatchInlineSnapshot(`
|
|
213
|
+
{
|
|
214
|
+
"basicAuth": undefined,
|
|
215
|
+
"publicZoneUrl": "https://zone.rpc.test",
|
|
216
|
+
"url": "https://internal.zone.rpc.test",
|
|
217
|
+
}
|
|
218
|
+
`)
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
describe('getClient', () => {
|
|
223
|
+
test('sends inferred Bearer auth', async () => {
|
|
224
|
+
const fetch = vi
|
|
225
|
+
.spyOn(globalThis, 'fetch')
|
|
226
|
+
.mockResolvedValue(Response.json({ id: 1, jsonrpc: '2.0', result: '0x1079' }))
|
|
227
|
+
try {
|
|
228
|
+
const client = Viem.getClient({
|
|
229
|
+
chainId: 4217,
|
|
230
|
+
rpc: { auth: 'rpc-token', url: 'https://internal.rpc.test' },
|
|
231
|
+
})
|
|
232
|
+
await client.getChainId()
|
|
233
|
+
|
|
234
|
+
const [input, init] = fetch.mock.calls[0]!
|
|
235
|
+
const upstream = new Request(input, init)
|
|
236
|
+
expect(upstream.headers.get('authorization')).toBe('Bearer rpc-token')
|
|
237
|
+
} finally {
|
|
238
|
+
fetch.mockRestore()
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
test('does not send RPC auth to a public Zone URL', async () => {
|
|
243
|
+
const fetch = vi
|
|
244
|
+
.spyOn(globalThis, 'fetch')
|
|
245
|
+
.mockResolvedValue(Response.json({ id: 1, jsonrpc: '2.0', result: '0x1079' }))
|
|
246
|
+
try {
|
|
247
|
+
const client = Viem.getClient({
|
|
248
|
+
chainId: zone.id,
|
|
249
|
+
rpc: {
|
|
250
|
+
auth: 'rpc:secret',
|
|
251
|
+
publicZoneUrl: 'https://public.zone.rpc.test',
|
|
252
|
+
url: 'https://internal.rpc.test',
|
|
253
|
+
},
|
|
254
|
+
zone,
|
|
255
|
+
zoneToken: 'zone-token',
|
|
256
|
+
})
|
|
257
|
+
await client.getChainId()
|
|
258
|
+
|
|
259
|
+
const [input, init] = fetch.mock.calls[0]!
|
|
260
|
+
const upstream = new Request(input, init)
|
|
261
|
+
expect(upstream.url).toBe('https://public.zone.rpc.test/')
|
|
262
|
+
expect(upstream.headers.get('authorization')).toBeNull()
|
|
263
|
+
expect(upstream.headers.get(ZoneRpcAuthentication.headerName)).toBe('zone-token')
|
|
264
|
+
} finally {
|
|
265
|
+
fetch.mockRestore()
|
|
266
|
+
}
|
|
267
|
+
})
|
|
115
268
|
})
|
|
116
269
|
|
|
117
270
|
describe('createGetClient', () => {
|
|
@@ -120,7 +273,7 @@ describe('createGetClient', () => {
|
|
|
120
273
|
rpc: ({ principal }) =>
|
|
121
274
|
principal?.type === 'public'
|
|
122
275
|
? { url: 'https://rpc.tempo.xyz' }
|
|
123
|
-
: {
|
|
276
|
+
: { auth: 'user:pass', url: 'https://internal.rpc' },
|
|
124
277
|
})
|
|
125
278
|
|
|
126
279
|
expect(getClient(4217, apiKeyPrincipal)).toBe(getClient(4217, apiKeyPrincipal))
|
package/src/internal/Viem.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ZoneRpcAuthentication } from 'ox/tempo'
|
|
2
2
|
import { createClient, http, publicActions } from 'viem'
|
|
3
|
-
import type { Client as core_Client, HttpTransport, PublicActions } from 'viem'
|
|
3
|
+
import type { Chain as core_Chain, Client as core_Client, HttpTransport, PublicActions } from 'viem'
|
|
4
4
|
import { tempoActions } from 'viem/tempo'
|
|
5
5
|
import type { TempoActions } from 'viem/tempo'
|
|
6
6
|
import { tempoMainnet, tempoTestnet } from 'viem/tempo/chains'
|
|
7
7
|
import type * as z from 'zod/mini'
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import * as Auth from './Auth.js'
|
|
10
10
|
import type * as Schema from './Schema.js'
|
|
11
11
|
|
|
12
12
|
/** Known Tempo chains keyed by id, for metadata lookups. */
|
|
@@ -41,22 +41,29 @@ export type Chain = Omit<typeof tempoMainnet, 'id'> & { id: ChainId }
|
|
|
41
41
|
/** Gets a Tempo viem client for a chain id. */
|
|
42
42
|
export type GetClient = (chainId?: ChainId) => getClient.ReturnType
|
|
43
43
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
/** Shared, per-chain, or dynamically resolved RPC URLs. */
|
|
45
|
+
export type UrlResolver =
|
|
46
|
+
| string
|
|
47
|
+
| Record<number, string>
|
|
48
|
+
| ((chainId: ChainId) => string | undefined)
|
|
49
|
+
|
|
50
|
+
/** Returns chain ids declared by a static chain-id-to-URL map. */
|
|
51
|
+
export function configuredChainIds(value: UrlResolver | undefined): number[] {
|
|
52
|
+
const urls = parseUrls(value)
|
|
53
|
+
if (!urls || typeof urls === 'string' || typeof urls === 'function') return []
|
|
54
|
+
return Object.keys(urls).map(Number)
|
|
55
|
+
}
|
|
49
56
|
|
|
50
57
|
/**
|
|
51
58
|
* Resolves the effective RPC config for a single request.
|
|
52
59
|
*
|
|
53
60
|
* Accepts either a static config object or a per-request resolver function. The
|
|
54
|
-
* resolver receives a {@link
|
|
61
|
+
* resolver receives a {@link resolveRpc.Context} (`chainId` plus the request
|
|
55
62
|
* `principal`), so callers can route traffic per caller — e.g. send anonymous
|
|
56
63
|
* (`principal.type === 'public'`) traffic to a separate, no-auth upstream. A
|
|
57
64
|
* `null` principal denotes a trusted, non-request caller (the scheduled
|
|
58
65
|
* webhook poller). A missing `url` falls back to the built-in public host map
|
|
59
|
-
* ({@link url});
|
|
66
|
+
* ({@link url}); missing `auth` means no Authorization header is sent.
|
|
60
67
|
*
|
|
61
68
|
* Memoization is keyed on the resolved output (see {@link createGetClient} and
|
|
62
69
|
* {@link Tidx.createGetClient}), not the context, so a resolver may branch on
|
|
@@ -64,20 +71,27 @@ export type UrlResolver = (chainId: ChainId) => string | undefined
|
|
|
64
71
|
* resolve to the same upstream share a client. Pass the result to
|
|
65
72
|
* {@link getClient} (or let `getClient` resolve for you) to build a client.
|
|
66
73
|
*/
|
|
67
|
-
export function
|
|
74
|
+
export function resolveRpc(
|
|
68
75
|
rpc: getClient.Rpc | undefined,
|
|
69
|
-
context:
|
|
70
|
-
):
|
|
76
|
+
context: resolveRpc.Context,
|
|
77
|
+
): resolveRpc.Resolved {
|
|
71
78
|
const config = typeof rpc === 'function' ? rpc(context) : rpc
|
|
79
|
+
const auth = Auth.resolveCredential({ chainId: context.chainId, value: config?.auth })
|
|
80
|
+
const publicZoneUrl = context.zone
|
|
81
|
+
? (resolveUrl(config?.publicZoneUrl, context.chainId) ?? context.zone.rpcUrls.default.http[0])
|
|
82
|
+
: undefined
|
|
72
83
|
return {
|
|
73
|
-
|
|
84
|
+
...auth,
|
|
85
|
+
...(publicZoneUrl ? { publicZoneUrl } : {}),
|
|
74
86
|
url:
|
|
75
|
-
(
|
|
87
|
+
resolveUrl(config?.url, context.chainId) ??
|
|
88
|
+
context.zone?.rpcUrls['internal']?.http[0] ??
|
|
89
|
+
context.zone?.rpcUrls.default.http[0] ??
|
|
76
90
|
url[context.chainId],
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
export declare namespace
|
|
94
|
+
export declare namespace resolveRpc {
|
|
81
95
|
/** RPC resolution context. */
|
|
82
96
|
type Context = {
|
|
83
97
|
/** Tempo chain id. */
|
|
@@ -88,12 +102,18 @@ export declare namespace resolve {
|
|
|
88
102
|
* `type: 'public'` principal; authenticated requests a `type: 'api_key'` one.
|
|
89
103
|
*/
|
|
90
104
|
principal: Auth.Principal | null
|
|
105
|
+
/** Zone chain selected for this request, when applicable. */
|
|
106
|
+
zone?: core_Chain | undefined
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
/** Resolved RPC config for a single request. */
|
|
94
110
|
type Resolved = {
|
|
95
111
|
/** Basic auth credentials, or undefined to send no Basic auth. */
|
|
96
112
|
basicAuth?: string | undefined
|
|
113
|
+
/** Bearer auth credential, or undefined to send no Bearer auth. */
|
|
114
|
+
bearerAuth?: string | undefined
|
|
115
|
+
/** Public Zone RPC URL that accepts a caller-provided authorization token. */
|
|
116
|
+
publicZoneUrl?: string | undefined
|
|
97
117
|
/**
|
|
98
118
|
* Resolved RPC URL, or `undefined` when neither a configured `rpc` nor the
|
|
99
119
|
* built-in {@link url} map covers the chain (e.g. an unconfigured localnet).
|
|
@@ -104,13 +124,27 @@ export declare namespace resolve {
|
|
|
104
124
|
}
|
|
105
125
|
|
|
106
126
|
export function getClient(options: getClient.Options): getClient.ReturnType {
|
|
107
|
-
const { chainId = defaultChainId, principal = null, rpc, zoneToken } = options
|
|
108
|
-
const { basicAuth, url
|
|
127
|
+
const { chainId = defaultChainId, principal = null, rpc, zone, zoneToken } = options
|
|
128
|
+
const { basicAuth, bearerAuth, publicZoneUrl, url } = resolveRpc(rpc, {
|
|
129
|
+
chainId,
|
|
130
|
+
principal,
|
|
131
|
+
zone,
|
|
132
|
+
})
|
|
133
|
+
const usePublicZoneUrl = Boolean(zoneToken && publicZoneUrl)
|
|
134
|
+
const rpcUrl = usePublicZoneUrl ? publicZoneUrl : url
|
|
135
|
+
// Public Zone endpoints authenticate with the caller's token, never internal RPC credentials.
|
|
136
|
+
const authorization = usePublicZoneUrl
|
|
137
|
+
? undefined
|
|
138
|
+
: basicAuth
|
|
139
|
+
? `Basic ${btoa(basicAuth)}`
|
|
140
|
+
: bearerAuth
|
|
141
|
+
? `Bearer ${bearerAuth}`
|
|
142
|
+
: undefined
|
|
109
143
|
const fetchOptions =
|
|
110
|
-
|
|
144
|
+
authorization || zoneToken
|
|
111
145
|
? {
|
|
112
146
|
headers: {
|
|
113
|
-
...(
|
|
147
|
+
...(authorization ? { Authorization: authorization } : {}),
|
|
114
148
|
...(zoneToken ? { [ZoneRpcAuthentication.headerName]: zoneToken } : {}),
|
|
115
149
|
},
|
|
116
150
|
}
|
|
@@ -134,16 +168,21 @@ export function getClient(options: getClient.Options): getClient.ReturnType {
|
|
|
134
168
|
export function createGetClient(options: createGetClient.Options = {}): createGetClient.ReturnType {
|
|
135
169
|
const { defaultChainId: defaultChainId_option = defaultChainId, rpc } = options
|
|
136
170
|
const clients = new Map<string, getClient.ReturnType>()
|
|
171
|
+
const zones = new Map((options.zones ?? []).map((zone) => [zone.id, zone]))
|
|
137
172
|
|
|
138
173
|
return (chainId = defaultChainId_option, principal = null) => {
|
|
139
|
-
const { basicAuth, url } =
|
|
140
|
-
|
|
174
|
+
const { basicAuth, bearerAuth, url } = resolveRpc(rpc, {
|
|
175
|
+
chainId,
|
|
176
|
+
principal,
|
|
177
|
+
zone: zones.get(chainId),
|
|
178
|
+
})
|
|
179
|
+
const cacheKey = JSON.stringify([url, basicAuth, bearerAuth, chainId])
|
|
141
180
|
const existing = clients.get(cacheKey)
|
|
142
181
|
if (existing) return existing
|
|
143
182
|
|
|
144
183
|
const client = getClient({
|
|
145
184
|
chainId,
|
|
146
|
-
rpc: { basicAuth, url: () => url },
|
|
185
|
+
rpc: { auth: basicAuth ?? bearerAuth, url: () => url },
|
|
147
186
|
})
|
|
148
187
|
clients.set(cacheKey, client)
|
|
149
188
|
return client
|
|
@@ -157,6 +196,8 @@ export declare namespace createGetClient {
|
|
|
157
196
|
defaultChainId?: ChainId | undefined
|
|
158
197
|
/** Tempo RPC options applied to every constructed client. */
|
|
159
198
|
rpc?: getClient.Rpc | undefined
|
|
199
|
+
/** Zone chains whose internal RPC URLs serve as per-chain defaults. */
|
|
200
|
+
zones?: readonly core_Chain[] | undefined
|
|
160
201
|
}
|
|
161
202
|
|
|
162
203
|
/** Memoized Tempo client resolver. */
|
|
@@ -182,26 +223,68 @@ export declare namespace getClient {
|
|
|
182
223
|
principal?: Auth.Principal | null | undefined
|
|
183
224
|
/** Tempo RPC options. */
|
|
184
225
|
rpc?: Rpc | undefined
|
|
226
|
+
/** Zone chain metadata used for RPC URL resolution. */
|
|
227
|
+
zone?: core_Chain | undefined
|
|
185
228
|
/** Zone authorization token forwarded to the RPC node. */
|
|
186
229
|
zoneToken?: string | undefined
|
|
187
230
|
}
|
|
188
231
|
|
|
189
232
|
/**
|
|
190
233
|
* Tempo RPC options: either a static config, or a per-request resolver
|
|
191
|
-
* function that receives a {@link
|
|
234
|
+
* function that receives a {@link resolveRpc.Context} and returns the config to
|
|
192
235
|
* use (e.g. routing anonymous callers to a public, no-auth RPC).
|
|
193
236
|
*/
|
|
194
237
|
type Rpc =
|
|
195
238
|
| {
|
|
196
|
-
/** Basic auth
|
|
197
|
-
|
|
239
|
+
/** Shared or per-chain RPC credentials. Values containing `:` use Basic auth; others use Bearer auth. */
|
|
240
|
+
auth?: Auth.ChainCredential | undefined
|
|
241
|
+
/** Resolves the public Zone RPC URL used with caller-provided authorization. */
|
|
242
|
+
publicZoneUrl?: UrlResolver | undefined
|
|
198
243
|
/** Resolves the RPC URL for a Tempo chain id. */
|
|
199
244
|
url?: UrlResolver | undefined
|
|
200
245
|
}
|
|
201
|
-
| ((context:
|
|
202
|
-
/**
|
|
203
|
-
|
|
246
|
+
| ((context: resolveRpc.Context) => {
|
|
247
|
+
/** Shared or per-chain RPC credentials, or undefined for none. */
|
|
248
|
+
auth?: Auth.ChainCredential | undefined
|
|
249
|
+
/** Public Zone RPC URL used with caller-provided authorization. */
|
|
250
|
+
publicZoneUrl?: string | undefined
|
|
204
251
|
/** RPC URL to use; falls back to the built-in public host when omitted. */
|
|
205
252
|
url?: string | undefined
|
|
206
253
|
})
|
|
207
254
|
}
|
|
255
|
+
|
|
256
|
+
/** Resolves a shared or per-chain URL for one chain id. */
|
|
257
|
+
export function resolveUrl(value: UrlResolver | undefined, chainId: ChainId) {
|
|
258
|
+
if (typeof value === 'function') return value(chainId)
|
|
259
|
+
const urls = parseUrls(value)
|
|
260
|
+
if (!urls) return undefined
|
|
261
|
+
if (typeof urls === 'string') return urls
|
|
262
|
+
return urls[chainId]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function parseUrls(value: UrlResolver | undefined): Record<number, string> | string | undefined {
|
|
266
|
+
if (!value || typeof value === 'function') return undefined
|
|
267
|
+
const urls =
|
|
268
|
+
typeof value === 'string'
|
|
269
|
+
? (() => {
|
|
270
|
+
try {
|
|
271
|
+
return JSON.parse(value) as unknown
|
|
272
|
+
} catch {
|
|
273
|
+
return value
|
|
274
|
+
}
|
|
275
|
+
})()
|
|
276
|
+
: value
|
|
277
|
+
if (typeof urls === 'string') return urls
|
|
278
|
+
if (
|
|
279
|
+
!urls ||
|
|
280
|
+
typeof urls !== 'object' ||
|
|
281
|
+
Array.isArray(urls) ||
|
|
282
|
+
Object.keys(urls).some((chainId) => {
|
|
283
|
+
const id = Number(chainId)
|
|
284
|
+
return !Number.isSafeInteger(id) || id <= 0 || String(id) !== chainId
|
|
285
|
+
}) ||
|
|
286
|
+
Object.values(urls).some((url) => typeof url !== 'string')
|
|
287
|
+
)
|
|
288
|
+
throw new Error('Expected a URL or a chain-id-to-URL JSON object.')
|
|
289
|
+
return urls as Record<number, string>
|
|
290
|
+
}
|
|
@@ -232,7 +232,7 @@ export const eventTypeHeader = 'tempo-event-type'
|
|
|
232
232
|
*/
|
|
233
233
|
export function sign(options: sign.Options): string {
|
|
234
234
|
const timestamp = options.timestamp ?? Math.floor(Date.now() / 1_000)
|
|
235
|
-
const v1 = hmac(options.secret, `${timestamp}.${options.body}`)
|
|
235
|
+
const v1 = Signature.hmac(options.secret, `${timestamp}.${options.body}`)
|
|
236
236
|
return `t=${timestamp},v1=${v1}`
|
|
237
237
|
}
|
|
238
238
|
|
|
@@ -253,15 +253,15 @@ export declare namespace sign {
|
|
|
253
253
|
* rejects signatures older than `tolerance` seconds (default 300).
|
|
254
254
|
*/
|
|
255
255
|
export function verify(options: verify.Options): boolean {
|
|
256
|
-
const parsed =
|
|
256
|
+
const parsed = Signature.parse(options.signature)
|
|
257
257
|
if (!parsed) return false
|
|
258
258
|
|
|
259
259
|
const tolerance = options.tolerance ?? 300
|
|
260
260
|
const now = options.now ?? Math.floor(Date.now() / 1_000)
|
|
261
261
|
if (Math.abs(now - parsed.timestamp) > tolerance) return false
|
|
262
262
|
|
|
263
|
-
const expected = hmac(options.secret, `${parsed.timestamp}.${options.body}`)
|
|
264
|
-
return timingSafeEqual(expected, parsed.v1)
|
|
263
|
+
const expected = Signature.hmac(options.secret, `${parsed.timestamp}.${options.body}`)
|
|
264
|
+
return Signature.timingSafeEqual(expected, parsed.v1)
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
export declare namespace verify {
|
|
@@ -280,28 +280,30 @@ export declare namespace verify {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
namespace Signature {
|
|
284
|
+
export function hmac(secret: string, message: string): string {
|
|
285
|
+
return Hash.hmac256(Hex.fromString(secret), Hex.fromString(message)).slice(2)
|
|
286
|
+
}
|
|
286
287
|
|
|
287
|
-
function
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
288
|
+
export function parse(signature: string): { timestamp: number; v1: string } | null {
|
|
289
|
+
let timestamp: number | undefined
|
|
290
|
+
let v1: string | undefined
|
|
291
|
+
for (const part of signature.split(',')) {
|
|
292
|
+
const [key, value] = part.split('=', 2)
|
|
293
|
+
if (key === 't' && value) timestamp = Number(value)
|
|
294
|
+
else if (key === 'v1' && value) v1 = value
|
|
295
|
+
}
|
|
296
|
+
if (timestamp === undefined || Number.isNaN(timestamp) || !v1) return null
|
|
297
|
+
return { timestamp, v1 }
|
|
294
298
|
}
|
|
295
|
-
if (timestamp === undefined || Number.isNaN(timestamp) || !v1) return null
|
|
296
|
-
return { timestamp, v1 }
|
|
297
|
-
}
|
|
298
299
|
|
|
299
|
-
function timingSafeEqual(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
300
|
+
export function timingSafeEqual(left: string, right: string): boolean {
|
|
301
|
+
if (left.length !== right.length) return false
|
|
302
|
+
let mismatch = 0
|
|
303
|
+
for (let index = 0; index < left.length; index++)
|
|
304
|
+
mismatch |= left.charCodeAt(index) ^ right.charCodeAt(index)
|
|
305
|
+
return mismatch === 0
|
|
306
|
+
}
|
|
305
307
|
}
|
|
306
308
|
|
|
307
309
|
/** Thrown when a subscriber URL fails SSRF/format validation. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Webhooks } from 'tapimo'
|
|
2
2
|
import * as TestApp from '../../test/App.js'
|
|
3
|
+
import * as Cursor from './Cursor.js'
|
|
3
4
|
|
|
4
5
|
const apiKeyOwner = { orgId: 'org_1', type: 'api_key' } as const
|
|
5
6
|
const mppOwner = { payer: 'did:pkh:eip155:1:0xabc', type: 'mpp' } as const
|
|
@@ -56,6 +57,42 @@ describe('createSubscription', () => {
|
|
|
56
57
|
expect(read).toEqual(subscription)
|
|
57
58
|
})
|
|
58
59
|
|
|
60
|
+
test('commits an initial poller cursor through both insert paths', async () => {
|
|
61
|
+
const db = TestApp.database()
|
|
62
|
+
const direct = await Webhooks.createSubscription(db, createInput(), {
|
|
63
|
+
startBlockNumber: 123,
|
|
64
|
+
})
|
|
65
|
+
const capped = await Webhooks.createSubscription(db, createInput({ owner: mppOwner }), {
|
|
66
|
+
maxPerOwner: 1,
|
|
67
|
+
startBlockNumber: 456,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
expect(Cursor.decode((await Webhooks.getCursor(db, direct.id))!, ['int']))
|
|
71
|
+
.toMatchInlineSnapshot(`
|
|
72
|
+
[
|
|
73
|
+
123,
|
|
74
|
+
]
|
|
75
|
+
`)
|
|
76
|
+
expect(Cursor.decode((await Webhooks.getCursor(db, capped.id))!, ['int']))
|
|
77
|
+
.toMatchInlineSnapshot(`
|
|
78
|
+
[
|
|
79
|
+
456,
|
|
80
|
+
]
|
|
81
|
+
`)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('rejects an invalid initial block number before persisting', async () => {
|
|
85
|
+
const db = TestApp.database()
|
|
86
|
+
|
|
87
|
+
for (const startBlockNumber of [-1, 1.5, Number.MAX_SAFE_INTEGER + 1])
|
|
88
|
+
await expect(
|
|
89
|
+
Webhooks.createSubscription(db, createInput(), { startBlockNumber }),
|
|
90
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
91
|
+
`[RangeError: startBlockNumber must be a non-negative safe integer.]`,
|
|
92
|
+
)
|
|
93
|
+
expect(await Webhooks.listSubscriptions(db, apiKeyOwner)).toEqual([])
|
|
94
|
+
})
|
|
95
|
+
|
|
59
96
|
test('sets expiresAt from ttl for MPP-owned subscriptions', async () => {
|
|
60
97
|
const db = TestApp.database()
|
|
61
98
|
const subscription = await Webhooks.createSubscription(
|
|
@@ -301,6 +338,28 @@ describe('cursors', () => {
|
|
|
301
338
|
await Webhooks.setCursor(db, created.id, '12345:7')
|
|
302
339
|
expect(await Webhooks.getCursor(db, created.id)).toMatchInlineSnapshot(`"12345:7"`)
|
|
303
340
|
})
|
|
341
|
+
|
|
342
|
+
test('atomically rejects a stale cursor write', async () => {
|
|
343
|
+
const db = TestApp.database()
|
|
344
|
+
const created = await Webhooks.createSubscription(db, createInput())
|
|
345
|
+
const a = Cursor.encode([100, 1])
|
|
346
|
+
const b = Cursor.encode([100, 2])
|
|
347
|
+
const results = await Promise.all([
|
|
348
|
+
Webhooks.compareAndSetCursor(db, {
|
|
349
|
+
cursor: a,
|
|
350
|
+
expectedCursor: null,
|
|
351
|
+
subscriptionId: created.id,
|
|
352
|
+
}),
|
|
353
|
+
Webhooks.compareAndSetCursor(db, {
|
|
354
|
+
cursor: b,
|
|
355
|
+
expectedCursor: null,
|
|
356
|
+
subscriptionId: created.id,
|
|
357
|
+
}),
|
|
358
|
+
])
|
|
359
|
+
|
|
360
|
+
expect(results.toSorted((a, b) => Number(a) - Number(b))).toEqual([false, true])
|
|
361
|
+
expect([a, b]).toContain(await Webhooks.getCursor(db, created.id))
|
|
362
|
+
})
|
|
304
363
|
})
|
|
305
364
|
|
|
306
365
|
describe('recordSuccess / recordFailure', () => {
|