tapimo 0.0.2 → 0.2.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/README.md +38 -16
- package/dist/ApiKey.d.ts +14 -11
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +11 -12
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +207 -0
- package/dist/ApiKeys.d.ts.map +1 -0
- package/dist/ApiKeys.js +282 -0
- package/dist/ApiKeys.js.map +1 -0
- package/dist/App.d.ts +6771 -3819
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +145 -317
- package/dist/App.js.map +1 -1
- package/dist/Handler.d.ts +86 -0
- package/dist/Handler.d.ts.map +1 -0
- package/dist/Handler.js +83 -0
- package/dist/Handler.js.map +1 -0
- package/dist/Scope.d.ts +14 -4
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +16 -4
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +5 -7
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +11 -4
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/Access.d.ts +1 -3
- package/dist/admin/Access.d.ts.map +1 -1
- package/dist/admin/Access.js +1 -3
- package/dist/admin/Access.js.map +1 -1
- package/dist/admin/App.d.ts +167 -205
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +2 -4
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +105 -5
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +75 -9
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/scopes.d.ts +6 -0
- package/dist/admin/apps/scopes.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +35 -149
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +18 -39
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +1 -1
- package/dist/apps/data/App.d.ts +19176 -0
- package/dist/apps/data/App.d.ts.map +1 -0
- package/dist/apps/data/App.js +236 -0
- package/dist/apps/data/App.js.map +1 -0
- package/dist/apps/data/index.d.ts +3 -0
- package/dist/apps/data/index.d.ts.map +1 -0
- package/dist/apps/data/index.js +3 -0
- package/dist/apps/data/index.js.map +1 -0
- package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
- package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
- package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
- package/dist/apps/data/routes/activities.js.map +1 -0
- package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
- package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
- package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
- package/dist/apps/data/routes/addresses.js.map +1 -0
- package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +49 -49
- package/dist/apps/data/routes/balances.d.ts.map +1 -0
- package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
- package/dist/apps/data/routes/balances.js.map +1 -0
- package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
- package/dist/apps/data/routes/blocks.d.ts.map +1 -0
- package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
- package/dist/apps/data/routes/blocks.js.map +1 -0
- package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +183 -183
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
- package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
- package/dist/apps/data/routes/coingecko.js.map +1 -0
- package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +460 -460
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
- package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
- package/dist/apps/data/routes/exchanges.js.map +1 -0
- package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +94 -94
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
- package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
- package/dist/apps/data/routes/fee-amm.js.map +1 -0
- package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
- package/dist/apps/data/routes/indexer.d.ts.map +1 -0
- package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
- package/dist/apps/data/routes/indexer.js.map +1 -0
- package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +6 -6
- package/dist/apps/data/routes/receipts.d.ts.map +1 -0
- package/dist/apps/{receipts.js → data/routes/receipts.js} +12 -12
- package/dist/apps/data/routes/receipts.js.map +1 -0
- package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +4 -4
- package/dist/apps/data/routes/rpc.d.ts.map +1 -0
- package/dist/apps/{rpc.js → data/routes/rpc.js} +6 -6
- package/dist/apps/data/routes/rpc.js.map +1 -0
- package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +4 -4
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
- package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
- package/dist/apps/data/routes/tokenlist.js.map +1 -0
- package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +11 -11
- package/dist/apps/data/routes/tokens.d.ts.map +1 -0
- package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
- package/dist/apps/data/routes/tokens.js.map +1 -0
- package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +288 -288
- package/dist/apps/data/routes/transactions.d.ts.map +1 -0
- package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
- package/dist/apps/data/routes/transactions.js.map +1 -0
- package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +35 -35
- package/dist/apps/data/routes/transfers.d.ts.map +1 -0
- package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
- package/dist/apps/data/routes/transfers.js.map +1 -0
- package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +42 -42
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
- package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
- package/dist/apps/data/routes/verified-tokens.js.map +1 -0
- package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +66 -63
- package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
- package/dist/apps/{webhooks.js → data/routes/webhooks.js} +67 -59
- package/dist/apps/data/routes/webhooks.js.map +1 -0
- package/dist/apps/docs/App.d.ts +27 -0
- package/dist/apps/docs/App.d.ts.map +1 -0
- package/dist/apps/docs/App.js +122 -0
- package/dist/apps/docs/App.js.map +1 -0
- package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
- package/dist/apps/docs/fonts.d.ts.map +1 -0
- package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
- package/dist/apps/docs/fonts.js.map +1 -0
- package/dist/apps/docs/index.d.ts +2 -0
- package/dist/apps/docs/index.d.ts.map +1 -0
- package/dist/apps/docs/index.js +2 -0
- package/dist/apps/docs/index.js.map +1 -0
- package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
- package/dist/apps/docs/logo.d.ts.map +1 -0
- package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
- package/dist/apps/docs/logo.js.map +1 -0
- package/dist/apps/index.d.ts +4 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +4 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/metadata.d.ts +7 -0
- package/dist/apps/metadata.d.ts.map +1 -0
- package/dist/apps/metadata.js +15 -0
- package/dist/apps/metadata.js.map +1 -0
- package/dist/apps/platform/App.d.ts +2985 -0
- package/dist/apps/platform/App.d.ts.map +1 -0
- package/dist/apps/platform/App.js +74 -0
- package/dist/apps/platform/App.js.map +1 -0
- package/dist/apps/platform/index.d.ts +2 -0
- package/dist/apps/platform/index.d.ts.map +1 -0
- package/dist/apps/platform/index.js +2 -0
- package/dist/apps/platform/index.js.map +1 -0
- package/dist/apps/platform/routes/api-keys.d.ts +681 -0
- package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
- package/dist/apps/platform/routes/api-keys.js +328 -0
- package/dist/apps/platform/routes/api-keys.js.map +1 -0
- package/dist/apps/platform/routes/invitations.d.ts +733 -0
- package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
- package/dist/apps/platform/routes/invitations.js +413 -0
- package/dist/apps/platform/routes/invitations.js.map +1 -0
- package/dist/apps/platform/routes/me.d.ts +95 -0
- package/dist/apps/platform/routes/me.d.ts.map +1 -0
- package/dist/apps/platform/routes/me.js +81 -0
- package/dist/apps/platform/routes/me.js.map +1 -0
- package/dist/apps/platform/routes/members.d.ts +554 -0
- package/dist/apps/platform/routes/members.d.ts.map +1 -0
- package/dist/apps/platform/routes/members.js +251 -0
- package/dist/apps/platform/routes/members.js.map +1 -0
- package/dist/apps/platform/routes/orgs.d.ts +582 -0
- package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
- package/dist/apps/platform/routes/orgs.js +265 -0
- package/dist/apps/platform/routes/orgs.js.map +1 -0
- package/dist/apps/platform/routes/projects.d.ts +740 -0
- package/dist/apps/platform/routes/projects.d.ts.map +1 -0
- package/dist/apps/platform/routes/projects.js +286 -0
- package/dist/apps/platform/routes/projects.js.map +1 -0
- package/dist/apps/relay/App.d.ts +41 -0
- package/dist/apps/relay/App.d.ts.map +1 -0
- package/dist/apps/relay/App.js +103 -0
- package/dist/apps/relay/App.js.map +1 -0
- package/dist/apps/relay/Sponsorships.d.ts +107 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
- package/dist/apps/relay/Sponsorships.js +193 -0
- package/dist/apps/relay/Sponsorships.js.map +1 -0
- package/dist/apps/relay/index.d.ts +3 -0
- package/dist/apps/relay/index.d.ts.map +1 -0
- package/dist/apps/relay/index.js +3 -0
- package/dist/apps/relay/index.js.map +1 -0
- package/dist/{Cli.d.ts → cli/Cli.d.ts} +13 -2
- package/dist/cli/Cli.d.ts.map +1 -0
- package/dist/cli/Cli.js +19 -0
- package/dist/cli/Cli.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +4 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +15 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +60 -0
- package/dist/cli/commands/admin.js.map +1 -0
- package/dist/cloudflare.d.ts +7 -0
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +9 -0
- package/dist/cloudflare.js.map +1 -1
- package/dist/db/Db.d.ts +113 -0
- package/dist/db/Db.d.ts.map +1 -0
- package/dist/db/Db.js +402 -0
- package/dist/db/Db.js.map +1 -0
- package/dist/db/Schema.d.ts +168 -0
- package/dist/db/Schema.d.ts.map +1 -0
- package/dist/db/Schema.js +229 -0
- package/dist/db/Schema.js.map +1 -0
- package/dist/db/tables/invitations.d.ts +84 -0
- package/dist/db/tables/invitations.d.ts.map +1 -0
- package/dist/db/tables/invitations.js +165 -0
- package/dist/db/tables/invitations.js.map +1 -0
- package/dist/db/tables/memberships.d.ts +108 -0
- package/dist/db/tables/memberships.d.ts.map +1 -0
- package/dist/db/tables/memberships.js +153 -0
- package/dist/db/tables/memberships.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +123 -0
- package/dist/db/tables/organizations.d.ts.map +1 -0
- package/dist/db/tables/organizations.js +170 -0
- package/dist/db/tables/organizations.js.map +1 -0
- package/dist/db/tables/projects.d.ts +65 -0
- package/dist/db/tables/projects.d.ts.map +1 -0
- package/dist/db/tables/projects.js +75 -0
- package/dist/db/tables/projects.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +120 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
- package/dist/db/tables/sponsoredTransactions.js +161 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -0
- package/dist/db/tables/users.d.ts +48 -0
- package/dist/db/tables/users.d.ts.map +1 -0
- package/dist/db/tables/users.js +65 -0
- package/dist/db/tables/users.js.map +1 -0
- package/dist/db/tables/verifiedTokens.d.ts +53 -0
- package/dist/db/tables/verifiedTokens.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokens.js +74 -0
- package/dist/db/tables/verifiedTokens.js.map +1 -0
- package/dist/db/tables/webhookDeliveries.d.ts +71 -0
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -0
- package/dist/db/tables/webhookDeliveries.js +119 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +158 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -0
- package/dist/db/tables/webhookSubscriptions.js +272 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -0
- package/dist/handlers/internal/executionError.d.ts +25 -0
- package/dist/handlers/internal/executionError.d.ts.map +1 -0
- package/dist/handlers/internal/executionError.js +186 -0
- package/dist/handlers/internal/executionError.js.map +1 -0
- package/dist/handlers/internal/multisig.d.ts +233 -0
- package/dist/handlers/internal/multisig.d.ts.map +1 -0
- package/dist/handlers/internal/multisig.js +542 -0
- package/dist/handlers/internal/multisig.js.map +1 -0
- package/dist/handlers/internal/requestListener.d.ts +124 -0
- package/dist/handlers/internal/requestListener.d.ts.map +1 -0
- package/dist/handlers/internal/requestListener.js +173 -0
- package/dist/handlers/internal/requestListener.js.map +1 -0
- package/dist/handlers/internal/sponsorship.d.ts +113 -0
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -0
- package/dist/handlers/internal/sponsorship.js +128 -0
- package/dist/handlers/internal/sponsorship.js.map +1 -0
- package/dist/handlers/internal/types.d.ts +284 -0
- package/dist/handlers/internal/types.d.ts.map +1 -0
- package/dist/handlers/internal/types.js +2 -0
- package/dist/handlers/internal/types.js.map +1 -0
- package/dist/handlers/internal/utils.d.ts +34 -0
- package/dist/handlers/internal/utils.d.ts.map +1 -0
- package/dist/handlers/internal/utils.js +131 -0
- package/dist/handlers/internal/utils.js.map +1 -0
- package/dist/handlers/relay.d.ts +123 -0
- package/dist/handlers/relay.d.ts.map +1 -0
- package/dist/handlers/relay.js +1278 -0
- package/dist/handlers/relay.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/Auth.d.ts +224 -16
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +572 -33
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Log.d.ts +7 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +4 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +0 -19
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +0 -57
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/RpcSchema.d.ts +10 -0
- package/dist/internal/RpcSchema.d.ts.map +1 -0
- package/dist/internal/RpcSchema.js +2 -0
- package/dist/internal/RpcSchema.js.map +1 -0
- package/dist/internal/Store.d.ts +49 -4
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +81 -5
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts +15 -34
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +115 -159
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Viem.d.ts +84 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Webhooks.d.ts +50 -36
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +92 -205
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +37 -6
- package/src/ApiKey.test.ts +3 -3
- package/src/ApiKey.ts +11 -12
- package/src/ApiKeys.test.ts +278 -0
- package/src/ApiKeys.ts +358 -0
- package/src/App.test-d.ts +1 -1
- package/src/App.test.ts +40508 -19083
- package/src/App.ts +239 -416
- package/src/Client.test-d.ts +307 -16
- package/src/Handler.ts +154 -0
- package/src/Scope.ts +17 -4
- package/src/Webhooks.test.ts +8 -7
- package/src/Webhooks.ts +13 -7
- package/src/admin/Access.ts +1 -3
- package/src/admin/App.ts +19 -24
- package/src/admin/apps/api-keys.test.ts +70 -18
- package/src/admin/apps/api-keys.ts +92 -9
- package/src/admin/apps/scopes.test.ts +8 -0
- package/src/admin/apps/verified-tokens.test.ts +3 -30
- package/src/admin/apps/verified-tokens.ts +18 -37
- package/src/admin/ui.generated.ts +1 -1
- package/src/apps/composition.test.ts +66 -0
- package/src/apps/data/App.ts +295 -0
- package/src/apps/data/index.ts +2 -0
- package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
- package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
- package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
- package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +6 -5
- package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
- package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +4 -4
- package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
- package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
- package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
- package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +2 -2
- package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
- package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
- package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
- package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +27 -6
- package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
- package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +4 -4
- package/src/apps/{receipts.ts → data/routes/receipts.ts} +13 -13
- package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +142 -13
- package/src/apps/{rpc.ts → data/routes/rpc.ts} +7 -7
- package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +8 -10
- package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
- package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +6 -5
- package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
- package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +4 -4
- package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
- package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +3 -3
- package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
- package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +27 -15
- package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
- package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +137 -150
- package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +83 -81
- package/src/apps/docs/App.ts +136 -0
- package/src/apps/docs/index.ts +1 -0
- package/src/apps/index.ts +3 -0
- package/src/apps/metadata.ts +23 -0
- package/src/apps/platform/App.ts +130 -0
- package/src/apps/platform/index.ts +1 -0
- package/src/apps/platform/routes/api-keys.test.ts +330 -0
- package/src/apps/platform/routes/api-keys.ts +427 -0
- package/src/apps/platform/routes/invitations.test.ts +361 -0
- package/src/apps/platform/routes/invitations.ts +519 -0
- package/src/apps/platform/routes/me.test.ts +121 -0
- package/src/apps/platform/routes/me.ts +106 -0
- package/src/apps/platform/routes/members.test.ts +195 -0
- package/src/apps/platform/routes/members.ts +313 -0
- package/src/apps/platform/routes/orgs.test.ts +313 -0
- package/src/apps/platform/routes/orgs.ts +343 -0
- package/src/apps/platform/routes/projects.test.ts +181 -0
- package/src/apps/platform/routes/projects.ts +367 -0
- package/src/apps/relay/App.test.ts +484 -0
- package/src/apps/relay/App.ts +128 -0
- package/src/apps/relay/Sponsorships.test.ts +375 -0
- package/src/apps/relay/Sponsorships.ts +305 -0
- package/src/apps/relay/index.ts +2 -0
- package/src/{Cli.test.ts → cli/Cli.test.ts} +10 -9
- package/src/{Cli.ts → cli/Cli.ts} +16 -9
- package/src/cli/bin.ts +4 -0
- package/src/cli/commands/admin.test.ts +71 -0
- package/src/cli/commands/admin.ts +60 -0
- package/src/cloudflare.ts +10 -0
- package/src/db/Db.test.ts +84 -0
- package/src/db/Db.ts +542 -0
- package/src/db/Schema.ts +301 -0
- package/src/db/tables/invitations.ts +198 -0
- package/src/db/tables/memberships.ts +208 -0
- package/src/db/tables/organizations.test.ts +160 -0
- package/src/db/tables/organizations.ts +232 -0
- package/src/db/tables/projects.ts +107 -0
- package/src/db/tables/sponsoredTransactions.test.ts +218 -0
- package/src/db/tables/sponsoredTransactions.ts +236 -0
- package/src/db/tables/users.ts +85 -0
- package/src/db/tables/verifiedTokens.ts +111 -0
- package/src/db/tables/webhookDeliveries.ts +159 -0
- package/src/db/tables/webhookSubscriptions.ts +358 -0
- package/src/handlers/internal/executionError.ts +207 -0
- package/src/handlers/internal/multisig.test.ts +818 -0
- package/src/handlers/internal/multisig.ts +823 -0
- package/src/handlers/internal/requestListener.ts +273 -0
- package/src/handlers/internal/sponsorship.ts +245 -0
- package/src/handlers/internal/types.ts +378 -0
- package/src/handlers/internal/utils.ts +153 -0
- package/src/handlers/relay.test.ts +2035 -0
- package/src/handlers/relay.ts +1623 -0
- package/src/index.ts +4 -2
- package/src/internal/Auth.test.ts +337 -21
- package/src/internal/Auth.ts +783 -44
- package/src/internal/Cursor.test.ts +3 -2
- package/src/internal/Log.test.ts +1 -1
- package/src/internal/Log.ts +11 -3
- package/src/internal/MetricSink.ts +1 -1
- package/src/internal/OpenApi.ts +0 -59
- package/src/internal/RateLimit.test.ts +1 -1
- package/src/internal/RpcSchema.ts +10 -0
- package/src/internal/Store.test.ts +150 -10
- package/src/internal/Store.ts +136 -11
- package/src/internal/Tidx.local.test.ts +1 -1
- package/src/internal/VerifiedTokens.test.ts +99 -115
- package/src/internal/VerifiedTokens.ts +123 -175
- package/src/internal/WebhookDestination.test.ts +1 -1
- package/src/internal/Webhooks.test.ts +111 -111
- package/src/internal/Webhooks.ts +103 -221
- package/dist/ApiKeySource.d.ts +0 -166
- package/dist/ApiKeySource.d.ts.map +0 -1
- package/dist/ApiKeySource.js +0 -234
- package/dist/ApiKeySource.js.map +0 -1
- package/dist/Cli.d.ts.map +0 -1
- package/dist/Cli.js +0 -13
- package/dist/Cli.js.map +0 -1
- package/dist/apps/activities.js.map +0 -1
- package/dist/apps/addresses.js.map +0 -1
- package/dist/apps/balances.d.ts.map +0 -1
- package/dist/apps/balances.js.map +0 -1
- package/dist/apps/blocks.d.ts.map +0 -1
- package/dist/apps/blocks.js.map +0 -1
- package/dist/apps/coingecko.d.ts.map +0 -1
- package/dist/apps/coingecko.js.map +0 -1
- package/dist/apps/exchanges.d.ts.map +0 -1
- package/dist/apps/exchanges.js.map +0 -1
- package/dist/apps/fee-amm.d.ts.map +0 -1
- package/dist/apps/fee-amm.js.map +0 -1
- package/dist/apps/indexer.d.ts.map +0 -1
- package/dist/apps/indexer.js.map +0 -1
- package/dist/apps/receipts.d.ts.map +0 -1
- package/dist/apps/receipts.js.map +0 -1
- package/dist/apps/rpc.d.ts.map +0 -1
- package/dist/apps/rpc.js.map +0 -1
- package/dist/apps/tokenlist.d.ts.map +0 -1
- package/dist/apps/tokenlist.js.map +0 -1
- package/dist/apps/tokens.d.ts.map +0 -1
- package/dist/apps/tokens.js.map +0 -1
- package/dist/apps/transactions.d.ts.map +0 -1
- package/dist/apps/transactions.js.map +0 -1
- package/dist/apps/transfers.d.ts.map +0 -1
- package/dist/apps/transfers.js.map +0 -1
- package/dist/apps/verified-tokens.d.ts.map +0 -1
- package/dist/apps/verified-tokens.js.map +0 -1
- package/dist/apps/webhooks.js.map +0 -1
- package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
- package/dist/internal/OpenApi.fonts.js.map +0 -1
- package/dist/internal/OpenApi.logo.d.ts.map +0 -1
- package/dist/internal/OpenApi.logo.js.map +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
- package/seeds/31318/verified-tokens.json +0 -30
- package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
- package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +0 -4
- package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +0 -30
- package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +0 -11
- package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +0 -1
- package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +0 -5
- package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +0 -1
- package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +0 -1
- package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
- package/seeds/4217/verified-tokens.json +0 -177
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
- package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +0 -1
- package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +0 -1
- package/seeds/42431/verified-tokens.json +0 -44
- package/seeds/openrpc/README.md +0 -27
- package/seeds/openrpc/execution-apis.json +0 -8989
- package/src/ApiKeySource.test-d.ts +0 -11
- package/src/ApiKeySource.test.ts +0 -295
- package/src/ApiKeySource.ts +0 -303
- /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
- /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import type { Context } from 'hono'
|
|
2
|
+
import { sql } from 'kysely'
|
|
2
3
|
import { Hex } from 'ox'
|
|
3
4
|
import * as z from 'zod/mini'
|
|
4
5
|
|
|
5
6
|
import type * as App from '../App.js'
|
|
7
|
+
import * as Db from '../db/Db.js'
|
|
8
|
+
import * as core_VerifiedTokens from '../db/tables/verifiedTokens.js'
|
|
6
9
|
import * as Schema from './Schema.js'
|
|
7
|
-
import * as Store from './Store.js'
|
|
8
10
|
import * as Timing from './Timing.js'
|
|
9
11
|
|
|
10
12
|
/** Chain id covered by the curated verified-token lists. */
|
|
11
13
|
export type ChainId = z.output<typeof Schema.ChainId>
|
|
12
14
|
|
|
13
|
-
/** Schema for a chain's verified token list (
|
|
15
|
+
/** Schema for a chain's verified token list (validated at the write boundary). */
|
|
14
16
|
export const Data = z
|
|
15
17
|
.array(
|
|
16
18
|
z
|
|
@@ -68,7 +70,8 @@ export function compile(options: compile.Options): Snapshot {
|
|
|
68
70
|
const { chainId, tokens, updatedAt, version } = options
|
|
69
71
|
// Backfill the derived `id` (lowercased address) without re-parsing through
|
|
70
72
|
// `Data`/`Schema.Address`, which would lowercase the stored `address` and
|
|
71
|
-
// drop its curated checksum casing.
|
|
73
|
+
// drop its curated checksum casing. Validation happens at the write boundary
|
|
74
|
+
// (`normalize`); reads trust the typed columns.
|
|
72
75
|
const list: SnapshotToken[] = tokens.map((token) => ({
|
|
73
76
|
...token,
|
|
74
77
|
id: token.id ?? (token.address.toLowerCase() as Hex.Hex),
|
|
@@ -112,90 +115,34 @@ export declare namespace compile {
|
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
// Storage layout: one
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
const keyPrefix = 'verified-token:v1'
|
|
118
|
+
// Storage layout: one `verified_tokens` row per curated token (ordered by
|
|
119
|
+
// `position`) plus a per-chain `verified_token_lists` row carrying the opaque
|
|
120
|
+
// list `version` the soft-refresh cache and `If-Match` preconditions compare.
|
|
119
121
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const storeSchema = 1
|
|
122
|
+
/** A chain's list-level metadata (the "head" the cache compares against). */
|
|
123
|
+
export type Head = core_VerifiedTokens.Meta
|
|
123
124
|
|
|
124
|
-
/**
|
|
125
|
-
function
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/** Store key for a chain's immutable snapshot blob at a given version. */
|
|
130
|
-
function snapshotKey(chainId: ChainId, version: string): string {
|
|
131
|
-
return `${keyPrefix}:${chainId}:snapshot:${version}`
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Head pointer: tiny, read once per soft-TTL window to detect version changes
|
|
135
|
-
// without fetching the (much larger) token blob.
|
|
136
|
-
const Head = z
|
|
137
|
-
.object({
|
|
138
|
-
chainId: z.number().check(z.int(), z.describe('Chain the head belongs to.')),
|
|
139
|
-
count: z.number().check(z.int(), z.nonnegative(), z.describe('Token count at this version.')),
|
|
140
|
-
schema: z.number().check(z.int(), z.describe('Storage schema version.')),
|
|
141
|
-
updatedAt: z.string().check(z.describe('ISO timestamp of the last publish.')),
|
|
142
|
-
version: z.string().check(z.describe('Current snapshot version.')),
|
|
143
|
-
})
|
|
144
|
-
.check(z.describe('Verified-token head pointer stored under the head key.'))
|
|
145
|
-
|
|
146
|
-
// Immutable per-version blob holding the validated token list.
|
|
147
|
-
const Blob = z
|
|
148
|
-
.object({
|
|
149
|
-
chainId: z.number().check(z.int(), z.describe('Chain the blob belongs to.')),
|
|
150
|
-
schema: z.number().check(z.int(), z.describe('Storage schema version.')),
|
|
151
|
-
tokens: Data,
|
|
152
|
-
updatedAt: z.string().check(z.describe('ISO timestamp of the last publish.')),
|
|
153
|
-
version: z.string().check(z.describe('Snapshot version this blob holds.')),
|
|
154
|
-
})
|
|
155
|
-
.check(z.describe('Verified-token snapshot blob stored under a versioned key.'))
|
|
156
|
-
|
|
157
|
-
/** Parsed head pointer for a chain. */
|
|
158
|
-
export type Head = z.output<typeof Head>
|
|
159
|
-
|
|
160
|
-
/** Reads a chain's head pointer, or `null` when the chain has no head yet. */
|
|
161
|
-
async function readHead(store: Store.State, chainId: ChainId): Promise<Head | null> {
|
|
162
|
-
const raw = await store.get(headKey(chainId))
|
|
163
|
-
if (!raw) return null
|
|
164
|
-
return Head.parse(JSON.parse(raw))
|
|
125
|
+
/** Reads a chain's list metadata, or `null` when it has no list yet. */
|
|
126
|
+
async function readHead(db: Db.Db, chainId: ChainId): Promise<Head | null> {
|
|
127
|
+
return (await core_VerifiedTokens.head(db, chainId)) ?? null
|
|
165
128
|
}
|
|
166
129
|
|
|
167
130
|
/**
|
|
168
|
-
* Reads and compiles a chain's
|
|
169
|
-
*
|
|
170
|
-
* never happen given the write-blob-before-flip-head ordering).
|
|
131
|
+
* Reads and compiles a chain's current verified list. Returns `null` when the
|
|
132
|
+
* chain has none.
|
|
171
133
|
*/
|
|
172
|
-
async function
|
|
173
|
-
const
|
|
174
|
-
if (!
|
|
175
|
-
const
|
|
176
|
-
const blob = Blob.parse({
|
|
177
|
-
...parsed,
|
|
178
|
-
tokens: Array.isArray(parsed.tokens) ? withIds(parsed.tokens) : parsed.tokens,
|
|
179
|
-
})
|
|
134
|
+
export async function read(db: Db.Db, chainId: ChainId): Promise<Snapshot | null> {
|
|
135
|
+
const head = await readHead(db, chainId)
|
|
136
|
+
if (!head) return null
|
|
137
|
+
const rows = await core_VerifiedTokens.list(db, chainId)
|
|
180
138
|
return compile({
|
|
181
139
|
chainId,
|
|
182
|
-
tokens:
|
|
183
|
-
updatedAt:
|
|
184
|
-
version:
|
|
140
|
+
tokens: rows.map(core_VerifiedTokens.toToken),
|
|
141
|
+
updatedAt: head.updatedAt,
|
|
142
|
+
version: head.version,
|
|
185
143
|
})
|
|
186
144
|
}
|
|
187
145
|
|
|
188
|
-
/**
|
|
189
|
-
* Reads and compiles the snapshot a chain's head points at. Returns `null` when
|
|
190
|
-
* the chain has no head. Throws {@link TornStateError} when `head` references a
|
|
191
|
-
* missing snapshot blob.
|
|
192
|
-
*/
|
|
193
|
-
export async function read(store: Store.State, chainId: ChainId): Promise<Snapshot | null> {
|
|
194
|
-
const head = await readHead(store, chainId)
|
|
195
|
-
if (!head) return null
|
|
196
|
-
return readBlob(store, chainId, head.version)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
146
|
// Tracks the last epoch-ms used by `nextVersion` so versions stay strictly
|
|
200
147
|
// monotonic even when multiple writes land in the same millisecond.
|
|
201
148
|
let lastVersionMs = 0
|
|
@@ -246,48 +193,56 @@ function withIds(tokens: readonly unknown[]): unknown[] {
|
|
|
246
193
|
// Returns the current authoritative list for a chain to read-modify-write
|
|
247
194
|
// against: the durable snapshot, or an empty list when the chain has no head yet
|
|
248
195
|
// (the first write starts the chain's list from scratch).
|
|
249
|
-
async function currentList(
|
|
250
|
-
|
|
251
|
-
chainId: ChainId,
|
|
252
|
-
): Promise<readonly SnapshotToken[]> {
|
|
253
|
-
return (await read(store, chainId))?.list ?? []
|
|
196
|
+
async function currentList(db: Db.Db, chainId: ChainId): Promise<readonly SnapshotToken[]> {
|
|
197
|
+
return (await read(db, chainId))?.list ?? []
|
|
254
198
|
}
|
|
255
199
|
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
// lost-update window under concurrent writers.
|
|
200
|
+
// Optimistic concurrency: when `ifMatch` is set, the caller's expected version
|
|
201
|
+
// must equal the current head version. Runs inside the publish lock, so —
|
|
202
|
+
// unlike the old best-effort KV check — the compare-and-set actually holds.
|
|
260
203
|
async function assertVersion(
|
|
261
|
-
|
|
204
|
+
db: Db.Db,
|
|
262
205
|
chainId: ChainId,
|
|
263
206
|
ifMatch: string | undefined,
|
|
264
207
|
): Promise<void> {
|
|
265
208
|
if (ifMatch === undefined) return
|
|
266
|
-
const head = await readHead(
|
|
209
|
+
const head = await readHead(db, chainId)
|
|
267
210
|
const actual = head?.version ?? emptyVersion
|
|
268
211
|
if (actual !== ifMatch) throw new VersionMismatchError({ actual, chainId, expected: ifMatch })
|
|
269
212
|
}
|
|
270
213
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
214
|
+
/**
|
|
215
|
+
* Fixed first key for the per-chain publish advisory lock (the ASCII bytes of
|
|
216
|
+
* `"vtok"`); the chain id is the second key.
|
|
217
|
+
*/
|
|
218
|
+
const publishLockKey = 0x76746f6b
|
|
219
|
+
|
|
220
|
+
// Runs a write's read-modify-publish inside one transaction holding a
|
|
221
|
+
// per-chain advisory lock, serializing concurrent writers so `assertVersion`
|
|
222
|
+
// and the read-modify-write can't interleave (the lock releases on commit).
|
|
223
|
+
async function withPublishLock<value>(
|
|
224
|
+
db: Db.Db,
|
|
225
|
+
chainId: ChainId,
|
|
226
|
+
fn: (tx: Db.Db) => Promise<value>,
|
|
227
|
+
): Promise<value> {
|
|
228
|
+
return db.transaction(async (tx) => {
|
|
229
|
+
await sql`SELECT pg_advisory_xact_lock(${publishLockKey}, ${chainId})`.execute(tx.kysely)
|
|
230
|
+
return fn(tx)
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Validate-replace-prime: validate the whole list, replace the chain's rows
|
|
235
|
+
// and bump its list version (atomic inside the publish lock's transaction),
|
|
236
|
+
// then prime this isolate for read-your-write.
|
|
275
237
|
async function publish(
|
|
276
|
-
|
|
238
|
+
db: Db.Db,
|
|
277
239
|
chainId: ChainId,
|
|
278
240
|
tokens: readonly TokenInput[],
|
|
279
241
|
): Promise<Snapshot> {
|
|
280
242
|
const list = normalize(chainId, tokens)
|
|
281
243
|
const version = nextVersion()
|
|
282
244
|
const updatedAt = new Date().toISOString()
|
|
283
|
-
await
|
|
284
|
-
snapshotKey(chainId, version),
|
|
285
|
-
JSON.stringify({ chainId, schema: storeSchema, tokens: list, updatedAt, version }),
|
|
286
|
-
)
|
|
287
|
-
await store.put(
|
|
288
|
-
headKey(chainId),
|
|
289
|
-
JSON.stringify({ chainId, count: list.length, schema: storeSchema, updatedAt, version }),
|
|
290
|
-
)
|
|
245
|
+
await core_VerifiedTokens.publish(db, chainId, { tokens: list, updatedAt, version })
|
|
291
246
|
const snapshot = compile({ chainId, tokens: list, updatedAt, version })
|
|
292
247
|
prime(chainId, snapshot)
|
|
293
248
|
return snapshot
|
|
@@ -297,21 +252,23 @@ async function publish(
|
|
|
297
252
|
* Appends a verified token to a chain's list and publishes a new snapshot.
|
|
298
253
|
* Throws on a duplicate address or (case-insensitive) symbol.
|
|
299
254
|
*/
|
|
300
|
-
export async function create(
|
|
255
|
+
export async function create(db: Db.Db, input: create.Input): Promise<create.Result> {
|
|
301
256
|
const { chainId, currency, decimals, logoUri, name, symbol } = input
|
|
302
257
|
const address = input.address.toLowerCase() as Hex.Hex
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
258
|
+
return withPublishLock(db, chainId, async (tx) => {
|
|
259
|
+
const list = await currentList(tx, chainId)
|
|
260
|
+
const token: Token = {
|
|
261
|
+
address,
|
|
262
|
+
currency,
|
|
263
|
+
decimals,
|
|
264
|
+
id: address,
|
|
265
|
+
name,
|
|
266
|
+
symbol,
|
|
267
|
+
...(logoUri === undefined ? {} : { logoUri }),
|
|
268
|
+
}
|
|
269
|
+
const snapshot = await publish(tx, chainId, [...list, token])
|
|
270
|
+
return { snapshot, token: snapshot.byAddress.get(address)! }
|
|
271
|
+
})
|
|
315
272
|
}
|
|
316
273
|
|
|
317
274
|
export declare namespace create {
|
|
@@ -347,33 +304,35 @@ export declare namespace create {
|
|
|
347
304
|
* absent, and the uniqueness errors when an edit collides with another entry.
|
|
348
305
|
*/
|
|
349
306
|
export async function patch(
|
|
350
|
-
|
|
307
|
+
db: Db.Db,
|
|
351
308
|
chainId: ChainId,
|
|
352
309
|
address: string,
|
|
353
310
|
input: patch.Input,
|
|
354
311
|
options: patch.Options = {},
|
|
355
312
|
): Promise<create.Result> {
|
|
356
|
-
await assertVersion(store, chainId, options.ifMatch)
|
|
357
313
|
const target = address.toLowerCase() as Hex.Hex
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
314
|
+
return withPublishLock(db, chainId, async (tx) => {
|
|
315
|
+
await assertVersion(tx, chainId, options.ifMatch)
|
|
316
|
+
const list = await currentList(tx, chainId)
|
|
317
|
+
const index = list.findIndex((token) => token.address.toLowerCase() === target)
|
|
318
|
+
if (index === -1) throw new NotFoundError({ address: target, chainId })
|
|
319
|
+
// Edit in place, overriding only the fields the patch supplies.
|
|
320
|
+
const next = list.map((token, i) => {
|
|
321
|
+
if (i !== index) return token
|
|
322
|
+
const logoUri = input.logoUri ?? token.logoUri
|
|
323
|
+
return {
|
|
324
|
+
address: target,
|
|
325
|
+
currency: input.currency ?? token.currency,
|
|
326
|
+
decimals: input.decimals ?? token.decimals,
|
|
327
|
+
id: target,
|
|
328
|
+
name: input.name ?? token.name,
|
|
329
|
+
symbol: input.symbol ?? token.symbol,
|
|
330
|
+
...(logoUri === undefined ? {} : { logoUri }),
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
const snapshot = await publish(tx, chainId, next)
|
|
334
|
+
return { snapshot, token: snapshot.byAddress.get(target)! }
|
|
374
335
|
})
|
|
375
|
-
const snapshot = await publish(store, chainId, next)
|
|
376
|
-
return { snapshot, token: snapshot.byAddress.get(target)! }
|
|
377
336
|
}
|
|
378
337
|
|
|
379
338
|
export declare namespace patch {
|
|
@@ -402,17 +361,19 @@ export declare namespace patch {
|
|
|
402
361
|
* Throws {@link NotFoundError} when the address is absent.
|
|
403
362
|
*/
|
|
404
363
|
export async function remove(
|
|
405
|
-
|
|
364
|
+
db: Db.Db,
|
|
406
365
|
chainId: ChainId,
|
|
407
366
|
address: string,
|
|
408
367
|
options: patch.Options = {},
|
|
409
368
|
): Promise<remove.Result> {
|
|
410
|
-
await assertVersion(store, chainId, options.ifMatch)
|
|
411
369
|
const target = address.toLowerCase()
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
370
|
+
return withPublishLock(db, chainId, async (tx) => {
|
|
371
|
+
await assertVersion(tx, chainId, options.ifMatch)
|
|
372
|
+
const list = await currentList(tx, chainId)
|
|
373
|
+
const next = list.filter((token) => token.address.toLowerCase() !== target)
|
|
374
|
+
if (next.length === list.length) throw new NotFoundError({ address: target, chainId })
|
|
375
|
+
return { snapshot: await publish(tx, chainId, next) }
|
|
376
|
+
})
|
|
416
377
|
}
|
|
417
378
|
|
|
418
379
|
export declare namespace remove {
|
|
@@ -428,13 +389,15 @@ export declare namespace remove {
|
|
|
428
389
|
* bulk-load the initial list and to roll back to a previous one.
|
|
429
390
|
*/
|
|
430
391
|
export async function replace(
|
|
431
|
-
|
|
392
|
+
db: Db.Db,
|
|
432
393
|
chainId: ChainId,
|
|
433
394
|
tokens: readonly TokenInput[],
|
|
434
395
|
options: patch.Options = {},
|
|
435
396
|
): Promise<remove.Result> {
|
|
436
|
-
|
|
437
|
-
|
|
397
|
+
return withPublishLock(db, chainId, async (tx) => {
|
|
398
|
+
await assertVersion(tx, chainId, options.ifMatch)
|
|
399
|
+
return { snapshot: await publish(tx, chainId, tokens) }
|
|
400
|
+
})
|
|
438
401
|
}
|
|
439
402
|
|
|
440
403
|
// Sentinel version/time for the empty snapshot served before a chain has any
|
|
@@ -491,7 +454,7 @@ export function prime(chainId: ChainId, snapshot: Snapshot): void {
|
|
|
491
454
|
// chain share one in-flight refresh.
|
|
492
455
|
function refresh(
|
|
493
456
|
c: Context<App.Environment>,
|
|
494
|
-
|
|
457
|
+
db: Db.Db,
|
|
495
458
|
chainId: ChainId,
|
|
496
459
|
cell: Cell | undefined,
|
|
497
460
|
): Promise<Snapshot> {
|
|
@@ -499,7 +462,7 @@ function refresh(
|
|
|
499
462
|
if (existing) return existing
|
|
500
463
|
const flight = (async () => {
|
|
501
464
|
try {
|
|
502
|
-
return await refreshCell(c,
|
|
465
|
+
return await refreshCell(c, db, chainId, cell)
|
|
503
466
|
} finally {
|
|
504
467
|
refreshes.delete(chainId)
|
|
505
468
|
}
|
|
@@ -513,15 +476,15 @@ function refresh(
|
|
|
513
476
|
// when the chain has no head yet).
|
|
514
477
|
async function refreshCell(
|
|
515
478
|
c: Context<App.Environment>,
|
|
516
|
-
|
|
479
|
+
db: Db.Db,
|
|
517
480
|
chainId: ChainId,
|
|
518
481
|
cell: Cell | undefined,
|
|
519
482
|
): Promise<Snapshot> {
|
|
520
|
-
// Cold: no prior snapshot. Load from
|
|
521
|
-
// chain has no head. A hard failure here propagates (we have nothing good
|
|
522
|
-
// serve, and must not resurrect deleted tokens).
|
|
483
|
+
// Cold: no prior snapshot. Load from the database, or an empty snapshot when
|
|
484
|
+
// the chain has no head. A hard failure here propagates (we have nothing good
|
|
485
|
+
// to serve, and must not resurrect deleted tokens).
|
|
523
486
|
if (!cell) {
|
|
524
|
-
const loaded = await Timing.time(c, 'verified_snapshot', () => read(
|
|
487
|
+
const loaded = await Timing.time(c, 'verified_snapshot', () => read(db, chainId))
|
|
525
488
|
const snapshot = loaded ?? emptySnapshot(chainId)
|
|
526
489
|
cells.set(chainId, { checkedAt: Date.now(), snapshot })
|
|
527
490
|
return snapshot
|
|
@@ -530,16 +493,15 @@ async function refreshCell(
|
|
|
530
493
|
// Soft-stale: serve the last good in-memory snapshot and log loudly on
|
|
531
494
|
// failure rather than dropping to empty (no resurrection of deleted tokens).
|
|
532
495
|
try {
|
|
533
|
-
const head = await Timing.time(c, 'verified_head', () => readHead(
|
|
496
|
+
const head = await Timing.time(c, 'verified_head', () => readHead(db, chainId))
|
|
534
497
|
// Unchanged version (or head not yet present): keep snapshot, bump checkedAt.
|
|
535
498
|
if (!head || head.version === cell.snapshot.version) {
|
|
536
499
|
cells.set(chainId, { checkedAt: Date.now(), snapshot: cell.snapshot })
|
|
537
500
|
return cell.snapshot
|
|
538
501
|
}
|
|
539
|
-
// Version changed:
|
|
540
|
-
const snapshot =
|
|
541
|
-
|
|
542
|
-
)
|
|
502
|
+
// Version changed: reload the current list (kept on a racing delete).
|
|
503
|
+
const snapshot =
|
|
504
|
+
(await Timing.time(c, 'verified_snapshot', () => read(db, chainId))) ?? cell.snapshot
|
|
543
505
|
cells.set(chainId, { checkedAt: Date.now(), snapshot })
|
|
544
506
|
return snapshot
|
|
545
507
|
} catch (error) {
|
|
@@ -553,32 +515,32 @@ async function refreshCell(
|
|
|
553
515
|
* Returns the compiled verified-token {@link Snapshot} for a chain.
|
|
554
516
|
*
|
|
555
517
|
* When the verified-tokens feature is unconfigured, serves an empty snapshot.
|
|
556
|
-
* When configured
|
|
557
|
-
* refreshed on a soft TTL: fresh lookups do zero
|
|
518
|
+
* When configured, serves a per-isolate snapshot backed by the app database,
|
|
519
|
+
* refreshed on a soft TTL: fresh lookups do zero database I/O; soft-stale
|
|
558
520
|
* lookups return the current snapshot immediately and refresh in the background
|
|
559
521
|
* (single-flight, head-only unless the version changed); a cold isolate loads
|
|
560
|
-
* from the
|
|
522
|
+
* from the database (an empty snapshot when no head exists).
|
|
561
523
|
*/
|
|
562
524
|
export async function snapshot(c: Context<App.Environment>, chainId: ChainId): Promise<Snapshot> {
|
|
563
525
|
return Timing.time(c, 'verified_tokens', () => {
|
|
564
526
|
const config = c.get('verifiedTokens')
|
|
565
|
-
// Unconfigured: nothing is verified. No
|
|
527
|
+
// Unconfigured: nothing is verified. No reads, no cell.
|
|
566
528
|
if (!config) return emptySnapshot(chainId)
|
|
567
529
|
|
|
568
530
|
const refreshMs = config.refreshMs ?? defaultRefreshMs
|
|
569
531
|
const cell = cells.get(chainId)
|
|
570
532
|
|
|
571
|
-
// Fresh: serve the in-memory snapshot with zero
|
|
533
|
+
// Fresh: serve the in-memory snapshot with zero database I/O.
|
|
572
534
|
if (cell && Date.now() - cell.checkedAt < refreshMs) return cell.snapshot
|
|
573
535
|
|
|
574
536
|
// Soft-stale: serve immediately, refresh in the background. Never blocks.
|
|
575
537
|
if (cell) {
|
|
576
|
-
void refresh(c,
|
|
538
|
+
void refresh(c, Db.get(c.get('dbCached')), chainId, cell)
|
|
577
539
|
return cell.snapshot
|
|
578
540
|
}
|
|
579
541
|
|
|
580
542
|
// Cold: must load before the first response.
|
|
581
|
-
return refresh(c,
|
|
543
|
+
return refresh(c, Db.get(c.get('dbCached')), chainId, undefined)
|
|
582
544
|
})
|
|
583
545
|
}
|
|
584
546
|
|
|
@@ -590,20 +552,6 @@ export async function snapshot(c: Context<App.Environment>, chainId: ChainId): P
|
|
|
590
552
|
*/
|
|
591
553
|
export const currencies = ['EUR', 'USD']
|
|
592
554
|
|
|
593
|
-
/**
|
|
594
|
-
* Thrown when a chain's `head` points at a snapshot version whose blob is
|
|
595
|
-
* missing from the store. The write path always writes the blob before flipping
|
|
596
|
-
* the head, so this indicates a torn write or external tampering.
|
|
597
|
-
*/
|
|
598
|
-
export class TornStateError extends Error {
|
|
599
|
-
override name = 'VerifiedTokens.TornStateError'
|
|
600
|
-
constructor(options: { chainId: number; version: string }) {
|
|
601
|
-
super(
|
|
602
|
-
`verified-token head for chain ${options.chainId} points at missing snapshot version "${options.version}".`,
|
|
603
|
-
)
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
555
|
/** Thrown when a write would introduce a duplicate address on a chain. */
|
|
608
556
|
export class DuplicateAddressError extends Error {
|
|
609
557
|
override name = 'VerifiedTokens.DuplicateAddressError'
|
|
@@ -3,7 +3,7 @@ import * as WebhookDestination from './WebhookDestination.js'
|
|
|
3
3
|
const envelope = {
|
|
4
4
|
chainId: 4217,
|
|
5
5
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
6
|
-
data: { amount: '1000', token: '
|
|
6
|
+
data: { amount: '1000', token: `0x${'aa'.repeat(20)}` },
|
|
7
7
|
id: 'evt_test',
|
|
8
8
|
subscriptionId: 'wh_test',
|
|
9
9
|
type: 'token:transfer',
|