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/internal/Auth.ts
CHANGED
|
@@ -587,11 +587,21 @@ export function middleware<
|
|
|
587
587
|
const overrides = options.overrides as
|
|
588
588
|
| Record<string, PolicyOverride | false | undefined>
|
|
589
589
|
| undefined
|
|
590
|
-
const
|
|
590
|
+
const routePolicies = policies(c)
|
|
591
|
+
const configuredOverride = (() => {
|
|
592
|
+
const configured = overrides?.[key]
|
|
593
|
+
if (configured !== undefined) return configured
|
|
594
|
+
const inheritedMethod = routePolicies.find(
|
|
595
|
+
(policy) => policy.inheritOverridesFrom,
|
|
596
|
+
)?.inheritOverridesFrom
|
|
597
|
+
if (inheritedMethod === undefined) return undefined
|
|
598
|
+
const inheritedKey = `${inheritedMethod.toUpperCase()} ${key.slice(key.indexOf(' ') + 1)}`
|
|
599
|
+
return overrides?.[inheritedKey]
|
|
600
|
+
})()
|
|
591
601
|
const routeOverride =
|
|
592
602
|
management && configuredOverride ? { mpp: configuredOverride.mpp } : configuredOverride
|
|
593
603
|
const endpointPolicy = bindMppScope(
|
|
594
|
-
resolvePolicy(base, defaults, [...
|
|
604
|
+
resolvePolicy(base, defaults, [...routePolicies, routeOverride], description),
|
|
595
605
|
scope,
|
|
596
606
|
)
|
|
597
607
|
if (!endpointPolicy) return next()
|
|
@@ -666,7 +676,10 @@ export declare namespace middleware {
|
|
|
666
676
|
}
|
|
667
677
|
|
|
668
678
|
/** MPP payment options used by auth middleware. */
|
|
669
|
-
type MppOptions = Omit<
|
|
679
|
+
type MppOptions = Omit<
|
|
680
|
+
Parameters<typeof Mppx.create<readonly [ReturnType<typeof tempo.session>]>>[0],
|
|
681
|
+
'methods'
|
|
682
|
+
> & {
|
|
670
683
|
/** Paid-request quota per access principal. Defaults to 100 per minute. */
|
|
671
684
|
rateLimit?: RateLimit.Limit | undefined
|
|
672
685
|
/** Global Tempo Session options passed to the MPP method instantiator. */
|
|
@@ -1000,12 +1013,20 @@ export declare namespace install {
|
|
|
1000
1013
|
}
|
|
1001
1014
|
|
|
1002
1015
|
/** Creates route middleware that contributes an auth policy override. */
|
|
1003
|
-
export function policy(options:
|
|
1016
|
+
export function policy(options: policy.Options): MiddlewareHandler {
|
|
1004
1017
|
const middleware = createMiddleware((_, next) => next()) as MiddlewareHandler & PolicyHandler
|
|
1005
1018
|
middleware[policySymbol] = options
|
|
1006
1019
|
return middleware
|
|
1007
1020
|
}
|
|
1008
1021
|
|
|
1022
|
+
export declare namespace policy {
|
|
1023
|
+
/** Route policy plus metadata for compatibility aliases. */
|
|
1024
|
+
type Options = PolicyOverride & {
|
|
1025
|
+
/** HTTP method whose configured override this route inherits when its own is absent. */
|
|
1026
|
+
inheritOverridesFrom?: string | undefined
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1009
1030
|
/** Adds management POSTs for OpenAPI-registered MPP GET resources. */
|
|
1010
1031
|
export function installMppManagementRoutes(
|
|
1011
1032
|
app: Hono<any, any>,
|
|
@@ -1106,7 +1127,7 @@ type OpenApiRoute = {
|
|
|
1106
1127
|
}
|
|
1107
1128
|
|
|
1108
1129
|
type PolicyHandler = {
|
|
1109
|
-
[policySymbol]?:
|
|
1130
|
+
[policySymbol]?: policy.Options | undefined
|
|
1110
1131
|
}
|
|
1111
1132
|
|
|
1112
1133
|
type MppManagementHandler = {
|
|
@@ -1283,7 +1304,7 @@ function policies(c: hono_Context) {
|
|
|
1283
1304
|
return matchedRoutes(c)
|
|
1284
1305
|
.slice(c.req.routeIndex + 1)
|
|
1285
1306
|
.map(policyFromRoute)
|
|
1286
|
-
.filter((
|
|
1307
|
+
.filter((routePolicy): routePolicy is policy.Options => routePolicy !== undefined)
|
|
1287
1308
|
}
|
|
1288
1309
|
|
|
1289
1310
|
function openApiSpec(route: RouterRoute) {
|
|
@@ -1433,8 +1454,8 @@ export function require<environment extends Environment = Environment>(
|
|
|
1433
1454
|
return proceed()
|
|
1434
1455
|
}
|
|
1435
1456
|
|
|
1436
|
-
const
|
|
1437
|
-
if (!
|
|
1457
|
+
const apiKey_resolved = await auth.apiKey?.resolve(c, credential.token)
|
|
1458
|
+
if (!apiKey_resolved) {
|
|
1438
1459
|
// A bearer session token is indistinguishable from an API key at the
|
|
1439
1460
|
// header, so a failed key lookup falls through to the session lane
|
|
1440
1461
|
// before rejecting.
|
|
@@ -1452,6 +1473,10 @@ export function require<environment extends Environment = Environment>(
|
|
|
1452
1473
|
})
|
|
1453
1474
|
}
|
|
1454
1475
|
|
|
1476
|
+
const scopes = Scope.expandAliases(apiKey_resolved.scopes)
|
|
1477
|
+
const apiKey =
|
|
1478
|
+
scopes === apiKey_resolved.scopes ? apiKey_resolved : { ...apiKey_resolved, scopes }
|
|
1479
|
+
|
|
1455
1480
|
// Sandbox keys are testnet-only. A sandbox key that explicitly targets
|
|
1456
1481
|
// mainnet (`?chainId`) is rejected with a clear message rather than
|
|
1457
1482
|
// steered or downgraded to anonymous, so the caller learns their key does
|
|
@@ -1829,7 +1854,8 @@ function getRequestId(c: hono_Context) {
|
|
|
1829
1854
|
return typeof variables['requestId'] === 'string' ? variables['requestId'] : undefined
|
|
1830
1855
|
}
|
|
1831
1856
|
|
|
1832
|
-
|
|
1857
|
+
/** True when the request carries an `Authorization: Payment` MPP credential. */
|
|
1858
|
+
export function hasPaymentCredential(c: hono_Context) {
|
|
1833
1859
|
const authorization = c.req.header('authorization')
|
|
1834
1860
|
if (!authorization) return false
|
|
1835
1861
|
return !!Credential.extractPaymentScheme(authorization)
|
package/src/internal/Cache.ts
CHANGED
|
@@ -58,10 +58,8 @@ export function response<environment extends Env>(
|
|
|
58
58
|
): MiddlewareHandler<environment> {
|
|
59
59
|
const defaultCacheControl = options.cacheControl ?? policies.default
|
|
60
60
|
const vary = options.vary ?? ['Accept-Encoding', 'Authorization', 'Tempo-API-Key', 'X-API-Key']
|
|
61
|
-
// hono/cache
|
|
62
|
-
//
|
|
63
|
-
// normalization so the `no-cache` purge below deletes exactly the entry the
|
|
64
|
-
// wrapped middleware reads — drift here would make refreshes silently miss.
|
|
61
|
+
// Mirror hono/cache's vary normalization so the `no-cache` purge below
|
|
62
|
+
// deletes exactly the entry the wrapped middleware reads.
|
|
65
63
|
const varyKeyDirectives = [
|
|
66
64
|
...new Set(vary.map((name) => name.trim().toLowerCase()).filter(Boolean)),
|
|
67
65
|
]
|
|
@@ -95,10 +93,19 @@ export function response<environment extends Env>(
|
|
|
95
93
|
type Caches = { open(name: string): Promise<{ delete(key: string): Promise<unknown> }> }
|
|
96
94
|
const caches = (globalThis as { caches?: Caches }).caches
|
|
97
95
|
if (noCache && !noStore && caches) {
|
|
98
|
-
|
|
96
|
+
// hono/cache 4.13 wraps generated keys in a canonical URL containing the
|
|
97
|
+
// request method and vary values. Keep this in sync with its
|
|
98
|
+
// `createCacheKey` so refreshes remove the stored GET response.
|
|
99
|
+
const key = await options.key(c)
|
|
100
|
+
const url = new URL('/.hono/cache', c.req.url)
|
|
101
|
+
url.searchParams.append('__hono_cache_key', key.split('#', 1)[0] ?? key)
|
|
102
|
+
url.searchParams.append('__hono_cache_method', c.req.method)
|
|
99
103
|
for (const name of varyKeyDirectives)
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
url.searchParams.append(
|
|
105
|
+
'__hono_cache_vary',
|
|
106
|
+
JSON.stringify([name, c.req.raw.headers.get(name) ?? '']),
|
|
107
|
+
)
|
|
108
|
+
await (await caches.open(options.name)).delete(url.href)
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
// Run ETag inside Hono's cache miss path so fresh responses are hashed
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as EarnVaults from './EarnVaults.js'
|
|
2
|
+
|
|
3
|
+
describe('addZoneRouteCapabilities', () => {
|
|
4
|
+
test('adds private routing and router swaps', () => {
|
|
5
|
+
expect(
|
|
6
|
+
EarnVaults.addZoneRouteCapabilities({
|
|
7
|
+
asyncRedeem: false,
|
|
8
|
+
boundedRedeem: true,
|
|
9
|
+
deposit: true,
|
|
10
|
+
exactWithdraw: true,
|
|
11
|
+
inKindDeposit: true,
|
|
12
|
+
privateRouting: false,
|
|
13
|
+
redeem: true,
|
|
14
|
+
routerSwaps: false,
|
|
15
|
+
}),
|
|
16
|
+
).toMatchObject({ privateRouting: true, routerSwaps: true })
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
describe('deriveZoneId', () => {
|
|
21
|
+
test('derives IDs from mainnet and testnet Zone chain schemes', () => {
|
|
22
|
+
expect([
|
|
23
|
+
EarnVaults.deriveZoneId(421_700_006),
|
|
24
|
+
EarnVaults.deriveZoneId(1_424_310_003),
|
|
25
|
+
]).toStrictEqual([6, 3])
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('rejects a source chain ID', () => {
|
|
29
|
+
expect(() => EarnVaults.deriveZoneId(31_318)).toThrowErrorMatchingInlineSnapshot(
|
|
30
|
+
`[EarnVaults.InvalidRegistryError: Chain 31318 does not use a supported Zone chain-ID scheme.]`,
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseAbi } from 'viem'
|
|
2
2
|
import { tempoTestnet } from 'viem/tempo/chains'
|
|
3
3
|
|
|
4
|
+
import * as TestEarn from '../../test/Earn.js'
|
|
4
5
|
import * as Runtime from '../../test/runtime.js'
|
|
5
6
|
import * as TestViem from '../../test/Viem.js'
|
|
6
7
|
import * as Zones from '../apps/Zones.js'
|
|
@@ -43,6 +44,17 @@ describe('schema.ResolveInput', () => {
|
|
|
43
44
|
})
|
|
44
45
|
})
|
|
45
46
|
|
|
47
|
+
describe('schema.ZoneRoute', () => {
|
|
48
|
+
test('normalizes the router address', () => {
|
|
49
|
+
expect(
|
|
50
|
+
EarnVaults.schema.ZoneRoute.parse({
|
|
51
|
+
...TestEarn.zoneRoute,
|
|
52
|
+
earnRouter: TestEarn.zoneRoute.earnRouter.toUpperCase().replace('0X', '0x'),
|
|
53
|
+
}),
|
|
54
|
+
).toStrictEqual(TestEarn.zoneRoute)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
46
58
|
describe('classifyEngineType', () => {
|
|
47
59
|
test('classifies supported capability fingerprints', () => {
|
|
48
60
|
expect([
|
|
@@ -193,3 +205,70 @@ describe('resolve', () => {
|
|
|
193
205
|
60_000,
|
|
194
206
|
)
|
|
195
207
|
})
|
|
208
|
+
|
|
209
|
+
describe('resolveZoneRoutes', () => {
|
|
210
|
+
test.runIf(Runtime.get().mode === 'testnet')(
|
|
211
|
+
'verifies immutable router bindings and derives private tokens',
|
|
212
|
+
async () => {
|
|
213
|
+
const getClient = Viem.createGetClient({
|
|
214
|
+
defaultChainId: tempoTestnet.id,
|
|
215
|
+
rpc: TestViem.rpc,
|
|
216
|
+
zones: [TestEarn.zone],
|
|
217
|
+
})
|
|
218
|
+
const discovery = await EarnVaults.resolve({
|
|
219
|
+
getClient,
|
|
220
|
+
input: {
|
|
221
|
+
chainId: tempoTestnet.id,
|
|
222
|
+
vaultAddress: TestEarn.zoneVaultAddress,
|
|
223
|
+
},
|
|
224
|
+
zones: [TestEarn.zone],
|
|
225
|
+
})
|
|
226
|
+
const routes = await EarnVaults.resolveZoneRoutes({
|
|
227
|
+
discovery,
|
|
228
|
+
getClient,
|
|
229
|
+
routes: [TestEarn.zoneRoute],
|
|
230
|
+
zones: [TestEarn.zone],
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
expect(routes).toHaveLength(1)
|
|
234
|
+
expect(routes[0]).toMatchObject({
|
|
235
|
+
...TestEarn.zoneRoute,
|
|
236
|
+
name: TestEarn.zone.name,
|
|
237
|
+
})
|
|
238
|
+
expect(routes[0]?.inputTokens).toHaveLength(1)
|
|
239
|
+
expect(routes[0]?.outputTokens).toStrictEqual(routes[0]?.inputTokens)
|
|
240
|
+
await expect(
|
|
241
|
+
EarnVaults.resolveZoneRoutes({
|
|
242
|
+
discovery,
|
|
243
|
+
getClient,
|
|
244
|
+
routes: [TestEarn.zoneRoute, TestEarn.zoneRoute],
|
|
245
|
+
zones: [TestEarn.zone],
|
|
246
|
+
}),
|
|
247
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
248
|
+
`[EarnVaults.InvalidRegistryError: Zone 1424310003 is configured more than once.]`,
|
|
249
|
+
)
|
|
250
|
+
await expect(
|
|
251
|
+
EarnVaults.resolveZoneRoutes({
|
|
252
|
+
discovery,
|
|
253
|
+
getClient,
|
|
254
|
+
routes: [
|
|
255
|
+
{ ...TestEarn.zoneRoute, deploymentBlock: TestEarn.zoneRoute.deploymentBlock + 1 },
|
|
256
|
+
],
|
|
257
|
+
zones: [TestEarn.zone],
|
|
258
|
+
}),
|
|
259
|
+
).rejects.toMatchObject({
|
|
260
|
+
result: {
|
|
261
|
+
issues: [
|
|
262
|
+
{
|
|
263
|
+
actual: String(TestEarn.zoneRoute.deploymentBlock + 1),
|
|
264
|
+
code: 'zone-deployment-block-mismatch',
|
|
265
|
+
message: 'Earn router deployment block does not match its code boundary.',
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
status: 'mismatch',
|
|
269
|
+
},
|
|
270
|
+
})
|
|
271
|
+
},
|
|
272
|
+
60_000,
|
|
273
|
+
)
|
|
274
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZoneId } from 'ox/tempo'
|
|
1
2
|
import {
|
|
2
3
|
ContractFunctionExecutionError,
|
|
3
4
|
ContractFunctionRevertedError,
|
|
@@ -161,6 +162,28 @@ export namespace schema {
|
|
|
161
162
|
})
|
|
162
163
|
.check(z.describe('Onchain identity of an Earn vault.'))
|
|
163
164
|
|
|
165
|
+
/** Schema for one curated Earn route through a private Zone. */
|
|
166
|
+
export const ZoneRoute = z
|
|
167
|
+
.strictObject({
|
|
168
|
+
chainId: Schema.ChainId.check(
|
|
169
|
+
z.describe('Private Zone chain id.'),
|
|
170
|
+
z.meta({ examples: [1424310003] }),
|
|
171
|
+
),
|
|
172
|
+
deploymentBlock: z
|
|
173
|
+
.number()
|
|
174
|
+
.check(
|
|
175
|
+
z.int(),
|
|
176
|
+
z.nonnegative(),
|
|
177
|
+
z.describe('Parent-chain block that deployed the Earn router.'),
|
|
178
|
+
z.meta({ examples: [31730087] }),
|
|
179
|
+
),
|
|
180
|
+
earnRouter: Schema.Address.check(
|
|
181
|
+
z.describe('Parent-chain router for this Zone and Earn vault.'),
|
|
182
|
+
z.meta({ examples: ['0xebedc74ffeead186acc6cac05eb82fb9e093a7c7'] }),
|
|
183
|
+
),
|
|
184
|
+
})
|
|
185
|
+
.check(z.describe('Curated Earn route through one private Zone.'))
|
|
186
|
+
|
|
164
187
|
/** Schema for live state resolved from one Earn vault. */
|
|
165
188
|
export const Discovery = z
|
|
166
189
|
.strictObject({
|
|
@@ -228,12 +251,48 @@ export type Discovery = z.output<typeof schema.Discovery>
|
|
|
228
251
|
/** Onchain identity of an Earn vault. */
|
|
229
252
|
export type ResolveInput = z.output<typeof schema.ResolveInput>
|
|
230
253
|
|
|
254
|
+
/** Curated Earn route through one private Zone. */
|
|
255
|
+
export type ZoneRoute = z.output<typeof schema.ZoneRoute>
|
|
256
|
+
|
|
257
|
+
/** Curated Zone route with immutable router bindings resolved onchain. */
|
|
258
|
+
export type ResolvedZoneRoute = ZoneRoute & {
|
|
259
|
+
/** Tokens accepted by private deposits. */
|
|
260
|
+
inputTokens: readonly Address[]
|
|
261
|
+
/** Configured private Zone name. */
|
|
262
|
+
name: string
|
|
263
|
+
/** Tokens returned by private redemptions. */
|
|
264
|
+
outputTokens: readonly Address[]
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** Adds capabilities proven by a verified private Zone route. */
|
|
268
|
+
export function addZoneRouteCapabilities(
|
|
269
|
+
capabilities: NonNullable<Discovery['capabilities']>,
|
|
270
|
+
): NonNullable<Discovery['capabilities']> {
|
|
271
|
+
return { ...capabilities, privateRouting: true, routerSwaps: true }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Derives a Zone ID from any supported Zone chain-ID scheme. */
|
|
275
|
+
export function deriveZoneId(chainId: number): number {
|
|
276
|
+
for (const sourceId of [4_217, 42_431] satisfies readonly ZoneId.SourceId[]) {
|
|
277
|
+
const zoneId = ZoneId.fromChainId(chainId, sourceId)
|
|
278
|
+
if (zoneId >= 0 && ZoneId.toChainId(zoneId, sourceId) === chainId) return zoneId
|
|
279
|
+
}
|
|
280
|
+
throw new InvalidRegistryError(`Chain ${chainId} does not use a supported Zone chain-ID scheme.`)
|
|
281
|
+
}
|
|
282
|
+
|
|
231
283
|
/** Stable code describing an onchain verification issue. */
|
|
232
284
|
export type VerificationIssueCode =
|
|
233
285
|
| 'chain-mismatch'
|
|
234
286
|
| 'engine-asset-mismatch'
|
|
235
287
|
| 'policy-unsupported'
|
|
236
288
|
| 'read-failed'
|
|
289
|
+
| 'zone-deployment-block-mismatch'
|
|
290
|
+
| 'zone-flow-unsupported'
|
|
291
|
+
| 'zone-id-mismatch'
|
|
292
|
+
| 'zone-router-invalid'
|
|
293
|
+
| 'zone-share-mismatch'
|
|
294
|
+
| 'zone-vault-asset-mismatch'
|
|
295
|
+
| 'zone-vault-mismatch'
|
|
237
296
|
|
|
238
297
|
/** One onchain verification issue. */
|
|
239
298
|
export type VerificationIssue = {
|
|
@@ -303,6 +362,16 @@ type RouterCapabilities = {
|
|
|
303
362
|
redeem: boolean
|
|
304
363
|
}
|
|
305
364
|
|
|
365
|
+
type ZoneRouteBindings = {
|
|
366
|
+
allowedZoneId: number
|
|
367
|
+
deposit: boolean
|
|
368
|
+
earnShare: Address
|
|
369
|
+
earnVault: Address
|
|
370
|
+
privateAsset: Address
|
|
371
|
+
redeem: boolean
|
|
372
|
+
vaultAsset: Address
|
|
373
|
+
}
|
|
374
|
+
|
|
306
375
|
type TokenMetadata = Omit<Discovery['assetToken'], 'address'>
|
|
307
376
|
|
|
308
377
|
const engineBindingsAbi = parseAbi(['function vault() view returns (address)'])
|
|
@@ -363,6 +432,139 @@ export declare namespace resolve {
|
|
|
363
432
|
}
|
|
364
433
|
}
|
|
365
434
|
|
|
435
|
+
/** Resolves and verifies every curated Zone route for one Earn vault. */
|
|
436
|
+
export async function resolveZoneRoutes(
|
|
437
|
+
options: resolveZoneRoutes.Options,
|
|
438
|
+
): Promise<ResolvedZoneRoute[]> {
|
|
439
|
+
const result = z.array(schema.ZoneRoute).safeParse(options.routes)
|
|
440
|
+
if (!result.success) throw invalid(result.error)
|
|
441
|
+
|
|
442
|
+
const chainIds = new Set<number>()
|
|
443
|
+
const routers = new Set<string>()
|
|
444
|
+
for (const route of result.data) {
|
|
445
|
+
if (chainIds.has(route.chainId))
|
|
446
|
+
throw new InvalidRegistryError(`Zone ${route.chainId} is configured more than once.`)
|
|
447
|
+
if (routers.has(route.earnRouter))
|
|
448
|
+
throw new InvalidRegistryError(
|
|
449
|
+
`Earn router ${route.earnRouter} is configured more than once.`,
|
|
450
|
+
)
|
|
451
|
+
chainIds.add(route.chainId)
|
|
452
|
+
routers.add(route.earnRouter)
|
|
453
|
+
}
|
|
454
|
+
if (result.data.length === 0) return []
|
|
455
|
+
|
|
456
|
+
const client = options.getClient(options.discovery.chainId)
|
|
457
|
+
return Promise.all(
|
|
458
|
+
result.data.map(async (route) => {
|
|
459
|
+
const zone = options.zones.find((candidate) => candidate.id === route.chainId)
|
|
460
|
+
if (!zone) throw new InvalidRegistryError(`Zone ${route.chainId} is not configured.`)
|
|
461
|
+
if (zone.sourceId !== options.discovery.chainId)
|
|
462
|
+
throw new InvalidRegistryError(
|
|
463
|
+
`Zone ${route.chainId} does not belong to chain ${options.discovery.chainId}.`,
|
|
464
|
+
)
|
|
465
|
+
const expectedZoneId = deriveZoneId(route.chainId)
|
|
466
|
+
|
|
467
|
+
const [code, previousCode] = await Promise.all([
|
|
468
|
+
client.getCode({
|
|
469
|
+
address: route.earnRouter,
|
|
470
|
+
blockNumber: BigInt(route.deploymentBlock),
|
|
471
|
+
}),
|
|
472
|
+
route.deploymentBlock === 0
|
|
473
|
+
? undefined
|
|
474
|
+
: client.getCode({
|
|
475
|
+
address: route.earnRouter,
|
|
476
|
+
blockNumber: BigInt(route.deploymentBlock - 1),
|
|
477
|
+
}),
|
|
478
|
+
])
|
|
479
|
+
if (!code || code === '0x' || (previousCode !== undefined && previousCode !== '0x'))
|
|
480
|
+
throw mismatch({
|
|
481
|
+
discovery: options.discovery,
|
|
482
|
+
issues: [
|
|
483
|
+
{
|
|
484
|
+
actual: String(route.deploymentBlock),
|
|
485
|
+
code: 'zone-deployment-block-mismatch',
|
|
486
|
+
message: 'Earn router deployment block does not match its code boundary.',
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
const bindings = await readZoneRouteBindings(client, { earnRouter: route.earnRouter }).catch(
|
|
492
|
+
(error) => {
|
|
493
|
+
if (!isMissingOptionalFunctionError(error)) throw error
|
|
494
|
+
throw mismatch({
|
|
495
|
+
discovery: options.discovery,
|
|
496
|
+
issues: [
|
|
497
|
+
{
|
|
498
|
+
actual: route.earnRouter,
|
|
499
|
+
code: 'zone-router-invalid',
|
|
500
|
+
message: 'Earn router does not expose the required immutable bindings.',
|
|
501
|
+
},
|
|
502
|
+
],
|
|
503
|
+
})
|
|
504
|
+
},
|
|
505
|
+
)
|
|
506
|
+
const issues: VerificationIssue[] = []
|
|
507
|
+
if (bindings.allowedZoneId !== expectedZoneId)
|
|
508
|
+
issues.push({
|
|
509
|
+
actual: bindings.allowedZoneId.toString(),
|
|
510
|
+
code: 'zone-id-mismatch',
|
|
511
|
+
expected: String(expectedZoneId),
|
|
512
|
+
message: 'Earn router is configured for a different Zone.',
|
|
513
|
+
})
|
|
514
|
+
compareAddress(
|
|
515
|
+
issues,
|
|
516
|
+
'zone-vault-mismatch',
|
|
517
|
+
'Earn router is configured for a different Earn vault.',
|
|
518
|
+
options.discovery.vaultAddress,
|
|
519
|
+
bindings.earnVault,
|
|
520
|
+
)
|
|
521
|
+
compareAddress(
|
|
522
|
+
issues,
|
|
523
|
+
'zone-vault-asset-mismatch',
|
|
524
|
+
'Earn router vault asset does not match the Earn vault.',
|
|
525
|
+
options.discovery.assetToken.address,
|
|
526
|
+
bindings.vaultAsset,
|
|
527
|
+
)
|
|
528
|
+
compareAddress(
|
|
529
|
+
issues,
|
|
530
|
+
'zone-share-mismatch',
|
|
531
|
+
'Earn router share token does not match the Earn vault.',
|
|
532
|
+
options.discovery.shareToken.address,
|
|
533
|
+
bindings.earnShare,
|
|
534
|
+
)
|
|
535
|
+
if (!bindings.deposit || !bindings.redeem)
|
|
536
|
+
issues.push({
|
|
537
|
+
actual: `deposit=${bindings.deposit},redeem=${bindings.redeem}`,
|
|
538
|
+
code: 'zone-flow-unsupported',
|
|
539
|
+
expected: 'deposit=true,redeem=true',
|
|
540
|
+
message: 'Earn router must support private deposits and redemptions.',
|
|
541
|
+
})
|
|
542
|
+
if (issues.length > 0) throw mismatch({ discovery: options.discovery, issues })
|
|
543
|
+
|
|
544
|
+
return {
|
|
545
|
+
...route,
|
|
546
|
+
inputTokens: [bindings.privateAsset],
|
|
547
|
+
name: zone.name,
|
|
548
|
+
outputTokens: [bindings.privateAsset],
|
|
549
|
+
}
|
|
550
|
+
}),
|
|
551
|
+
)
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export declare namespace resolveZoneRoutes {
|
|
555
|
+
/** Inputs for resolving and verifying curated Zone routes. */
|
|
556
|
+
type Options = {
|
|
557
|
+
/** Live state of the Earn vault bound by every router. */
|
|
558
|
+
discovery: Discovery
|
|
559
|
+
/** Resolves the parent-chain client used to read each router. */
|
|
560
|
+
getClient: Viem.GetClient
|
|
561
|
+
/** Curated Zone routes to verify. */
|
|
562
|
+
routes: unknown
|
|
563
|
+
/** Private Zones configured by the API. */
|
|
564
|
+
zones: readonly Chain[]
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
366
568
|
/** Infers the supported engine type from its capability fingerprint. */
|
|
367
569
|
export function classifyEngineType(
|
|
368
570
|
options: classifyEngineType.Options,
|
|
@@ -729,6 +931,60 @@ declare namespace readEngineBindings {
|
|
|
729
931
|
}
|
|
730
932
|
}
|
|
731
933
|
|
|
934
|
+
async function readZoneRouteBindings(
|
|
935
|
+
client: Client,
|
|
936
|
+
options: readZoneRouteBindings.Options,
|
|
937
|
+
): Promise<ZoneRouteBindings> {
|
|
938
|
+
const [allowedZoneId, earnShare, earnVault, privateAsset, vaultAsset, deposit, redeem] =
|
|
939
|
+
await Promise.all([
|
|
940
|
+
client.readContract({
|
|
941
|
+
abi: Abis.earnRouter,
|
|
942
|
+
address: options.earnRouter,
|
|
943
|
+
functionName: 'allowedZoneId',
|
|
944
|
+
}),
|
|
945
|
+
client.readContract({
|
|
946
|
+
abi: Abis.earnRouter,
|
|
947
|
+
address: options.earnRouter,
|
|
948
|
+
functionName: 'earnShare',
|
|
949
|
+
}),
|
|
950
|
+
client.readContract({
|
|
951
|
+
abi: Abis.earnRouter,
|
|
952
|
+
address: options.earnRouter,
|
|
953
|
+
functionName: 'earnVault',
|
|
954
|
+
}),
|
|
955
|
+
client.readContract({
|
|
956
|
+
abi: Abis.earnRouter,
|
|
957
|
+
address: options.earnRouter,
|
|
958
|
+
functionName: 'privateAsset',
|
|
959
|
+
}),
|
|
960
|
+
client.readContract({
|
|
961
|
+
abi: Abis.earnRouter,
|
|
962
|
+
address: options.earnRouter,
|
|
963
|
+
functionName: 'vaultAsset',
|
|
964
|
+
}),
|
|
965
|
+
client.readContract({
|
|
966
|
+
abi: Abis.earnRouter,
|
|
967
|
+
address: options.earnRouter,
|
|
968
|
+
args: [0],
|
|
969
|
+
functionName: 'supportsFlow',
|
|
970
|
+
}),
|
|
971
|
+
client.readContract({
|
|
972
|
+
abi: Abis.earnRouter,
|
|
973
|
+
address: options.earnRouter,
|
|
974
|
+
args: [1],
|
|
975
|
+
functionName: 'supportsFlow',
|
|
976
|
+
}),
|
|
977
|
+
])
|
|
978
|
+
return { allowedZoneId, deposit, earnShare, earnVault, privateAsset, redeem, vaultAsset }
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
declare namespace readZoneRouteBindings {
|
|
982
|
+
type Options = {
|
|
983
|
+
/** Parent-chain Earn router to inspect. */
|
|
984
|
+
earnRouter: Address
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
732
988
|
async function readRouterCapabilities(
|
|
733
989
|
client: Client,
|
|
734
990
|
options: readRouterCapabilities.Options,
|
|
@@ -840,6 +1096,27 @@ function compareAddress(
|
|
|
840
1096
|
if (!isAddressEqual(actual, expected)) issues.push({ actual, code, expected, message })
|
|
841
1097
|
}
|
|
842
1098
|
|
|
1099
|
+
function mismatch(options: mismatch.Options): VerificationError {
|
|
1100
|
+
return new VerificationError({
|
|
1101
|
+
issues: options.issues,
|
|
1102
|
+
snapshot: {
|
|
1103
|
+
assetToken: options.discovery.assetToken,
|
|
1104
|
+
isSynced: options.discovery.state.isAccountingAligned,
|
|
1105
|
+
shareToken: options.discovery.shareToken,
|
|
1106
|
+
},
|
|
1107
|
+
status: 'mismatch',
|
|
1108
|
+
})
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
declare namespace mismatch {
|
|
1112
|
+
type Options = {
|
|
1113
|
+
/** Live vault state captured with the mismatch. */
|
|
1114
|
+
discovery: Discovery
|
|
1115
|
+
/** Verification issues that rejected the deployment. */
|
|
1116
|
+
issues: readonly VerificationIssue[]
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
843
1120
|
function unavailable(): VerificationUnavailable {
|
|
844
1121
|
return {
|
|
845
1122
|
issues: [
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as http from 'node:http'
|
|
2
|
+
|
|
3
|
+
import * as Fetch from './Fetch.js'
|
|
4
|
+
|
|
5
|
+
describe('withTimeout', () => {
|
|
6
|
+
test('aborts a fetch after the configured duration', async () => {
|
|
7
|
+
const server = http.createServer(() => {})
|
|
8
|
+
const url = await listen(server)
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const fetch = Fetch.withTimeout(globalThis.fetch, { timeout: 10 })
|
|
12
|
+
await expect(fetch(url)).rejects.toMatchObject({ name: 'TimeoutError' })
|
|
13
|
+
} finally {
|
|
14
|
+
server.closeAllConnections()
|
|
15
|
+
await close(server)
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
describe('resolveSignal', () => {
|
|
21
|
+
test('preserves caller and Request signals', () => {
|
|
22
|
+
const signal = AbortSignal.timeout(1_000)
|
|
23
|
+
const request = new Request('https://api.tempo.xyz', { signal })
|
|
24
|
+
|
|
25
|
+
expect(Fetch.resolveSignal('https://api.tempo.xyz', { init: { signal }, timeout: 10 })).toBe(
|
|
26
|
+
signal,
|
|
27
|
+
)
|
|
28
|
+
expect(Fetch.resolveSignal(request, { timeout: 10 })).toBe(request.signal)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function close(server: http.Server): Promise<void> {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
server.close((error) => (error ? reject(error) : resolve()))
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function listen(server: http.Server): Promise<string> {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
server.listen(0, '127.0.0.1', () => {
|
|
41
|
+
const address = server.address()
|
|
42
|
+
if (!address || typeof address === 'string') throw new Error('Expected a TCP server address.')
|
|
43
|
+
resolve(`http://127.0.0.1:${address.port}`)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
}
|