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,5 @@
|
|
|
1
|
+
/** @module-tag localnet */
|
|
2
|
+
|
|
1
3
|
import { nanoid } from 'nanoid'
|
|
2
4
|
import { Hash, Hex, Secp256k1 } from 'ox'
|
|
3
5
|
import { ZoneRpcAuthentication } from 'ox/tempo'
|
|
@@ -14,6 +16,7 @@ import * as TestStripe from '../../../test/Stripe.js'
|
|
|
14
16
|
import * as BillingSettings from '../../db/tables/billingSettings.js'
|
|
15
17
|
import type * as Db from '../../db/Db.js'
|
|
16
18
|
import * as Fees from '../../internal/Fees.js'
|
|
19
|
+
import type * as Log from '../../internal/Log.js'
|
|
17
20
|
import * as Organizations from '../../db/tables/organizations.js'
|
|
18
21
|
import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
|
|
19
22
|
import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
|
|
@@ -28,10 +31,10 @@ const feePayerAccount = Tempo.accounts[10]!
|
|
|
28
31
|
const senderAccount = Tempo.accounts[9]!
|
|
29
32
|
const zone = runtime.zone.chainId
|
|
30
33
|
const zoneScope = `zone:${zone}:read` as const
|
|
31
|
-
const zoneOptions = {
|
|
34
|
+
const zoneOptions = TestApp.zone({
|
|
32
35
|
chainId: zone,
|
|
33
|
-
|
|
34
|
-
}
|
|
36
|
+
rpcUrl: runtime.zone.publicZoneUrl,
|
|
37
|
+
})
|
|
35
38
|
|
|
36
39
|
/** Super admin secret configured on the end-to-end billing app. */
|
|
37
40
|
const superAdminSecret = 'tempo:sk:a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1'
|
|
@@ -255,8 +258,7 @@ describe('behavior: Zone chain routing', () => {
|
|
|
255
258
|
try {
|
|
256
259
|
const api = TestApp.create({
|
|
257
260
|
auth: { keys },
|
|
258
|
-
rpc: ({ chainId }) =>
|
|
259
|
-
chainId === zone ? { basicAuth: 'rpc-secret', url: server.url } : {},
|
|
261
|
+
rpc: ({ chainId }) => (chainId === zone ? { auth: 'rpc:secret', url: server.url } : {}),
|
|
260
262
|
zones: [zoneOptions],
|
|
261
263
|
})
|
|
262
264
|
const body = await request(api, {
|
|
@@ -266,7 +268,7 @@ describe('behavior: Zone chain routing', () => {
|
|
|
266
268
|
})
|
|
267
269
|
|
|
268
270
|
expect(body).toMatchObject({ result: Hex.fromNumber(zone) })
|
|
269
|
-
expect(authorization).toEqual(['Basic
|
|
271
|
+
expect(authorization).toEqual(['Basic cnBjOnNlY3JldA=='])
|
|
270
272
|
} finally {
|
|
271
273
|
await server.closeAsync()
|
|
272
274
|
}
|
|
@@ -368,8 +370,10 @@ describe('behavior: Zone chain routing', () => {
|
|
|
368
370
|
})
|
|
369
371
|
|
|
370
372
|
test('requires Zone authorization for an embedded signed transaction', async () => {
|
|
373
|
+
const entries: Log.Entry[] = []
|
|
371
374
|
const api = TestApp.create({
|
|
372
375
|
auth: { keys },
|
|
376
|
+
logger: (entry) => void entries.push(entry),
|
|
373
377
|
relay: { feePayer: { account: feePayerAccount } },
|
|
374
378
|
zones: [zoneOptions],
|
|
375
379
|
})
|
|
@@ -396,6 +400,7 @@ describe('behavior: Zone chain routing', () => {
|
|
|
396
400
|
const authorized = await request(api, { ...rpc, zoneToken: token() })
|
|
397
401
|
|
|
398
402
|
expect(refused).toMatchObject({ error: { data: { code: 'api_key_forbidden' } } })
|
|
403
|
+
expectSponsorshipCode({ code: 'api_key_forbidden', entry: entries[0] })
|
|
399
404
|
expect(authorized).toMatchObject({ result: expect.stringMatching(/^0x/) })
|
|
400
405
|
})
|
|
401
406
|
})
|
|
@@ -450,7 +455,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
450
455
|
`)
|
|
451
456
|
})
|
|
452
457
|
|
|
453
|
-
test('behavior: non-mainnet production keys record billable rows', async () => {
|
|
458
|
+
test('behavior: non-mainnet production keys record non-billable rows', async () => {
|
|
454
459
|
const db = TestApp.database()
|
|
455
460
|
const app = TestApp.create({
|
|
456
461
|
auth: { keys },
|
|
@@ -466,7 +471,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
466
471
|
expect(body.error).toBeUndefined()
|
|
467
472
|
|
|
468
473
|
const [row] = await SponsoredTransactions.listPending(db)
|
|
469
|
-
expect(row?.billable).toBe(
|
|
474
|
+
expect(row?.billable).toBe(false)
|
|
470
475
|
expect(row?.environment).toMatchInlineSnapshot(`"production"`)
|
|
471
476
|
})
|
|
472
477
|
|
|
@@ -509,7 +514,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
509
514
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
510
515
|
})
|
|
511
516
|
|
|
512
|
-
test('behavior: keys without project
|
|
517
|
+
test('behavior: organization-attributed keys sponsor without a project', async () => {
|
|
513
518
|
const db = TestApp.database()
|
|
514
519
|
const app = TestApp.create({
|
|
515
520
|
auth: { keys },
|
|
@@ -522,26 +527,273 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
522
527
|
params: [await signSponsorable()],
|
|
523
528
|
token: 'secret_unattributed',
|
|
524
529
|
})
|
|
525
|
-
expect(body.
|
|
526
|
-
expect(body.
|
|
530
|
+
expect(body.error).toBeUndefined()
|
|
531
|
+
expect(Transaction.deserialize(body.result as `0x76${string}`).feePayerSignature).toBeDefined()
|
|
532
|
+
|
|
533
|
+
const [row] = await SponsoredTransactions.listPending(db)
|
|
534
|
+
expect(row?.orgId).toMatchInlineSnapshot(`"org_1"`)
|
|
535
|
+
expect(row?.projectId).toBeNull()
|
|
536
|
+
})
|
|
537
|
+
|
|
538
|
+
test('behavior: batches aggregate sponsorship rejections without retaining payloads', async () => {
|
|
539
|
+
const db = TestApp.database()
|
|
540
|
+
const entries: Log.Entry[] = []
|
|
541
|
+
const app = TestApp.create({
|
|
542
|
+
auth: { keys },
|
|
543
|
+
db,
|
|
544
|
+
logger: (entry) => void entries.push(entry),
|
|
545
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
546
|
+
})
|
|
547
|
+
const transactions = await Promise.all([
|
|
548
|
+
signSponsorable({ chainId: 999_999, nonce: 0 }),
|
|
549
|
+
signSponsorable({ chainId: 999_999, nonce: 1 }),
|
|
550
|
+
])
|
|
551
|
+
|
|
552
|
+
const response = await app.fetch(
|
|
553
|
+
new Request('http://tempo-api.test/rpc/sponsor', {
|
|
554
|
+
body: JSON.stringify(
|
|
555
|
+
transactions.map((transaction, index) => ({
|
|
556
|
+
id: index + 1,
|
|
557
|
+
jsonrpc: '2.0',
|
|
558
|
+
method: 'eth_signRawTransaction',
|
|
559
|
+
params: [transaction],
|
|
560
|
+
})),
|
|
561
|
+
),
|
|
562
|
+
headers: {
|
|
563
|
+
'content-type': 'application/json',
|
|
564
|
+
'tempo-api-key': 'secret_sponsor',
|
|
565
|
+
},
|
|
566
|
+
method: 'POST',
|
|
567
|
+
}),
|
|
568
|
+
)
|
|
569
|
+
const body = await response.json()
|
|
570
|
+
|
|
571
|
+
expect(body).toMatchObject([
|
|
572
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
573
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
574
|
+
])
|
|
575
|
+
expect(entries).toHaveLength(1)
|
|
576
|
+
expect(entries[0]?.rpc).toStrictEqual({
|
|
577
|
+
code: -32602,
|
|
578
|
+
dataCode: 'chain_id_unsupported',
|
|
579
|
+
errors: 2,
|
|
580
|
+
})
|
|
581
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
582
|
+
chainId: 999_999,
|
|
583
|
+
method: 'eth_signRawTransaction',
|
|
584
|
+
outcome: 'rejected',
|
|
585
|
+
reason: 'chain_id_unsupported',
|
|
586
|
+
rejections: 2,
|
|
587
|
+
})
|
|
588
|
+
expect(JSON.stringify(entries[0])).not.toContain(transactions[0])
|
|
589
|
+
expect(JSON.stringify(entries[0])).not.toContain(transactions[1])
|
|
590
|
+
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
591
|
+
})
|
|
592
|
+
|
|
593
|
+
test('behavior: invalid batch items never enable payload hashes', async () => {
|
|
594
|
+
const db = TestApp.database()
|
|
595
|
+
const entries: Log.Entry[] = []
|
|
596
|
+
const app = TestApp.create({
|
|
597
|
+
auth: { keys },
|
|
598
|
+
db,
|
|
599
|
+
logger: (entry) => void entries.push(entry),
|
|
600
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
601
|
+
})
|
|
602
|
+
const serialized = await signSponsorable({ chainId: 999_999 })
|
|
603
|
+
|
|
604
|
+
const response = await app.fetch(
|
|
605
|
+
new Request('http://tempo-api.test/rpc/sponsor', {
|
|
606
|
+
body: JSON.stringify([
|
|
607
|
+
null,
|
|
608
|
+
{
|
|
609
|
+
id: 2,
|
|
610
|
+
jsonrpc: '2.0',
|
|
611
|
+
method: 'eth_signRawTransaction',
|
|
612
|
+
params: [serialized],
|
|
613
|
+
},
|
|
614
|
+
]),
|
|
615
|
+
headers: {
|
|
616
|
+
'content-type': 'application/json',
|
|
617
|
+
'tempo-api-key': 'secret_sponsor',
|
|
618
|
+
},
|
|
619
|
+
method: 'POST',
|
|
620
|
+
}),
|
|
621
|
+
)
|
|
622
|
+
const body = await response.json()
|
|
623
|
+
|
|
624
|
+
expect(body).toMatchObject([
|
|
625
|
+
{ error: { code: -32600 } },
|
|
626
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
627
|
+
])
|
|
628
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
629
|
+
chainId: 999_999,
|
|
630
|
+
method: 'eth_signRawTransaction',
|
|
631
|
+
outcome: 'rejected',
|
|
632
|
+
reason: 'chain_id_unsupported',
|
|
633
|
+
rejections: 1,
|
|
634
|
+
})
|
|
635
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
636
|
+
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
637
|
+
})
|
|
638
|
+
|
|
639
|
+
test('behavior: batch diagnostics use only rejected request methods', async () => {
|
|
640
|
+
const db = TestApp.database()
|
|
641
|
+
const entries: Log.Entry[] = []
|
|
642
|
+
const app = TestApp.create({
|
|
643
|
+
auth: { keys },
|
|
644
|
+
db,
|
|
645
|
+
logger: (entry) => void entries.push(entry),
|
|
646
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
647
|
+
})
|
|
648
|
+
const serialized = await signSponsorable({ chainId: 999_999 })
|
|
649
|
+
|
|
650
|
+
const response = await app.fetch(
|
|
651
|
+
new Request('http://tempo-api.test/rpc/sponsor', {
|
|
652
|
+
body: JSON.stringify([
|
|
653
|
+
{
|
|
654
|
+
id: 1,
|
|
655
|
+
jsonrpc: '2.0',
|
|
656
|
+
method: 'eth_fillTransaction',
|
|
657
|
+
params: [],
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
id: 2,
|
|
661
|
+
jsonrpc: '2.0',
|
|
662
|
+
method: 'eth_signRawTransaction',
|
|
663
|
+
params: [serialized],
|
|
664
|
+
},
|
|
665
|
+
]),
|
|
666
|
+
headers: {
|
|
667
|
+
'content-type': 'application/json',
|
|
668
|
+
'tempo-api-key': 'secret_sponsor',
|
|
669
|
+
},
|
|
670
|
+
method: 'POST',
|
|
671
|
+
}),
|
|
672
|
+
)
|
|
673
|
+
const body = await response.json()
|
|
674
|
+
|
|
675
|
+
expect(body).toMatchObject([
|
|
676
|
+
{ error: { data: { code: 'internal_error' } } },
|
|
677
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
678
|
+
])
|
|
679
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
680
|
+
chainId: 999_999,
|
|
681
|
+
method: 'eth_signRawTransaction',
|
|
682
|
+
outcome: 'rejected',
|
|
683
|
+
reason: 'chain_id_unsupported',
|
|
684
|
+
rejections: 1,
|
|
685
|
+
})
|
|
686
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
687
|
+
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
688
|
+
})
|
|
689
|
+
|
|
690
|
+
test('behavior: duplicate batch ids suppress request attribution', async () => {
|
|
691
|
+
const db = TestApp.database()
|
|
692
|
+
const entries: Log.Entry[] = []
|
|
693
|
+
const app = TestApp.create({
|
|
694
|
+
auth: { keys },
|
|
695
|
+
db,
|
|
696
|
+
logger: (entry) => void entries.push(entry),
|
|
697
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
698
|
+
})
|
|
699
|
+
const serialized = await signSponsorable({ chainId: 999_999 })
|
|
700
|
+
|
|
701
|
+
const response = await app.fetch(
|
|
702
|
+
new Request('http://tempo-api.test/rpc/sponsor/999999', {
|
|
703
|
+
body: JSON.stringify([
|
|
704
|
+
{
|
|
705
|
+
id: 1,
|
|
706
|
+
jsonrpc: '2.0',
|
|
707
|
+
method: 'eth_chainId',
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
id: 1,
|
|
711
|
+
jsonrpc: '2.0',
|
|
712
|
+
method: 'eth_signRawTransaction',
|
|
713
|
+
params: [serialized],
|
|
714
|
+
},
|
|
715
|
+
]),
|
|
716
|
+
headers: {
|
|
717
|
+
'content-type': 'application/json',
|
|
718
|
+
'tempo-api-key': 'secret_sponsor',
|
|
719
|
+
},
|
|
720
|
+
method: 'POST',
|
|
721
|
+
}),
|
|
722
|
+
)
|
|
723
|
+
const body = await response.json()
|
|
724
|
+
|
|
725
|
+
expect(body).toMatchObject([
|
|
726
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
727
|
+
{ error: { data: { code: 'chain_id_unsupported' } } },
|
|
728
|
+
])
|
|
729
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
730
|
+
chainId: 999_999,
|
|
731
|
+
outcome: 'rejected',
|
|
732
|
+
reason: 'chain_id_unsupported',
|
|
733
|
+
rejections: 2,
|
|
734
|
+
})
|
|
735
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
527
736
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
528
737
|
})
|
|
529
738
|
|
|
530
739
|
test('behavior: super admin principals are refused', async () => {
|
|
531
740
|
const db = TestApp.database()
|
|
741
|
+
const entries: Log.Entry[] = []
|
|
532
742
|
const app = TestApp.create({
|
|
533
743
|
auth: { keys, superAdmin: { secret: 'super-admin-secret' } },
|
|
534
744
|
db,
|
|
745
|
+
logger: (entry) => void entries.push(entry),
|
|
535
746
|
relay: { feePayer: { account: feePayerAccount } },
|
|
536
747
|
})
|
|
748
|
+
const serialized = await signSponsorable()
|
|
537
749
|
|
|
538
750
|
const body = await relayRequest(app, {
|
|
539
751
|
method: 'eth_signRawTransaction',
|
|
540
|
-
params: [
|
|
752
|
+
params: [serialized],
|
|
541
753
|
token: 'super-admin-secret',
|
|
542
754
|
})
|
|
543
755
|
expect(body.result).toBeUndefined()
|
|
544
|
-
expect(body.error
|
|
756
|
+
expect(body.error).toStrictEqual({
|
|
757
|
+
code: -32602,
|
|
758
|
+
data: { code: 'api_key_required' },
|
|
759
|
+
message: 'Sponsorship rejected.',
|
|
760
|
+
})
|
|
761
|
+
expectSponsorshipCode({ code: 'api_key_required', entry: entries[0] })
|
|
762
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
763
|
+
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
764
|
+
})
|
|
765
|
+
|
|
766
|
+
test('behavior: sponsorship policy invariants return internal errors', async () => {
|
|
767
|
+
const db = TestApp.database()
|
|
768
|
+
const entries: Log.Entry[] = []
|
|
769
|
+
const app = TestApp.create({
|
|
770
|
+
auth: {
|
|
771
|
+
keys,
|
|
772
|
+
overrides: {
|
|
773
|
+
'ALL /rpc/sponsor': { apiKey: { scopes: [] } },
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
db,
|
|
777
|
+
logger: (entry) => void entries.push(entry),
|
|
778
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
779
|
+
})
|
|
780
|
+
const serialized = await signSponsorable()
|
|
781
|
+
|
|
782
|
+
const body = await relayRequest(app, {
|
|
783
|
+
method: 'eth_signRawTransaction',
|
|
784
|
+
params: [serialized],
|
|
785
|
+
token: 'secret_unscoped',
|
|
786
|
+
})
|
|
787
|
+
|
|
788
|
+
expect(body.error).toStrictEqual({
|
|
789
|
+
code: -32603,
|
|
790
|
+
data: { code: 'internal_error' },
|
|
791
|
+
message: 'Internal error',
|
|
792
|
+
})
|
|
793
|
+
expect(entries[0]?.level).toBe('error')
|
|
794
|
+
expectSponsorshipCode({ code: 'internal_error', entry: entries[0] })
|
|
795
|
+
expect(entries[0]?.sponsorship?.internalErrors).toBe(1)
|
|
796
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
545
797
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
546
798
|
})
|
|
547
799
|
|
|
@@ -625,30 +877,49 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
|
|
|
625
877
|
|
|
626
878
|
test('behavior: sponsorship is refused for chains this deployment does not serve', async () => {
|
|
627
879
|
const db = TestApp.database()
|
|
880
|
+
const entries: Log.Entry[] = []
|
|
628
881
|
const app = TestApp.create({
|
|
629
882
|
auth: { keys },
|
|
630
883
|
db,
|
|
884
|
+
logger: (entry) => void entries.push(entry),
|
|
631
885
|
relay: { feePayer: { account: feePayerAccount } },
|
|
632
886
|
})
|
|
887
|
+
const serialized = await senderAccount.signTransaction({
|
|
888
|
+
chainId: 999_999,
|
|
889
|
+
feePayer: true,
|
|
890
|
+
gas: 100_000n,
|
|
891
|
+
maxFeePerGas: 1_000_000n,
|
|
892
|
+
maxPriorityFeePerGas: 0n,
|
|
893
|
+
nonce: 0,
|
|
894
|
+
to: Tempo.accounts[8]!.address,
|
|
895
|
+
value: 0n,
|
|
896
|
+
})
|
|
633
897
|
|
|
634
898
|
const body = await relayRequest(app, {
|
|
635
899
|
method: 'eth_signRawTransaction',
|
|
636
|
-
params: [
|
|
637
|
-
await senderAccount.signTransaction({
|
|
638
|
-
chainId: 999_999,
|
|
639
|
-
feePayer: true,
|
|
640
|
-
gas: 100_000n,
|
|
641
|
-
maxFeePerGas: 1_000_000n,
|
|
642
|
-
maxPriorityFeePerGas: 0n,
|
|
643
|
-
nonce: 0,
|
|
644
|
-
to: Tempo.accounts[8]!.address,
|
|
645
|
-
value: 0n,
|
|
646
|
-
}),
|
|
647
|
-
],
|
|
900
|
+
params: [serialized],
|
|
648
901
|
token: 'secret_sponsor',
|
|
649
902
|
})
|
|
650
903
|
expect(body.result).toBeUndefined()
|
|
651
|
-
expect(body.error
|
|
904
|
+
expect(body.error).toStrictEqual({
|
|
905
|
+
code: -32602,
|
|
906
|
+
data: { code: 'chain_id_unsupported' },
|
|
907
|
+
message: 'Unsupported chain id.',
|
|
908
|
+
})
|
|
909
|
+
expect(entries[0]?.rpc).toStrictEqual({
|
|
910
|
+
code: -32602,
|
|
911
|
+
dataCode: 'chain_id_unsupported',
|
|
912
|
+
errors: 1,
|
|
913
|
+
})
|
|
914
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
915
|
+
chainId: 999_999,
|
|
916
|
+
method: 'eth_signRawTransaction',
|
|
917
|
+
outcome: 'rejected',
|
|
918
|
+
payloadHash: Hash.keccak256(serialized),
|
|
919
|
+
reason: 'chain_id_unsupported',
|
|
920
|
+
rejections: 1,
|
|
921
|
+
})
|
|
922
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
652
923
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
653
924
|
})
|
|
654
925
|
})
|
|
@@ -669,15 +940,6 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
669
940
|
nonce: '0x0',
|
|
670
941
|
} as const
|
|
671
942
|
|
|
672
|
-
function createApp(db: Db.Source = TestApp.database()) {
|
|
673
|
-
return TestApp.create({
|
|
674
|
-
auth: { keys },
|
|
675
|
-
db,
|
|
676
|
-
relay: { feePayer: { account: feePayerAccount } },
|
|
677
|
-
supportedChainIds: [Viem.chainId.mainnet],
|
|
678
|
-
})
|
|
679
|
-
}
|
|
680
|
-
|
|
681
943
|
/** Activates billing for the org so the gate reaches the limit checks. */
|
|
682
944
|
async function activate(db: ReturnType<typeof TestApp.database>, orgId = 'org_1') {
|
|
683
945
|
await StripeCustomers.create(db, { orgId, stripeCustomerId: `cus_gate_${orgId}` })
|
|
@@ -695,18 +957,23 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
695
957
|
const overCapFees = { gas: 1_000_000n, maxFeePerGas: 2_000_000_000_000n } as const
|
|
696
958
|
|
|
697
959
|
test('behavior: refuses mainnet sponsorship without a billing source', async () => {
|
|
698
|
-
const
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
960
|
+
const entries: Log.Entry[] = []
|
|
961
|
+
const body = await relayRequest(
|
|
962
|
+
createMainnetApp({ logger: (entry) => void entries.push(entry) }),
|
|
963
|
+
{
|
|
964
|
+
method: 'eth_signRawTransaction',
|
|
965
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
966
|
+
token: 'secret_sponsor_prod',
|
|
967
|
+
},
|
|
968
|
+
)
|
|
703
969
|
expect(body.error?.code).toBe(-32602)
|
|
704
970
|
expect(body.error?.message).toBe('Billing required.')
|
|
705
971
|
expect(body.error?.data).toStrictEqual({ code: 'billing_required' })
|
|
972
|
+
expectSponsorshipCode({ code: 'billing_required', entry: entries[0] })
|
|
706
973
|
})
|
|
707
974
|
|
|
708
975
|
test('behavior: returns the billing reason for sponsor fills', async () => {
|
|
709
|
-
const body = await relayRequest(
|
|
976
|
+
const body = await relayRequest(createMainnetApp(), {
|
|
710
977
|
method: 'eth_fillTransaction',
|
|
711
978
|
params: [fill],
|
|
712
979
|
token: 'secret_sponsor_prod',
|
|
@@ -718,6 +985,91 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
718
985
|
})
|
|
719
986
|
})
|
|
720
987
|
|
|
988
|
+
test('behavior: error capabilities retain sponsor fill attribution', async () => {
|
|
989
|
+
const entries: Log.Entry[] = []
|
|
990
|
+
const body = await relayRequest(
|
|
991
|
+
createMainnetApp({ logger: (entry) => void entries.push(entry) }),
|
|
992
|
+
{
|
|
993
|
+
method: 'eth_fillTransaction',
|
|
994
|
+
params: [
|
|
995
|
+
{
|
|
996
|
+
...fill,
|
|
997
|
+
capabilities: { balanceDiffs: false, errors: true },
|
|
998
|
+
},
|
|
999
|
+
],
|
|
1000
|
+
token: 'secret_sponsor_prod',
|
|
1001
|
+
},
|
|
1002
|
+
)
|
|
1003
|
+
type Result = {
|
|
1004
|
+
capabilities?: {
|
|
1005
|
+
error?: { errorName?: string | undefined; message?: string | undefined } | undefined
|
|
1006
|
+
sponsored?: boolean | undefined
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const result = body.result as unknown as Result | undefined
|
|
1010
|
+
|
|
1011
|
+
expect(body.error).toBeUndefined()
|
|
1012
|
+
expect(result?.capabilities).toMatchObject({
|
|
1013
|
+
error: { errorName: 'unknown', message: 'Billing required.' },
|
|
1014
|
+
sponsored: false,
|
|
1015
|
+
})
|
|
1016
|
+
expect(entries[0]?.level).toBe('warn')
|
|
1017
|
+
expect(entries[0]?.rpc).toBeUndefined()
|
|
1018
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
1019
|
+
chainId: Viem.chainId.mainnet,
|
|
1020
|
+
method: 'eth_fillTransaction',
|
|
1021
|
+
outcome: 'rejected',
|
|
1022
|
+
reason: 'billing_required',
|
|
1023
|
+
rejections: 1,
|
|
1024
|
+
})
|
|
1025
|
+
})
|
|
1026
|
+
|
|
1027
|
+
test('behavior: error capabilities hide sponsorship policy invariants', async () => {
|
|
1028
|
+
const entries: Log.Entry[] = []
|
|
1029
|
+
const app = TestApp.create({
|
|
1030
|
+
auth: {
|
|
1031
|
+
keys,
|
|
1032
|
+
overrides: {
|
|
1033
|
+
'ALL /rpc/sponsor': { apiKey: { scopes: [] } },
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
db: TestApp.database(),
|
|
1037
|
+
logger: (entry) => void entries.push(entry),
|
|
1038
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
1039
|
+
supportedChainIds: [Viem.chainId.mainnet],
|
|
1040
|
+
})
|
|
1041
|
+
|
|
1042
|
+
const body = await relayRequest(app, {
|
|
1043
|
+
method: 'eth_fillTransaction',
|
|
1044
|
+
params: [
|
|
1045
|
+
{
|
|
1046
|
+
...fill,
|
|
1047
|
+
capabilities: { balanceDiffs: false, errors: true },
|
|
1048
|
+
},
|
|
1049
|
+
],
|
|
1050
|
+
token: 'secret_unscoped',
|
|
1051
|
+
})
|
|
1052
|
+
|
|
1053
|
+
expect(body.error).toBeUndefined()
|
|
1054
|
+
expect(body.result).toMatchObject({
|
|
1055
|
+
capabilities: {
|
|
1056
|
+
error: { errorName: 'unknown', message: 'Internal error' },
|
|
1057
|
+
sponsored: false,
|
|
1058
|
+
},
|
|
1059
|
+
})
|
|
1060
|
+
expect(JSON.stringify(body)).not.toContain('ineligible API key')
|
|
1061
|
+
expect(entries[0]?.level).toBe('error')
|
|
1062
|
+
expect(entries[0]?.rpc).toBeUndefined()
|
|
1063
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
1064
|
+
chainId: Viem.chainId.mainnet,
|
|
1065
|
+
internalErrors: 1,
|
|
1066
|
+
method: 'eth_fillTransaction',
|
|
1067
|
+
outcome: 'rejected',
|
|
1068
|
+
reason: 'internal_error',
|
|
1069
|
+
rejections: 1,
|
|
1070
|
+
})
|
|
1071
|
+
})
|
|
1072
|
+
|
|
721
1073
|
test('behavior: relay fills still fall back to self-payment', async () => {
|
|
722
1074
|
const server = await Relay.createServer(
|
|
723
1075
|
RequestListener.fromFetchHandler(async (request) => {
|
|
@@ -766,7 +1118,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
766
1118
|
test('behavior: refuses mainnet sponsorship while billing is inactive', async () => {
|
|
767
1119
|
const db = TestApp.database()
|
|
768
1120
|
await StripeCustomers.create(db, { orgId: 'org_1', stripeCustomerId: 'cus_gate' })
|
|
769
|
-
const body = await relayRequest(
|
|
1121
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
770
1122
|
method: 'eth_signRawTransaction',
|
|
771
1123
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
|
|
772
1124
|
token: 'secret_sponsor_prod',
|
|
@@ -777,24 +1129,29 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
777
1129
|
|
|
778
1130
|
test('behavior: past-due billing refuses with its own reason', async () => {
|
|
779
1131
|
const db = TestApp.database()
|
|
1132
|
+
const entries: Log.Entry[] = []
|
|
780
1133
|
await activate(db)
|
|
781
1134
|
// An unpaid invoice parked the org; the caller must settle it, not attach a card.
|
|
782
1135
|
await StripeCustomers.setStatus(db, 'org_1', 'past_due')
|
|
783
|
-
const body = await relayRequest(
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
1136
|
+
const body = await relayRequest(
|
|
1137
|
+
createMainnetApp({ db, logger: (entry) => void entries.push(entry) }),
|
|
1138
|
+
{
|
|
1139
|
+
method: 'eth_signRawTransaction',
|
|
1140
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
1141
|
+
token: 'secret_sponsor_prod',
|
|
1142
|
+
},
|
|
1143
|
+
)
|
|
788
1144
|
expect(body.error?.code).toBe(-32602)
|
|
789
1145
|
expect(body.error?.message).toBe('Billing past due.')
|
|
790
1146
|
expect(body.error?.data).toStrictEqual({ code: 'billing_past_due' })
|
|
1147
|
+
expectSponsorshipCode({ code: 'billing_past_due', entry: entries[0] })
|
|
791
1148
|
})
|
|
792
1149
|
|
|
793
1150
|
test('behavior: active billing opens mainnet sponsorship and records it', async () => {
|
|
794
1151
|
const db = TestApp.database()
|
|
795
1152
|
await activate(db)
|
|
796
1153
|
|
|
797
|
-
const body = await relayRequest(
|
|
1154
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
798
1155
|
method: 'eth_signRawTransaction',
|
|
799
1156
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
800
1157
|
token: 'secret_sponsor_prod',
|
|
@@ -813,15 +1170,44 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
813
1170
|
|
|
814
1171
|
test('behavior: a sandbox key never sponsors mainnet, even with active billing', async () => {
|
|
815
1172
|
const db = TestApp.database()
|
|
1173
|
+
const entries: Log.Entry[] = []
|
|
816
1174
|
await activate(db) // org_1 is active…
|
|
817
|
-
const
|
|
1175
|
+
const app = TestApp.create({
|
|
1176
|
+
auth: { keys },
|
|
1177
|
+
db,
|
|
1178
|
+
logger: (entry) => void entries.push(entry),
|
|
1179
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
1180
|
+
supportedChainIds: [Viem.chainId.mainnet],
|
|
1181
|
+
})
|
|
1182
|
+
const serialized = await signSponsorable({
|
|
1183
|
+
chainId: Viem.chainId.mainnet,
|
|
1184
|
+
...halfDollarFees,
|
|
1185
|
+
})
|
|
1186
|
+
const body = await relayRequest(app, {
|
|
818
1187
|
method: 'eth_signRawTransaction',
|
|
819
|
-
params: [
|
|
1188
|
+
params: [serialized],
|
|
820
1189
|
token: 'secret_sponsor', // …but this key is sandbox.
|
|
821
1190
|
})
|
|
822
1191
|
// Refused for the environment, before the billing check reveals a reason.
|
|
823
|
-
expect(body.error
|
|
824
|
-
|
|
1192
|
+
expect(body.error).toStrictEqual({
|
|
1193
|
+
code: -32602,
|
|
1194
|
+
data: { code: 'production_api_key_required' },
|
|
1195
|
+
message: 'Sponsorship rejected.',
|
|
1196
|
+
})
|
|
1197
|
+
expect(entries[0]?.rpc).toStrictEqual({
|
|
1198
|
+
code: -32602,
|
|
1199
|
+
dataCode: 'production_api_key_required',
|
|
1200
|
+
errors: 1,
|
|
1201
|
+
})
|
|
1202
|
+
expect(entries[0]?.sponsorship).toStrictEqual({
|
|
1203
|
+
chainId: Viem.chainId.mainnet,
|
|
1204
|
+
method: 'eth_signRawTransaction',
|
|
1205
|
+
outcome: 'rejected',
|
|
1206
|
+
payloadHash: Hash.keccak256(serialized),
|
|
1207
|
+
reason: 'production_api_key_required',
|
|
1208
|
+
rejections: 1,
|
|
1209
|
+
})
|
|
1210
|
+
expect(JSON.stringify(entries[0])).not.toContain(serialized)
|
|
825
1211
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
826
1212
|
})
|
|
827
1213
|
|
|
@@ -829,7 +1215,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
829
1215
|
const db = TestApp.database()
|
|
830
1216
|
// org_1 is active; the production wildcard key belongs to org_2, which has nothing.
|
|
831
1217
|
await activate(db)
|
|
832
|
-
const body = await relayRequest(
|
|
1218
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
833
1219
|
method: 'eth_signRawTransaction',
|
|
834
1220
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
835
1221
|
token: 'secret_wildcard_prod',
|
|
@@ -840,15 +1226,20 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
840
1226
|
|
|
841
1227
|
test('behavior: refuses a transaction over the platform fee cap', async () => {
|
|
842
1228
|
const db = TestApp.database()
|
|
1229
|
+
const entries: Log.Entry[] = []
|
|
843
1230
|
await activate(db)
|
|
844
|
-
const body = await relayRequest(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1231
|
+
const body = await relayRequest(
|
|
1232
|
+
createMainnetApp({ db, logger: (entry) => void entries.push(entry) }),
|
|
1233
|
+
{
|
|
1234
|
+
method: 'eth_signRawTransaction',
|
|
1235
|
+
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...overCapFees })],
|
|
1236
|
+
token: 'secret_sponsor_prod',
|
|
1237
|
+
},
|
|
1238
|
+
)
|
|
849
1239
|
expect(body.error?.code).toBe(-32602)
|
|
850
1240
|
expect(body.error?.message).toBe('Transaction fee limit exceeded.')
|
|
851
1241
|
expect(body.error?.data).toStrictEqual({ code: 'tx_fee_limit_exceeded' })
|
|
1242
|
+
expectSponsorshipCode({ code: 'tx_fee_limit_exceeded', entry: entries[0] })
|
|
852
1243
|
})
|
|
853
1244
|
|
|
854
1245
|
test('behavior: the org fee limit tightens the platform cap but never loosens it', async () => {
|
|
@@ -856,7 +1247,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
856
1247
|
await activate(db)
|
|
857
1248
|
// Tighter than the platform default: $0.50 envelopes now refuse.
|
|
858
1249
|
await BillingSettings.upsert(db, { orgId: 'org_1', txFeeLimit: '0.10' })
|
|
859
|
-
const app =
|
|
1250
|
+
const app = createMainnetApp({ db })
|
|
860
1251
|
const tightened = await relayRequest(app, {
|
|
861
1252
|
method: 'eth_signRawTransaction',
|
|
862
1253
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
@@ -876,6 +1267,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
876
1267
|
|
|
877
1268
|
test('behavior: refuses fee tokens the verified list does not resolve to USD', async () => {
|
|
878
1269
|
const db = TestApp.database()
|
|
1270
|
+
const entries: Log.Entry[] = []
|
|
879
1271
|
await activate(db)
|
|
880
1272
|
// EURC is verified yet non-USD; fee math reads micro-USD, so it refuses.
|
|
881
1273
|
const eurc = `0x${'e0'.repeat(20)}` as const
|
|
@@ -883,7 +1275,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
883
1275
|
tokens: [{ address: eurc, currency: 'EUR', decimals: 6, name: 'Euro Coin', symbol: 'EURC' }],
|
|
884
1276
|
})
|
|
885
1277
|
|
|
886
|
-
const app =
|
|
1278
|
+
const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
|
|
887
1279
|
const request = async (feeToken: `0x${string}`) =>
|
|
888
1280
|
await relayRequest(app, {
|
|
889
1281
|
method: 'eth_signRawTransaction',
|
|
@@ -893,9 +1285,11 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
893
1285
|
const nonUsd = await request(eurc)
|
|
894
1286
|
expect(nonUsd.error?.message).toBe('Fee token unsupported.')
|
|
895
1287
|
expect(nonUsd.error?.data).toStrictEqual({ code: 'fee_token_unsupported' })
|
|
1288
|
+
expectSponsorshipCode({ code: 'fee_token_unsupported', entry: entries[0] })
|
|
896
1289
|
// Tokens absent from the verified list refuse the same way.
|
|
897
1290
|
const unverified = await request(`0x${'ab'.repeat(20)}`)
|
|
898
1291
|
expect(unverified.error?.data).toStrictEqual({ code: 'fee_token_unsupported' })
|
|
1292
|
+
expectSponsorshipCode({ code: 'fee_token_unsupported', entry: entries[1] })
|
|
899
1293
|
expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
|
|
900
1294
|
})
|
|
901
1295
|
|
|
@@ -903,7 +1297,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
903
1297
|
const db = TestApp.database()
|
|
904
1298
|
await activate(db)
|
|
905
1299
|
|
|
906
|
-
const body = await relayRequest(
|
|
1300
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
907
1301
|
method: 'eth_signRawTransaction',
|
|
908
1302
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
909
1303
|
token: 'secret_sponsor_prod',
|
|
@@ -915,6 +1309,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
915
1309
|
|
|
916
1310
|
test('behavior: refuses sponsorship over the period spend limit; raising restores', async () => {
|
|
917
1311
|
const db = TestApp.database()
|
|
1312
|
+
const entries: Log.Entry[] = []
|
|
918
1313
|
await activate(db)
|
|
919
1314
|
await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '1' })
|
|
920
1315
|
// $0.90 already finalized this window; a $0.50 cap would overshoot $1.
|
|
@@ -934,7 +1329,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
934
1329
|
finalizedAt: new Date().toISOString(),
|
|
935
1330
|
})
|
|
936
1331
|
|
|
937
|
-
const app =
|
|
1332
|
+
const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
|
|
938
1333
|
const request = async () =>
|
|
939
1334
|
await relayRequest(app, {
|
|
940
1335
|
method: 'eth_signRawTransaction',
|
|
@@ -944,6 +1339,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
944
1339
|
const refused = await request()
|
|
945
1340
|
expect(refused.error?.message).toBe('Spend limit exceeded.')
|
|
946
1341
|
expect(refused.error?.data).toStrictEqual({ code: 'spend_limit_exceeded' })
|
|
1342
|
+
expectSponsorshipCode({ code: 'spend_limit_exceeded', entry: entries[0] })
|
|
947
1343
|
|
|
948
1344
|
await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '10' })
|
|
949
1345
|
const restored = await request()
|
|
@@ -968,7 +1364,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
968
1364
|
transactionHash: `0x${'34'.repeat(32)}`,
|
|
969
1365
|
})
|
|
970
1366
|
|
|
971
|
-
const body = await relayRequest(
|
|
1367
|
+
const body = await relayRequest(createMainnetApp({ db }), {
|
|
972
1368
|
method: 'eth_signRawTransaction',
|
|
973
1369
|
params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
|
|
974
1370
|
token: 'secret_sponsor_prod',
|
|
@@ -985,7 +1381,7 @@ describe('behavior: mainnet billing gate', () => {
|
|
|
985
1381
|
await activate(seed)
|
|
986
1382
|
// Limit fits exactly two $0.50 sponsorships.
|
|
987
1383
|
await BillingSettings.upsert(seed, { orgId: 'org_1', spendLimit: '1' })
|
|
988
|
-
const app =
|
|
1384
|
+
const app = createMainnetApp({ db })
|
|
989
1385
|
// Distinct nonces → distinct envelopes → distinct rows, fired together.
|
|
990
1386
|
const results = await Promise.all(
|
|
991
1387
|
Array.from({ length: 6 }, async (_, nonce) =>
|
|
@@ -1339,3 +1735,38 @@ describe.runIf(TestStripe.secretKey)(
|
|
|
1339
1735
|
)
|
|
1340
1736
|
},
|
|
1341
1737
|
)
|
|
1738
|
+
|
|
1739
|
+
function createMainnetApp(options: createMainnetApp.Options = {}) {
|
|
1740
|
+
return TestApp.create({
|
|
1741
|
+
auth: { keys },
|
|
1742
|
+
db: options.db ?? TestApp.database(),
|
|
1743
|
+
...(options.logger ? { logger: options.logger } : {}),
|
|
1744
|
+
relay: { feePayer: { account: feePayerAccount } },
|
|
1745
|
+
supportedChainIds: [Viem.chainId.mainnet],
|
|
1746
|
+
})
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
declare namespace createMainnetApp {
|
|
1750
|
+
/** Mainnet sponsorship test app options. */
|
|
1751
|
+
type Options = {
|
|
1752
|
+
/** Database source. */
|
|
1753
|
+
db?: Db.Source | undefined
|
|
1754
|
+
/** Structured request log sink. */
|
|
1755
|
+
logger?: Log.Emit | undefined
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
function expectSponsorshipCode(options: expectSponsorshipCode.Options) {
|
|
1760
|
+
expect(options.entry?.rpc?.dataCode).toBe(options.code)
|
|
1761
|
+
expect(options.entry?.sponsorship?.reason).toBe(options.code)
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
declare namespace expectSponsorshipCode {
|
|
1765
|
+
/** Expected canonical sponsorship code. */
|
|
1766
|
+
type Options = {
|
|
1767
|
+
/** Expected client and internal code. */
|
|
1768
|
+
code: Log.SponsorshipReason
|
|
1769
|
+
/** Structured request log entry. */
|
|
1770
|
+
entry: Log.Entry | undefined
|
|
1771
|
+
}
|
|
1772
|
+
}
|