tapimo 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +6396 -4575
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +39 -4
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +15 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +7 -0
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +176 -78
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +84 -4
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +123 -9
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +60 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +4 -2
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +90 -90
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +71 -71
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +16 -16
- package/dist/apps/Zones.js +4 -4
- package/dist/apps/data/App.d.ts +1699 -749
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +58 -9
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +62 -0
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
- package/dist/apps/data/ZoneSelection.js +44 -0
- package/dist/apps/data/ZoneSelection.js.map +1 -0
- package/dist/apps/data/routes/activities.d.ts +2417 -50
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1896 -1293
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +471 -340
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +12 -12
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +44 -17
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +42 -42
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +22 -12
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +179 -179
- package/dist/apps/data/routes/earn.d.ts +144 -19
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +160 -28
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +719 -13
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +16 -13
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +9 -11
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +34 -34
- package/dist/apps/data/routes/receipts.d.ts +363 -263
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +29 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.js +24 -10
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +16 -15
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +112 -98
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +85 -35
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +38 -18
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +25 -21
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
- package/dist/apps/data/routes/webhooks.d.ts +15 -15
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +2 -2
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +32 -32
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +38 -27
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.js +5 -4
- package/dist/apps/funding/routes/chains.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +24 -19
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/providers.d.ts +13 -13
- package/dist/apps/funding/routes/providers.d.ts.map +1 -1
- package/dist/apps/funding/routes/providers.js +3 -2
- package/dist/apps/funding/routes/providers.js.map +1 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
- package/dist/apps/funding/routes/quotes.js +2 -2
- package/dist/apps/funding/routes/quotes.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +60 -48
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +27 -19
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +4558 -3700
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +19 -6
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +786 -175
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +312 -34
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +103 -30
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +91 -32
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/faucet.d.ts.map +1 -1
- package/dist/apps/management/routes/faucet.js +23 -12
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +46 -13
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +79 -29
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +120 -75
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +100 -41
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +5 -5
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +14 -10
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +99 -78
- package/dist/apps/management/routes/members.d.ts.map +1 -1
- package/dist/apps/management/routes/members.js +37 -18
- package/dist/apps/management/routes/members.js.map +1 -1
- package/dist/apps/management/routes/orgs.d.ts +48 -8
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +48 -19
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +108 -46
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +72 -21
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/scopes.d.ts.map +1 -1
- package/dist/apps/management/routes/scopes.js +8 -5
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +82 -82
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +41 -31
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +35 -7
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +36 -17
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +200 -183
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +80 -35
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +12 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +52 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +26 -3
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +24 -5
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +5 -0
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
- package/dist/db/tables/webhookDeliveries.js +10 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -1
- package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
- package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
- package/dist/db/tables/webhookQueueCompletions.js +32 -0
- package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
- package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +68 -47
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +29 -5
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +19 -6
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +11 -7
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +43 -4
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +167 -0
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +3 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +30 -24
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +140 -41
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +14 -9
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +16 -5
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +11 -10
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +14 -9
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +28 -6
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +121 -25
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +2 -0
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +23 -6
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +29 -12
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +37 -20
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/Deposit.d.ts +2 -2
- package/dist/internal/funding/Deposit.d.ts.map +1 -1
- package/dist/internal/funding/Deposit.js +9 -8
- package/dist/internal/funding/Deposit.js.map +1 -1
- package/dist/internal/funding/DepositAddress.d.ts +4 -4
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
- package/dist/internal/funding/DepositAddress.js +9 -8
- package/dist/internal/funding/DepositAddress.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +68 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +42 -20
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +13 -12
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +23 -21
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +38 -0
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
- package/dist/internal/funding/providers/stargate.js +277 -0
- package/dist/internal/funding/providers/stargate.js.map +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +3 -3
- package/src/App.test.ts +148 -0
- package/src/App.ts +45 -4
- package/src/Assets.test.ts +18 -0
- package/src/Assets.ts +22 -0
- package/src/Client.test-d.ts +311 -16
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +143 -0
- package/src/admin/apps/earn-vaults.ts +84 -7
- package/src/admin/apps/organizations.ts +6 -2
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/routes/api-keys.tsx +125 -2
- package/src/admin/ui.generated.ts +71 -71
- package/src/apps/Zones.test.ts +4 -4
- package/src/apps/Zones.ts +4 -4
- package/src/apps/composition.test.ts +1 -1
- package/src/apps/data/App.test.ts +72 -0
- package/src/apps/data/App.ts +58 -10
- package/src/apps/data/ZoneSelection.test.ts +196 -0
- package/src/apps/data/ZoneSelection.ts +108 -0
- package/src/apps/data/routes/activities.test.ts +1843 -2
- package/src/apps/data/routes/activities.ts +2211 -1388
- package/src/apps/data/routes/balances.ts +134 -98
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +36 -17
- package/src/apps/data/routes/earn.test.ts +187 -25
- package/src/apps/data/routes/earn.ts +228 -32
- package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
- package/src/apps/data/routes/exchanges.test.ts +31 -1
- package/src/apps/data/routes/exchanges.ts +19 -15
- package/src/apps/data/routes/fee-amm.ts +18 -11
- package/src/apps/data/routes/receipts.ts +48 -17
- package/src/apps/data/routes/rpc.test.ts +75 -0
- package/src/apps/data/routes/rpc.ts +23 -9
- package/src/apps/data/routes/tokenlist.ts +21 -18
- package/src/apps/data/routes/tokens.test.ts +607 -0
- package/src/apps/data/routes/tokens.ts +312 -231
- package/src/apps/data/routes/transactions.ts +69 -30
- package/src/apps/data/routes/transfers.test.ts +424 -3
- package/src/apps/data/routes/transfers.ts +57 -36
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/webhooks.ts +6 -2
- package/src/apps/data/routes/zones.test.ts +21 -15
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/chains.test.ts +211 -7
- package/src/apps/funding/routes/chains.ts +19 -12
- package/src/apps/funding/routes/deposit-addresses.test.ts +416 -0
- package/src/apps/funding/routes/deposit-addresses.ts +101 -84
- package/src/apps/funding/routes/providers.ts +9 -5
- package/src/apps/funding/routes/quotes.test.ts +42 -0
- package/src/apps/funding/routes/quotes.ts +8 -5
- package/src/apps/funding/routes/transfers.test.ts +430 -40
- package/src/apps/funding/routes/transfers.ts +76 -59
- package/src/apps/management/Billing.test.ts +26 -0
- package/src/apps/management/Billing.ts +24 -7
- package/src/apps/management/routes/api-keys.test.ts +398 -0
- package/src/apps/management/routes/api-keys.ts +481 -145
- package/src/apps/management/routes/billing.test.ts +209 -0
- package/src/apps/management/routes/billing.ts +254 -177
- package/src/apps/management/routes/faucet.test.ts +39 -0
- package/src/apps/management/routes/faucet.ts +75 -41
- package/src/apps/management/routes/invitations.test.ts +216 -0
- package/src/apps/management/routes/invitations.ts +186 -109
- package/src/apps/management/routes/invite-links.test.ts +263 -1
- package/src/apps/management/routes/invite-links.ts +295 -214
- package/src/apps/management/routes/me.test.ts +49 -0
- package/src/apps/management/routes/me.ts +42 -32
- package/src/apps/management/routes/members.test.ts +124 -1
- package/src/apps/management/routes/members.ts +81 -51
- package/src/apps/management/routes/orgs.test.ts +176 -0
- package/src/apps/management/routes/orgs.ts +101 -59
- package/src/apps/management/routes/projects.test.ts +183 -0
- package/src/apps/management/routes/projects.ts +124 -60
- package/src/apps/management/routes/scopes.test.ts +44 -0
- package/src/apps/management/routes/scopes.ts +37 -28
- package/src/apps/management/routes/usage.test.ts +92 -0
- package/src/apps/management/routes/usage.ts +186 -151
- package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
- package/src/apps/management/routes/verified-token-requests.ts +166 -133
- package/src/apps/management/routes/webhooks.test.ts +234 -0
- package/src/apps/management/routes/webhooks.ts +191 -78
- package/src/apps/mpp/internal/Adapter.ts +13 -1
- package/src/db/Db.test.ts +41 -0
- package/src/db/Db.ts +75 -1
- package/src/db/Schema.ts +33 -5
- package/src/db/tables/earnVaults.test.ts +22 -0
- package/src/db/tables/earnVaults.ts +11 -1
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/db/tables/webhookDeliveries.ts +13 -0
- package/src/db/tables/webhookQueueCompletions.ts +55 -0
- package/src/db/tables/webhookQueueEvents.ts +95 -61
- package/src/db/tables/webhookSubscriptions.ts +45 -6
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +35 -9
- package/src/internal/Cache.ts +14 -7
- package/src/internal/EarnVaults.capabilities.test.ts +33 -0
- package/src/internal/EarnVaults.test.ts +79 -0
- package/src/internal/EarnVaults.ts +277 -0
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +20 -5
- package/src/internal/OpenApi.ts +177 -51
- package/src/internal/Response.test.ts +95 -0
- package/src/internal/Response.ts +41 -3
- package/src/internal/Schema.test.ts +18 -0
- package/src/internal/Schema.ts +19 -9
- package/src/internal/Store.test.ts +364 -0
- package/src/internal/Store.ts +153 -27
- package/src/internal/Tidx.test.ts +21 -1
- package/src/internal/Tidx.ts +23 -6
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/Webhooks.test.ts +122 -8
- package/src/internal/Webhooks.ts +59 -29
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/Deposit.ts +71 -64
- package/src/internal/funding/DepositAddress.ts +50 -43
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +246 -170
- package/src/internal/funding/Transfer.ts +133 -110
- package/src/internal/funding/providers/index.test.ts +22 -0
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/stargate.test.ts +163 -0
- package/src/internal/funding/providers/stargate.ts +409 -0
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/providers/index.test.ts +1 -0
- package/src/providers/index.ts +9 -0
package/src/apps/Zones.test.ts
CHANGED
|
@@ -5,11 +5,11 @@ describe('chains', () => {
|
|
|
5
5
|
expect(Zones.chains).toMatchObject([
|
|
6
6
|
{
|
|
7
7
|
contracts: {
|
|
8
|
-
messenger: { address: '
|
|
9
|
-
portal: { address: '
|
|
10
|
-
verifier: { address: '
|
|
8
|
+
messenger: { address: '0x5A4d000000000000000000000000000000000000' },
|
|
9
|
+
portal: { address: '0x5Ad0000000000000000000000000000000000003' },
|
|
10
|
+
verifier: { address: '0x5a56000000000000000000000000000000000000' },
|
|
11
11
|
},
|
|
12
|
-
id:
|
|
12
|
+
id: 1_424_310_003,
|
|
13
13
|
name: 'zone-moderato-internal',
|
|
14
14
|
rpcUrls: {
|
|
15
15
|
default: { http: ['https://zone-internal-rpc.testnet.tempo.xyz'] },
|
package/src/apps/Zones.ts
CHANGED
|
@@ -6,11 +6,11 @@ export const zoneModeratoInternal = defineChain({
|
|
|
6
6
|
...tempoTestnet,
|
|
7
7
|
contracts: {
|
|
8
8
|
...tempoTestnet.contracts,
|
|
9
|
-
messenger: { address: '
|
|
10
|
-
portal: { address: '
|
|
11
|
-
verifier: { address: '
|
|
9
|
+
messenger: { address: '0x5A4d000000000000000000000000000000000000' },
|
|
10
|
+
portal: { address: '0x5Ad0000000000000000000000000000000000003' },
|
|
11
|
+
verifier: { address: '0x5a56000000000000000000000000000000000000' },
|
|
12
12
|
},
|
|
13
|
-
id:
|
|
13
|
+
id: 1_424_310_003,
|
|
14
14
|
name: 'zone-moderato-internal',
|
|
15
15
|
rpcUrls: {
|
|
16
16
|
default: { http: ['https://zone-internal-rpc.testnet.tempo.xyz'] },
|
|
@@ -149,14 +149,54 @@ describe('MPP session management', () => {
|
|
|
149
149
|
PaymentRequest.serialize({ _mppx_scope: 'GET /v1/scopes' }),
|
|
150
150
|
)
|
|
151
151
|
})
|
|
152
|
+
|
|
153
|
+
test('applies POST auth overrides to QUERY aliases', async () => {
|
|
154
|
+
const app = TestApp.create({
|
|
155
|
+
auth: {
|
|
156
|
+
overrides: {
|
|
157
|
+
'POST /v1/exchange/quotes': { mpp: false, public: false },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const post = await app.request('/v1/exchange/quotes', { method: 'POST' })
|
|
163
|
+
const query = await app.request('/v1/exchange/quotes', { method: 'QUERY' })
|
|
164
|
+
|
|
165
|
+
expect([post.status, query.status]).toEqual([401, 401])
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test('prefers an explicit QUERY auth override', async () => {
|
|
169
|
+
const app = TestApp.create({
|
|
170
|
+
auth: {
|
|
171
|
+
overrides: {
|
|
172
|
+
'POST /v1/exchange/quotes': { mpp: false, public: false },
|
|
173
|
+
'QUERY /v1/exchange/quotes': false,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const post = await app.request('/v1/exchange/quotes', { method: 'POST' })
|
|
179
|
+
const query = await app.request('/v1/exchange/quotes', { method: 'QUERY' })
|
|
180
|
+
|
|
181
|
+
expect([post.status, query.status]).toEqual([401, 400])
|
|
182
|
+
})
|
|
152
183
|
})
|
|
153
184
|
|
|
154
185
|
describe('zone chain gate', () => {
|
|
186
|
+
const legacyModerato = 1_424_310_001
|
|
187
|
+
const moderato = 1_424_310_003
|
|
155
188
|
/** A consumer-supplied zone chain id (the API never derives these). */
|
|
156
189
|
const zone = 421_700_001
|
|
157
190
|
/** A second zone, isolating per-zone grants. */
|
|
158
191
|
const zoneB = 4_217_000_002
|
|
159
192
|
|
|
193
|
+
const legacyModeratoReader = {
|
|
194
|
+
id: 'key_legacy_moderato',
|
|
195
|
+
orgId: 'org_test',
|
|
196
|
+
scopes: ['data:read', 'indexer:query', `zone:${legacyModerato}:read`],
|
|
197
|
+
token: 'secret_legacy_moderato',
|
|
198
|
+
} satisfies TestApp.kvStore.Key
|
|
199
|
+
|
|
160
200
|
function zoneOptions(chainId: number) {
|
|
161
201
|
return TestApp.zone({
|
|
162
202
|
chainId,
|
|
@@ -261,6 +301,38 @@ describe('zone chain gate', () => {
|
|
|
261
301
|
expect(response.status).toBe(200)
|
|
262
302
|
})
|
|
263
303
|
|
|
304
|
+
test('the legacy Moderato id and read scope route to current upstreams', async () => {
|
|
305
|
+
const fetch = vi
|
|
306
|
+
.spyOn(globalThis, 'fetch')
|
|
307
|
+
.mockResolvedValueOnce(Response.json({ id: 1, jsonrpc: '2.0', result: '0x54e89ac3' }))
|
|
308
|
+
.mockResolvedValueOnce(Response.json({ columns: [], ok: true, row_count: 0, rows: [] }))
|
|
309
|
+
try {
|
|
310
|
+
const app = TestApp.create({
|
|
311
|
+
auth: { keys: [legacyModeratoReader] },
|
|
312
|
+
rpc: { url: (chainId) => `https://${chainId}.rpc.test` },
|
|
313
|
+
tidx: { baseUrl: (chainId) => `https://${chainId}.tidx.test` },
|
|
314
|
+
zones: true,
|
|
315
|
+
})
|
|
316
|
+
const rpc = await app.request(`/rpc/${legacyModerato}`, {
|
|
317
|
+
body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: 'eth_chainId' }),
|
|
318
|
+
headers: as(legacyModeratoReader).headers,
|
|
319
|
+
method: 'POST',
|
|
320
|
+
})
|
|
321
|
+
const tidx = await app.request(
|
|
322
|
+
`/v1/indexer/query?chainId=${legacyModerato}&sql=select%201`,
|
|
323
|
+
as(legacyModeratoReader),
|
|
324
|
+
)
|
|
325
|
+
const tidxUpstream = new URL((fetch.mock.calls[1]![0] as Request).url)
|
|
326
|
+
|
|
327
|
+
expect([rpc.status, tidx.status]).toEqual([200, 200])
|
|
328
|
+
expect((fetch.mock.calls[0]![0] as Request).url).toBe(`https://${moderato}.rpc.test/`)
|
|
329
|
+
expect(tidxUpstream.origin).toBe(`https://${moderato}.tidx.test`)
|
|
330
|
+
expect(tidxUpstream.searchParams.get('chainId')).toBe(String(moderato))
|
|
331
|
+
} finally {
|
|
332
|
+
fetch.mockRestore()
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
|
|
264
336
|
test('a Zone write scope reads Zone data', async () => {
|
|
265
337
|
const response = await zoneApp().request(`/v1/tokenlist?chainId=${zone}`, as(zoneWriter))
|
|
266
338
|
expect(response.status).toBe(200)
|
package/src/apps/data/App.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { matchedRoutes } from 'hono/route'
|
|
|
3
3
|
import { ZoneRpcAuthentication } from 'ox/tempo'
|
|
4
4
|
import * as z from 'zod/mini'
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as Assets from '../../Assets.js'
|
|
7
7
|
import type * as App from '../../App.js'
|
|
8
8
|
import * as Auth from '../../internal/Auth.js'
|
|
9
9
|
import * as EdgeCache from '../../internal/EdgeCache.js'
|
|
@@ -17,6 +17,7 @@ import * as Scope from '../../Scope.js'
|
|
|
17
17
|
import * as Metadata from '../metadata.js'
|
|
18
18
|
|
|
19
19
|
import type * as FxOracle from './FxOracle.js'
|
|
20
|
+
import * as ZoneSelection from './ZoneSelection.js'
|
|
20
21
|
|
|
21
22
|
import { transactions as transactionActivities } from './routes/activities.js'
|
|
22
23
|
import { addresses } from './routes/addresses.js'
|
|
@@ -58,9 +59,17 @@ export function data(options: data.Options = {}) {
|
|
|
58
59
|
const dataRouteHandlers = new Set<unknown>()
|
|
59
60
|
|
|
60
61
|
const getTidx = Tidx.createGetClient({ tidx })
|
|
62
|
+
const addresses_routes = addresses({ fx: options.fx })
|
|
61
63
|
const earn_routes = earn({ fx: options.fx })
|
|
62
64
|
const indexer_routes = indexer()
|
|
65
|
+
const transactionActivities_routes = transactionActivities({ fx: options.fx })
|
|
63
66
|
const indexerRouteHandlers = new Set(indexer_routes.routes.map((route) => route.handler))
|
|
67
|
+
const inferredZoneRouteHandlers = new Set([
|
|
68
|
+
...addresses_routes.routes
|
|
69
|
+
.filter((route) => route.path === '/v1/addresses/:address/activities')
|
|
70
|
+
.map((route) => route.handler),
|
|
71
|
+
...transactionActivities_routes.routes.map((route) => route.handler),
|
|
72
|
+
])
|
|
64
73
|
const rpcOnlyRouteHandlers = new Set(
|
|
65
74
|
earn_routes.routes
|
|
66
75
|
.filter((route) => route.path === '/v1/earn/vaults/:vaultId/positions/:address')
|
|
@@ -106,6 +115,7 @@ export function data(options: data.Options = {}) {
|
|
|
106
115
|
c,
|
|
107
116
|
defaultChainId,
|
|
108
117
|
handlers: dataRouteHandlers,
|
|
118
|
+
inferredZoneHandlers: inferredZoneRouteHandlers,
|
|
109
119
|
indexerHandlers: indexerRouteHandlers,
|
|
110
120
|
rpcOnlyHandlers: rpcOnlyRouteHandlers,
|
|
111
121
|
})
|
|
@@ -135,6 +145,30 @@ export function data(options: data.Options = {}) {
|
|
|
135
145
|
c.set('supportedChainIds', narrowedChainIds)
|
|
136
146
|
if (!narrowedChainIds.has(selection.chainId))
|
|
137
147
|
return Response.unsupportedChainId(c, selection.chainId, narrowedChainIds)
|
|
148
|
+
if (selection.inferredZones) {
|
|
149
|
+
if (principal?.type !== 'api_key')
|
|
150
|
+
return Response.error(c, {
|
|
151
|
+
code: 'api_key_forbidden',
|
|
152
|
+
message: '`include=zones` requires an API key with readable Zone scopes.',
|
|
153
|
+
status: 403,
|
|
154
|
+
})
|
|
155
|
+
const zoneChainIds = ZoneSelection.readableChainIds({
|
|
156
|
+
parentChainId: selection.chainId,
|
|
157
|
+
principal,
|
|
158
|
+
rpc: rpc_config,
|
|
159
|
+
tidx: tidx_config,
|
|
160
|
+
zones,
|
|
161
|
+
})
|
|
162
|
+
if (zoneChainIds.length === 0)
|
|
163
|
+
return Response.error(c, {
|
|
164
|
+
code: 'api_key_forbidden',
|
|
165
|
+
message: 'The API key has no readable configured Zones.',
|
|
166
|
+
status: 403,
|
|
167
|
+
})
|
|
168
|
+
c.set('supportedChainIds', new Set([selection.chainId, ...zoneChainIds]))
|
|
169
|
+
c.set('zoneChainIds', zoneChainIds)
|
|
170
|
+
return next()
|
|
171
|
+
}
|
|
138
172
|
c.set('chainId', selection.chainId)
|
|
139
173
|
return next()
|
|
140
174
|
})
|
|
@@ -147,10 +181,12 @@ export function data(options: data.Options = {}) {
|
|
|
147
181
|
c,
|
|
148
182
|
defaultChainId: c.get('chainId'),
|
|
149
183
|
handlers: dataRouteHandlers,
|
|
184
|
+
inferredZoneHandlers: inferredZoneRouteHandlers,
|
|
150
185
|
indexerHandlers: indexerRouteHandlers,
|
|
151
186
|
rpcOnlyHandlers: rpcOnlyRouteHandlers,
|
|
152
187
|
})
|
|
153
188
|
if (!selection.matched) return next()
|
|
189
|
+
if (selection.inferredZones) return next()
|
|
154
190
|
const chainId = c.get('chainId')
|
|
155
191
|
if (!zones.has(chainId)) return next()
|
|
156
192
|
|
|
@@ -165,8 +201,8 @@ export function data(options: data.Options = {}) {
|
|
|
165
201
|
return Response.error(c, {
|
|
166
202
|
code: 'api_key_forbidden',
|
|
167
203
|
message: selection.rpc
|
|
168
|
-
? `Chain
|
|
169
|
-
: `Chain
|
|
204
|
+
? `Chain ID ${chainId} is a Zone. Use an API key granting \`zone:${chainId}:read\` or \`zone:${chainId}:write\`, or pass a Zone token via \`X-Authorization-Token\`.`
|
|
205
|
+
: `Chain ID ${chainId} is a Zone. Use an API key granting \`zone:${chainId}:read\` or \`zone:${chainId}:write\`.`,
|
|
170
206
|
status: 403,
|
|
171
207
|
})
|
|
172
208
|
|
|
@@ -187,10 +223,12 @@ export function data(options: data.Options = {}) {
|
|
|
187
223
|
c,
|
|
188
224
|
defaultChainId: c.get('chainId'),
|
|
189
225
|
handlers: dataRouteHandlers,
|
|
226
|
+
inferredZoneHandlers: inferredZoneRouteHandlers,
|
|
190
227
|
indexerHandlers: indexerRouteHandlers,
|
|
191
228
|
rpcOnlyHandlers: rpcOnlyRouteHandlers,
|
|
192
229
|
})
|
|
193
|
-
if (!selection.matched || !Viem.isMainnet(c.get('chainId')))
|
|
230
|
+
if (!selection.matched || selection.inferredZones || !Viem.isMainnet(c.get('chainId')))
|
|
231
|
+
return next()
|
|
194
232
|
|
|
195
233
|
return Response.error(c, {
|
|
196
234
|
code: 'api_key_forbidden',
|
|
@@ -211,7 +249,7 @@ export function data(options: data.Options = {}) {
|
|
|
211
249
|
'Content-Type': asset.contentType,
|
|
212
250
|
})
|
|
213
251
|
})
|
|
214
|
-
.route('/',
|
|
252
|
+
.route('/', addresses_routes)
|
|
215
253
|
.route('/', blocks())
|
|
216
254
|
.route('/', earn_routes)
|
|
217
255
|
.route('/', exchanges({ fx: options.fx }))
|
|
@@ -221,7 +259,7 @@ export function data(options: data.Options = {}) {
|
|
|
221
259
|
.route('/', tokenlist())
|
|
222
260
|
.route('/', tokens())
|
|
223
261
|
.route('/', transactions())
|
|
224
|
-
.route('/',
|
|
262
|
+
.route('/', transactionActivities_routes)
|
|
225
263
|
.route('/', transfers({ fx: options.fx }))
|
|
226
264
|
.route('/', verifiedTokens())
|
|
227
265
|
.route(
|
|
@@ -240,14 +278,16 @@ export function data(options: data.Options = {}) {
|
|
|
240
278
|
c,
|
|
241
279
|
defaultChainId: c.get('chainId'),
|
|
242
280
|
handlers: dataRouteHandlers,
|
|
281
|
+
inferredZoneHandlers: inferredZoneRouteHandlers,
|
|
243
282
|
indexerHandlers: indexerRouteHandlers,
|
|
244
283
|
rpcOnlyHandlers: rpcOnlyRouteHandlers,
|
|
245
284
|
})
|
|
246
|
-
if (selection.matched && !selection.conflict && !selection.invalid)
|
|
285
|
+
if (selection.matched && !selection.conflict && !selection.inferredZones && !selection.invalid)
|
|
247
286
|
c.set('chainId', selection.chainId)
|
|
248
287
|
return (
|
|
249
288
|
selection.matched &&
|
|
250
289
|
!selection.conflict &&
|
|
290
|
+
!selection.inferredZones &&
|
|
251
291
|
!selection.invalid &&
|
|
252
292
|
!c.get('zones').has(selection.chainId)
|
|
253
293
|
)
|
|
@@ -302,6 +342,7 @@ function resolveChainSelector(options: {
|
|
|
302
342
|
c: Context<App.Environment>
|
|
303
343
|
defaultChainId: Viem.ChainId
|
|
304
344
|
handlers: ReadonlySet<unknown>
|
|
345
|
+
inferredZoneHandlers: ReadonlySet<unknown>
|
|
305
346
|
indexerHandlers: ReadonlySet<unknown>
|
|
306
347
|
rpcOnlyHandlers: ReadonlySet<unknown>
|
|
307
348
|
}) {
|
|
@@ -310,9 +351,11 @@ function resolveChainSelector(options: {
|
|
|
310
351
|
let rpc = false
|
|
311
352
|
let rpcOnly = false
|
|
312
353
|
let indexer = false
|
|
354
|
+
let inferredZonesAllowed = false
|
|
313
355
|
for (const route of matchedRoutes(options.c)) {
|
|
314
356
|
if (!options.handlers.has(route.handler)) continue
|
|
315
357
|
matched = true
|
|
358
|
+
if (options.inferredZoneHandlers.has(route.handler)) inferredZonesAllowed = true
|
|
316
359
|
if (options.indexerHandlers.has(route.handler)) indexer = true
|
|
317
360
|
if (options.rpcOnlyHandlers.has(route.handler)) rpcOnly = true
|
|
318
361
|
const selector = pathChainSelector(route.path, options.c.req.path)
|
|
@@ -326,6 +369,7 @@ function resolveChainSelector(options: {
|
|
|
326
369
|
return {
|
|
327
370
|
chainId: options.defaultChainId,
|
|
328
371
|
conflict: false,
|
|
372
|
+
inferredZones: false,
|
|
329
373
|
indexer: false,
|
|
330
374
|
invalid: false,
|
|
331
375
|
matched: false,
|
|
@@ -334,6 +378,10 @@ function resolveChainSelector(options: {
|
|
|
334
378
|
}
|
|
335
379
|
|
|
336
380
|
const search = new URL(options.c.req.url).searchParams
|
|
381
|
+
const include = inferredZonesAllowed
|
|
382
|
+
? search.getAll('include').flatMap((value) => value.split(',').map((part) => part.trim()))
|
|
383
|
+
: []
|
|
384
|
+
const inferredZones = include.includes('zones')
|
|
337
385
|
const raw = [
|
|
338
386
|
...(path === undefined ? [] : [path]),
|
|
339
387
|
...(rpc ? [] : search.getAll('chainId')),
|
|
@@ -344,6 +392,7 @@ function resolveChainSelector(options: {
|
|
|
344
392
|
return {
|
|
345
393
|
chainId: chainIds[0] ?? options.defaultChainId,
|
|
346
394
|
conflict: chainIds.length > 1,
|
|
395
|
+
inferredZones,
|
|
347
396
|
indexer,
|
|
348
397
|
invalid: parsed.some((result) => !result.success),
|
|
349
398
|
matched: true,
|
|
@@ -473,7 +522,6 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
|
|
|
473
522
|
const { assets, basePath, origin } = options
|
|
474
523
|
if (!assets) return () => undefined
|
|
475
524
|
const getAsset: App.GetAsset = async (chainId, path) => {
|
|
476
|
-
const pathname = Path.join(basePath, 'assets', String(chainId), path)
|
|
477
525
|
// `path` may be absolute (`Path.join` returns a leading slash); strip it so
|
|
478
526
|
// the key is `:chainId/:path`, not `:chainId//:path`.
|
|
479
527
|
const key = `${chainId}/${path.replace(/^\/+/, '')}`
|
|
@@ -483,7 +531,7 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
|
|
|
483
531
|
response: new globalThis.Response(asset.body, {
|
|
484
532
|
headers: { 'Content-Type': asset.contentType },
|
|
485
533
|
}),
|
|
486
|
-
uri:
|
|
534
|
+
uri: Assets.url({ basePath, chainId, origin, path }),
|
|
487
535
|
}
|
|
488
536
|
}
|
|
489
537
|
const list = assets.list
|
|
@@ -492,7 +540,7 @@ function createGetAsset(options: createGetAsset.Options): App.GetAsset {
|
|
|
492
540
|
const prefix = `${chainId}/${path.replace(/^\/+/, '')}`
|
|
493
541
|
return (await list(prefix)).map((key) => ({
|
|
494
542
|
key,
|
|
495
|
-
uri:
|
|
543
|
+
uri: Assets.url({ basePath, chainId, origin, path: key.slice(String(chainId).length + 1) }),
|
|
496
544
|
}))
|
|
497
545
|
}
|
|
498
546
|
return getAsset
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import * as ApiKey from '../../ApiKey.js'
|
|
2
|
+
import * as App from '../../App.js'
|
|
3
|
+
import * as Db from '../../db/Db.js'
|
|
4
|
+
import type * as Auth from '../../internal/Auth.js'
|
|
5
|
+
import * as Viem from '../../internal/Viem.js'
|
|
6
|
+
import * as Zones from '../Zones.js'
|
|
7
|
+
|
|
8
|
+
import * as Data from './App.js'
|
|
9
|
+
import * as ZoneSelection from './ZoneSelection.js'
|
|
10
|
+
import * as Activities from './routes/activities.js'
|
|
11
|
+
|
|
12
|
+
describe('transaction activity Zone query', () => {
|
|
13
|
+
test('accepts the Zones include with an optional parent chain', () => {
|
|
14
|
+
expect(
|
|
15
|
+
Activities.schema.getTransactionActivities.Query.parse({ include: 'zones' }).include,
|
|
16
|
+
).toStrictEqual(['zones'])
|
|
17
|
+
expect(
|
|
18
|
+
Activities.schema.getTransactionActivities.Query.parse({
|
|
19
|
+
chainId: '4217',
|
|
20
|
+
include: 'zones',
|
|
21
|
+
}),
|
|
22
|
+
).toMatchObject({ chainId: 4217, include: ['zones'] })
|
|
23
|
+
expect(
|
|
24
|
+
Activities.schema.getTransactionActivities.Query.safeParse({ includeZones: 'true' }).success,
|
|
25
|
+
).toBe(false)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('opts in only activity routes and accepts a parent chain', async () => {
|
|
29
|
+
const app = App.create({
|
|
30
|
+
auth: false,
|
|
31
|
+
db: Db.postgres({ connectionString: 'postgresql://unused@127.0.0.1:1/unused' }),
|
|
32
|
+
zones: [Zones.zoneModeratoInternal],
|
|
33
|
+
}).route('/', Data.data({ webhook: false }))
|
|
34
|
+
const address = '0x0000000000000000000000000000000000000001'
|
|
35
|
+
const hash = `0x${'00'.repeat(32)}`
|
|
36
|
+
const addressScoped = await app.request(
|
|
37
|
+
`/v1/addresses/${address}/activities?include=zones&chainId=${Viem.chainId.testnet}`,
|
|
38
|
+
)
|
|
39
|
+
const forbidden = await app.request(`/v1/transactions/${hash}/activities?include=zones`)
|
|
40
|
+
const scoped = await app.request(
|
|
41
|
+
`/v1/transactions/${hash}/activities?include=zones&chainId=${Viem.chainId.testnet}`,
|
|
42
|
+
)
|
|
43
|
+
const unsupported = await app.request('/v1/tokenlist?include=zones')
|
|
44
|
+
|
|
45
|
+
expect(forbidden.status).toBe(403)
|
|
46
|
+
expect(forbidden.headers.get('cache-control')).toBe('no-store')
|
|
47
|
+
expect(await addressScoped.json()).toMatchObject({ error: { code: 'api_key_forbidden' } })
|
|
48
|
+
expect(await scoped.json()).toMatchObject({ error: { code: 'api_key_forbidden' } })
|
|
49
|
+
expect(await unsupported.json()).toMatchObject({ error: { code: 'query_invalid' } })
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('readableChainIds', () => {
|
|
54
|
+
test('intersects the parent chain, scopes, and configured routable Zones', () => {
|
|
55
|
+
const principal = apiKeyPrincipal({
|
|
56
|
+
scopes: [
|
|
57
|
+
'data:read',
|
|
58
|
+
`zone:${Zones.zoneMainnetInternal.id}:read`,
|
|
59
|
+
`zone:${Zones.zoneModeratoInternal.id}:write`,
|
|
60
|
+
],
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
expect(
|
|
64
|
+
ZoneSelection.readableChainIds({
|
|
65
|
+
parentChainId: Viem.chainId.testnet,
|
|
66
|
+
principal,
|
|
67
|
+
zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
|
|
68
|
+
}),
|
|
69
|
+
).toStrictEqual([Zones.zoneModeratoInternal.id])
|
|
70
|
+
expect(
|
|
71
|
+
ZoneSelection.readableChainIds({
|
|
72
|
+
parentChainId: Viem.chainId.mainnet,
|
|
73
|
+
principal,
|
|
74
|
+
zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
|
|
75
|
+
}),
|
|
76
|
+
).toStrictEqual([Zones.zoneMainnetInternal.id])
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('lets wildcard keys read every configured routable Zone of the parent chain', () => {
|
|
80
|
+
expect(
|
|
81
|
+
ZoneSelection.readableChainIds({
|
|
82
|
+
parentChainId: Viem.chainId.testnet,
|
|
83
|
+
principal: apiKeyPrincipal({ scopes: ['*'] }),
|
|
84
|
+
zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
|
|
85
|
+
}),
|
|
86
|
+
).toStrictEqual([Zones.zoneModeratoInternal.id])
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('filters sandbox keys by each Zone parent chain', () => {
|
|
90
|
+
const principal = apiKeyPrincipal({
|
|
91
|
+
environment: 'sandbox',
|
|
92
|
+
scopes: [
|
|
93
|
+
'data:read',
|
|
94
|
+
`zone:${Zones.zoneMainnetInternal.id}:read`,
|
|
95
|
+
`zone:${Zones.zoneModeratoInternal.id}:read`,
|
|
96
|
+
],
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
expect(
|
|
100
|
+
ZoneSelection.readableChainIds({
|
|
101
|
+
parentChainId: Viem.chainId.testnet,
|
|
102
|
+
principal,
|
|
103
|
+
zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
|
|
104
|
+
}),
|
|
105
|
+
).toStrictEqual([Zones.zoneModeratoInternal.id])
|
|
106
|
+
expect(
|
|
107
|
+
ZoneSelection.readableChainIds({
|
|
108
|
+
parentChainId: Viem.chainId.mainnet,
|
|
109
|
+
principal,
|
|
110
|
+
zones: new Map(Zones.chains.map((zone) => [zone.id, zone])),
|
|
111
|
+
}),
|
|
112
|
+
).toStrictEqual([])
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
test('requires data read access and both upstreams', () => {
|
|
116
|
+
const zone = {
|
|
117
|
+
...Zones.zoneModeratoInternal,
|
|
118
|
+
id: 1_424_310_099,
|
|
119
|
+
rpcUrls: { default: { http: ['https://zone.rpc.test'] } },
|
|
120
|
+
}
|
|
121
|
+
const zones = new Map([[zone.id, zone]])
|
|
122
|
+
|
|
123
|
+
expect(
|
|
124
|
+
ZoneSelection.readableChainIds({
|
|
125
|
+
parentChainId: zone.sourceId,
|
|
126
|
+
principal: apiKeyPrincipal({ scopes: [`zone:${zone.id}:read`] }),
|
|
127
|
+
zones,
|
|
128
|
+
}),
|
|
129
|
+
).toStrictEqual([])
|
|
130
|
+
expect(
|
|
131
|
+
ZoneSelection.readableChainIds({
|
|
132
|
+
parentChainId: zone.sourceId,
|
|
133
|
+
principal: apiKeyPrincipal({ scopes: ['data:read', `zone:${zone.id}:read`] }),
|
|
134
|
+
zones,
|
|
135
|
+
}),
|
|
136
|
+
).toStrictEqual([])
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe('uniqueMatch', () => {
|
|
141
|
+
test('selects one match after every chain completes', () => {
|
|
142
|
+
expect(
|
|
143
|
+
ZoneSelection.uniqueMatch([
|
|
144
|
+
{ chainId: 1, value: null },
|
|
145
|
+
{ chainId: 2, value: 'receipt' },
|
|
146
|
+
]),
|
|
147
|
+
).toStrictEqual({ chainId: 2, kind: 'selected', value: 'receipt' })
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test('distinguishes no match from ambiguous matches', () => {
|
|
151
|
+
expect(ZoneSelection.uniqueMatch([{ chainId: 1, value: null }])).toStrictEqual({
|
|
152
|
+
kind: 'not_found',
|
|
153
|
+
})
|
|
154
|
+
expect(
|
|
155
|
+
ZoneSelection.uniqueMatch([
|
|
156
|
+
{ chainId: 1, value: 'first' },
|
|
157
|
+
{ chainId: 2, value: 'second' },
|
|
158
|
+
]),
|
|
159
|
+
).toStrictEqual({ kind: 'ambiguous' })
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
test('fails the selection when any chain lookup fails', () => {
|
|
163
|
+
const cause = new Error('unavailable')
|
|
164
|
+
expect(
|
|
165
|
+
ZoneSelection.uniqueMatch([
|
|
166
|
+
{ chainId: 1, value: 'receipt' },
|
|
167
|
+
{ cause, chainId: 2 },
|
|
168
|
+
]),
|
|
169
|
+
).toStrictEqual({ failures: [{ cause, chainId: 2 }], kind: 'failed' })
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
function apiKeyPrincipal(
|
|
174
|
+
options: apiKeyPrincipal.Options,
|
|
175
|
+
): Extract<Auth.Principal, { type: 'api_key' }> {
|
|
176
|
+
const apiKey = ApiKey.schema.ApiKey.parse({
|
|
177
|
+
environment: options.environment,
|
|
178
|
+
id: 'key_test',
|
|
179
|
+
orgId: 'org_test',
|
|
180
|
+
scopes: options.scopes,
|
|
181
|
+
})
|
|
182
|
+
return {
|
|
183
|
+
apiKey,
|
|
184
|
+
environment: apiKey.environment,
|
|
185
|
+
id: apiKey.id,
|
|
186
|
+
orgId: apiKey.orgId,
|
|
187
|
+
type: 'api_key',
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
declare namespace apiKeyPrincipal {
|
|
192
|
+
type Options = {
|
|
193
|
+
environment?: 'production' | 'sandbox' | undefined
|
|
194
|
+
scopes: readonly string[]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Chain } from 'viem'
|
|
2
|
+
|
|
3
|
+
import type * as Auth from '../../internal/Auth.js'
|
|
4
|
+
import * as Tidx from '../../internal/Tidx.js'
|
|
5
|
+
import * as Viem from '../../internal/Viem.js'
|
|
6
|
+
import * as Scope from '../../Scope.js'
|
|
7
|
+
|
|
8
|
+
/** Returns configured and routable Zones that an API key may read. */
|
|
9
|
+
export function readableChainIds(options: readableChainIds.Options): readonly number[] {
|
|
10
|
+
const { parentChainId, principal, zones } = options
|
|
11
|
+
const scopes = principal.apiKey.scopes
|
|
12
|
+
if (!scopes.includes(Scope.wildcard) && !scopes.includes('data:read')) return []
|
|
13
|
+
|
|
14
|
+
const chainIds = [...zones.values()].flatMap((zone) => {
|
|
15
|
+
if (zone.sourceId !== parentChainId) return []
|
|
16
|
+
const allowed =
|
|
17
|
+
scopes.includes(Scope.wildcard) ||
|
|
18
|
+
scopes.includes(`zone:${zone.id}:read`) ||
|
|
19
|
+
scopes.includes(`zone:${zone.id}:write`)
|
|
20
|
+
if (!allowed) return []
|
|
21
|
+
if (
|
|
22
|
+
principal.environment === 'sandbox' &&
|
|
23
|
+
(zone.sourceId === undefined || Viem.isMainnet(zone.sourceId))
|
|
24
|
+
)
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
const context = { chainId: zone.id, principal, zone }
|
|
28
|
+
if (Viem.resolveRpc(options.rpc, context).url === undefined) return []
|
|
29
|
+
if (Tidx.resolve(options.tidx, context).baseUrl === undefined) return []
|
|
30
|
+
return [zone.id]
|
|
31
|
+
})
|
|
32
|
+
return chainIds.sort((a, b) => a - b)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export declare namespace readableChainIds {
|
|
36
|
+
/** Inputs for resolving the readable inferred-Zone set. */
|
|
37
|
+
type Options = {
|
|
38
|
+
/** Parent Tempo chain whose Zones may be selected. */
|
|
39
|
+
parentChainId: Viem.ChainId
|
|
40
|
+
/** Authenticated API-key principal selecting Zones. */
|
|
41
|
+
principal: Extract<Auth.Principal, { type: 'api_key' }>
|
|
42
|
+
/** RPC configuration used to exclude unroutable Zones. */
|
|
43
|
+
rpc?: Viem.getClient.Rpc | undefined
|
|
44
|
+
/** TIDX configuration used to exclude unroutable Zones. */
|
|
45
|
+
tidx?: Tidx.getClient.Tidx | undefined
|
|
46
|
+
/** Hosted Zone metadata keyed by chain id. */
|
|
47
|
+
zones: ReadonlyMap<number, Chain>
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Resolves chain receipt probes without treating partial upstream results as complete. */
|
|
52
|
+
export function uniqueMatch<const value>(
|
|
53
|
+
probes: readonly uniqueMatch.Probe<value>[],
|
|
54
|
+
): uniqueMatch.Result<value> {
|
|
55
|
+
const failures = probes.flatMap((probe) => ('cause' in probe ? [probe] : []))
|
|
56
|
+
if (failures.length > 0) return { failures, kind: 'failed' }
|
|
57
|
+
|
|
58
|
+
const matches = probes.flatMap((probe) =>
|
|
59
|
+
'value' in probe && probe.value !== null
|
|
60
|
+
? [{ chainId: probe.chainId, value: probe.value }]
|
|
61
|
+
: [],
|
|
62
|
+
)
|
|
63
|
+
if (matches.length === 0) return { kind: 'not_found' }
|
|
64
|
+
if (matches.length > 1) return { kind: 'ambiguous' }
|
|
65
|
+
return { ...matches[0]!, kind: 'selected' }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export declare namespace uniqueMatch {
|
|
69
|
+
/** One completed chain lookup. */
|
|
70
|
+
type Probe<value> =
|
|
71
|
+
| {
|
|
72
|
+
/** Chain that completed the lookup. */
|
|
73
|
+
chainId: number
|
|
74
|
+
/** Matching value, or null when the chain did not contain the resource. */
|
|
75
|
+
value: value | null
|
|
76
|
+
}
|
|
77
|
+
| {
|
|
78
|
+
/** Upstream failure from this chain. */
|
|
79
|
+
cause: unknown
|
|
80
|
+
/** Chain that failed the lookup. */
|
|
81
|
+
chainId: number
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Unique-match decision across every requested chain. */
|
|
85
|
+
type Result<value> =
|
|
86
|
+
| {
|
|
87
|
+
/** Chain containing the unique match. */
|
|
88
|
+
chainId: number
|
|
89
|
+
/** Unique match result. */
|
|
90
|
+
kind: 'selected'
|
|
91
|
+
/** Value found in the selected Zone. */
|
|
92
|
+
value: value
|
|
93
|
+
}
|
|
94
|
+
| {
|
|
95
|
+
/** Every failed Zone lookup. */
|
|
96
|
+
failures: readonly Extract<Probe<value>, { cause: unknown }>[]
|
|
97
|
+
/** Partial failure result. */
|
|
98
|
+
kind: 'failed'
|
|
99
|
+
}
|
|
100
|
+
| {
|
|
101
|
+
/** Ambiguous match result. */
|
|
102
|
+
kind: 'ambiguous'
|
|
103
|
+
}
|
|
104
|
+
| {
|
|
105
|
+
/** No-match result. */
|
|
106
|
+
kind: 'not_found'
|
|
107
|
+
}
|
|
108
|
+
}
|