tapimo 0.0.0 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/dist/ApiKey.d.ts +65 -0
- package/dist/ApiKey.d.ts.map +1 -0
- package/dist/ApiKey.js +105 -0
- package/dist/ApiKey.js.map +1 -0
- package/dist/ApiKeySource.d.ts +166 -0
- package/dist/ApiKeySource.d.ts.map +1 -0
- package/dist/ApiKeySource.js +234 -0
- package/dist/ApiKeySource.js.map +1 -0
- package/dist/App.d.ts +19317 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +612 -0
- package/dist/App.js.map +1 -0
- package/dist/Assets.d.ts +44 -0
- package/dist/Assets.d.ts.map +1 -0
- package/dist/Assets.js +23 -0
- package/dist/Assets.js.map +1 -0
- package/dist/Auth.d.ts +2 -0
- package/dist/Auth.d.ts.map +1 -0
- package/dist/Auth.js +2 -0
- package/dist/Auth.js.map +1 -0
- package/dist/Cli.d.ts +21 -0
- package/dist/Cli.d.ts.map +1 -0
- package/dist/Cli.js +13 -0
- package/dist/Cli.js.map +1 -0
- package/dist/Client.d.ts +20 -0
- package/dist/Client.d.ts.map +1 -0
- package/dist/Client.js +24 -0
- package/dist/Client.js.map +1 -0
- package/dist/Metrics.d.ts +70 -0
- package/dist/Metrics.d.ts.map +1 -0
- package/dist/Metrics.js +91 -0
- package/dist/Metrics.js.map +1 -0
- package/dist/Scope.d.ts +35 -0
- package/dist/Scope.d.ts.map +1 -0
- package/dist/Scope.js +38 -0
- package/dist/Scope.js.map +1 -0
- package/dist/Webhooks.d.ts +79 -0
- package/dist/Webhooks.d.ts.map +1 -0
- package/dist/Webhooks.js +107 -0
- package/dist/Webhooks.js.map +1 -0
- package/dist/admin/Access.d.ts +41 -0
- package/dist/admin/Access.d.ts.map +1 -0
- package/dist/admin/Access.js +75 -0
- package/dist/admin/Access.js.map +1 -0
- package/dist/admin/App.d.ts +1221 -0
- package/dist/admin/App.d.ts.map +1 -0
- package/dist/admin/App.js +113 -0
- package/dist/admin/App.js.map +1 -0
- package/dist/admin/apps/api-keys.d.ts +209 -0
- package/dist/admin/apps/api-keys.d.ts.map +1 -0
- package/dist/admin/apps/api-keys.js +129 -0
- package/dist/admin/apps/api-keys.js.map +1 -0
- package/dist/admin/apps/scopes.d.ts +46 -0
- package/dist/admin/apps/scopes.d.ts.map +1 -0
- package/dist/admin/apps/scopes.js +41 -0
- package/dist/admin/apps/scopes.js.map +1 -0
- package/dist/admin/apps/verified-tokens.d.ts +1206 -0
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -0
- package/dist/admin/apps/verified-tokens.js +485 -0
- package/dist/admin/apps/verified-tokens.js.map +1 -0
- package/dist/admin/index.d.ts +3 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +3 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/ui.generated.d.ts +11 -0
- package/dist/admin/ui.generated.d.ts.map +1 -0
- package/dist/admin/ui.generated.js +43 -0
- package/dist/admin/ui.generated.js.map +1 -0
- package/dist/apps/activities.d.ts +18725 -0
- package/dist/apps/activities.d.ts.map +1 -0
- package/dist/apps/activities.js +3138 -0
- package/dist/apps/activities.js.map +1 -0
- package/dist/apps/addresses.d.ts +3662 -0
- package/dist/apps/addresses.d.ts.map +1 -0
- package/dist/apps/addresses.js +22 -0
- package/dist/apps/addresses.js.map +1 -0
- package/dist/apps/balances.d.ts +342 -0
- package/dist/apps/balances.d.ts.map +1 -0
- package/dist/apps/balances.js +393 -0
- package/dist/apps/balances.js.map +1 -0
- package/dist/apps/blocks.d.ts +931 -0
- package/dist/apps/blocks.d.ts.map +1 -0
- package/dist/apps/blocks.js +689 -0
- package/dist/apps/blocks.js.map +1 -0
- package/dist/apps/coingecko.d.ts +1053 -0
- package/dist/apps/coingecko.d.ts.map +1 -0
- package/dist/apps/coingecko.js +1015 -0
- package/dist/apps/coingecko.js.map +1 -0
- package/dist/apps/exchanges.d.ts +3000 -0
- package/dist/apps/exchanges.d.ts.map +1 -0
- package/dist/apps/exchanges.js +3570 -0
- package/dist/apps/exchanges.js.map +1 -0
- package/dist/apps/fee-amm.d.ts +640 -0
- package/dist/apps/fee-amm.d.ts.map +1 -0
- package/dist/apps/fee-amm.js +815 -0
- package/dist/apps/fee-amm.js.map +1 -0
- package/dist/apps/indexer.d.ts +116 -0
- package/dist/apps/indexer.d.ts.map +1 -0
- package/dist/apps/indexer.js +270 -0
- package/dist/apps/indexer.js.map +1 -0
- package/dist/apps/receipts.d.ts +1438 -0
- package/dist/apps/receipts.d.ts.map +1 -0
- package/dist/apps/receipts.js +874 -0
- package/dist/apps/receipts.js.map +1 -0
- package/dist/apps/rpc.d.ts +173 -0
- package/dist/apps/rpc.d.ts.map +1 -0
- package/dist/apps/rpc.js +191 -0
- package/dist/apps/rpc.js.map +1 -0
- package/dist/apps/tokenlist.d.ts +192 -0
- package/dist/apps/tokenlist.d.ts.map +1 -0
- package/dist/apps/tokenlist.js +153 -0
- package/dist/apps/tokenlist.js.map +1 -0
- package/dist/apps/tokens.d.ts +2246 -0
- package/dist/apps/tokens.d.ts.map +1 -0
- package/dist/apps/tokens.js +1789 -0
- package/dist/apps/tokens.js.map +1 -0
- package/dist/apps/transactions.d.ts +2327 -0
- package/dist/apps/transactions.d.ts.map +1 -0
- package/dist/apps/transactions.js +975 -0
- package/dist/apps/transactions.js.map +1 -0
- package/dist/apps/transfers.d.ts +589 -0
- package/dist/apps/transfers.d.ts.map +1 -0
- package/dist/apps/transfers.js +769 -0
- package/dist/apps/transfers.js.map +1 -0
- package/dist/apps/verified-tokens.d.ts +544 -0
- package/dist/apps/verified-tokens.d.ts.map +1 -0
- package/dist/apps/verified-tokens.js +234 -0
- package/dist/apps/verified-tokens.js.map +1 -0
- package/dist/apps/webhooks.d.ts +7684 -0
- package/dist/apps/webhooks.d.ts.map +1 -0
- package/dist/apps/webhooks.js +2112 -0
- package/dist/apps/webhooks.js.map +1 -0
- package/dist/cloudflare.d.ts +32 -0
- package/dist/cloudflare.d.ts.map +1 -0
- package/dist/cloudflare.js +45 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/Auth.d.ts +298 -0
- package/dist/internal/Auth.d.ts.map +1 -0
- package/dist/internal/Auth.js +618 -0
- package/dist/internal/Auth.js.map +1 -0
- package/dist/internal/Cache.d.ts +74 -0
- package/dist/internal/Cache.d.ts.map +1 -0
- package/dist/internal/Cache.js +215 -0
- package/dist/internal/Cache.js.map +1 -0
- package/dist/internal/Cursor.d.ts +79 -0
- package/dist/internal/Cursor.d.ts.map +1 -0
- package/dist/internal/Cursor.js +116 -0
- package/dist/internal/Cursor.js.map +1 -0
- package/dist/internal/EdgeCache.d.ts +59 -0
- package/dist/internal/EdgeCache.d.ts.map +1 -0
- package/dist/internal/EdgeCache.js +174 -0
- package/dist/internal/EdgeCache.js.map +1 -0
- package/dist/internal/Log.d.ts +104 -0
- package/dist/internal/Log.d.ts.map +1 -0
- package/dist/internal/Log.js +118 -0
- package/dist/internal/Log.js.map +1 -0
- package/dist/internal/MetricSink.d.ts +65 -0
- package/dist/internal/MetricSink.d.ts.map +1 -0
- package/dist/internal/MetricSink.js +146 -0
- package/dist/internal/MetricSink.js.map +1 -0
- package/dist/internal/Mpp.d.ts +71 -0
- package/dist/internal/Mpp.d.ts.map +1 -0
- package/dist/internal/Mpp.js +105 -0
- package/dist/internal/Mpp.js.map +1 -0
- package/dist/internal/OpenApi.d.ts +313 -0
- package/dist/internal/OpenApi.d.ts.map +1 -0
- package/dist/internal/OpenApi.fonts.d.ts +2 -0
- package/dist/internal/OpenApi.fonts.d.ts.map +1 -0
- package/dist/internal/OpenApi.fonts.js +39 -0
- package/dist/internal/OpenApi.fonts.js.map +1 -0
- package/dist/internal/OpenApi.js +335 -0
- package/dist/internal/OpenApi.js.map +1 -0
- package/dist/internal/OpenApi.logo.d.ts +6 -0
- package/dist/internal/OpenApi.logo.d.ts.map +1 -0
- package/dist/internal/OpenApi.logo.js +19 -0
- package/dist/internal/OpenApi.logo.js.map +1 -0
- package/dist/internal/Path.d.ts +5 -0
- package/dist/internal/Path.d.ts.map +1 -0
- package/dist/internal/Path.js +16 -0
- package/dist/internal/Path.js.map +1 -0
- package/dist/internal/RateLimit.d.ts +60 -0
- package/dist/internal/RateLimit.d.ts.map +1 -0
- package/dist/internal/RateLimit.js +48 -0
- package/dist/internal/RateLimit.js.map +1 -0
- package/dist/internal/Response.d.ts +132 -0
- package/dist/internal/Response.d.ts.map +1 -0
- package/dist/internal/Response.js +72 -0
- package/dist/internal/Response.js.map +1 -0
- package/dist/internal/Schema.d.ts +257 -0
- package/dist/internal/Schema.d.ts.map +1 -0
- package/dist/internal/Schema.js +360 -0
- package/dist/internal/Schema.js.map +1 -0
- package/dist/internal/Store.d.ts +204 -0
- package/dist/internal/Store.d.ts.map +1 -0
- package/dist/internal/Store.js +291 -0
- package/dist/internal/Store.js.map +1 -0
- package/dist/internal/Tidx.d.ts +120 -0
- package/dist/internal/Tidx.d.ts.map +1 -0
- package/dist/internal/Tidx.js +156 -0
- package/dist/internal/Tidx.js.map +1 -0
- package/dist/internal/Timing.d.ts +22 -0
- package/dist/internal/Timing.d.ts.map +1 -0
- package/dist/internal/Timing.js +32 -0
- package/dist/internal/Timing.js.map +1 -0
- package/dist/internal/Ttl.d.ts +25 -0
- package/dist/internal/Ttl.d.ts.map +1 -0
- package/dist/internal/Ttl.js +49 -0
- package/dist/internal/Ttl.js.map +1 -0
- package/dist/internal/Value.d.ts +47 -0
- package/dist/internal/Value.d.ts.map +1 -0
- package/dist/internal/Value.js +122 -0
- package/dist/internal/Value.js.map +1 -0
- package/dist/internal/VerifiedTokens.d.ts +228 -0
- package/dist/internal/VerifiedTokens.d.ts.map +1 -0
- package/dist/internal/VerifiedTokens.js +450 -0
- package/dist/internal/VerifiedTokens.js.map +1 -0
- package/dist/internal/Viem.d.ts +2082 -0
- package/dist/internal/Viem.d.ts.map +1 -0
- package/dist/internal/Viem.js +63 -0
- package/dist/internal/Viem.js.map +1 -0
- package/dist/internal/WebhookDestination.d.ts +198 -0
- package/dist/internal/WebhookDestination.d.ts.map +1 -0
- package/dist/internal/WebhookDestination.js +170 -0
- package/dist/internal/WebhookDestination.js.map +1 -0
- package/dist/internal/Webhooks.d.ts +433 -0
- package/dist/internal/Webhooks.d.ts.map +1 -0
- package/dist/internal/Webhooks.js +489 -0
- package/dist/internal/Webhooks.js.map +1 -0
- package/dist/internal/webhookDestinations/betterStack.d.ts +26 -0
- package/dist/internal/webhookDestinations/betterStack.d.ts.map +1 -0
- package/dist/internal/webhookDestinations/betterStack.js +76 -0
- package/dist/internal/webhookDestinations/betterStack.js.map +1 -0
- package/dist/internal/webhookDestinations/slack.d.ts +59 -0
- package/dist/internal/webhookDestinations/slack.d.ts.map +1 -0
- package/dist/internal/webhookDestinations/slack.js +422 -0
- package/dist/internal/webhookDestinations/slack.js.map +1 -0
- package/dist/internal/webhookDestinations/url.d.ts +17 -0
- package/dist/internal/webhookDestinations/url.d.ts.map +1 -0
- package/dist/internal/webhookDestinations/url.js +130 -0
- package/dist/internal/webhookDestinations/url.js.map +1 -0
- package/dist/openrpc.json +5302 -0
- package/package.json +46 -4
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +1 -0
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +1 -0
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +1 -0
- package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +1 -0
- package/seeds/31318/verified-tokens.json +30 -0
- package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +25 -0
- package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +4 -0
- package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +30 -0
- package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +11 -0
- package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +1 -0
- package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
- package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +5 -0
- package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +1 -0
- package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +1 -0
- package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
- package/seeds/4217/verified-tokens.json +177 -0
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +25 -0
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +1 -0
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +1 -0
- package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +1 -0
- package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +1 -0
- package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +1 -0
- package/seeds/42431/verified-tokens.json +44 -0
- package/seeds/openrpc/README.md +27 -0
- package/seeds/openrpc/execution-apis.json +8989 -0
- package/src/ApiKey.test.ts +91 -0
- package/src/ApiKey.ts +122 -0
- package/src/ApiKeySource.test-d.ts +11 -0
- package/src/ApiKeySource.test.ts +295 -0
- package/src/ApiKeySource.ts +303 -0
- package/src/App.test-d.ts +38 -0
- package/src/App.test.ts +65927 -0
- package/src/App.ts +855 -0
- package/src/Assets.ts +58 -0
- package/src/Auth.ts +1 -0
- package/src/Cli.test.ts +81 -0
- package/src/Cli.ts +38 -0
- package/src/Client.test-d.ts +1438 -0
- package/src/Client.test.ts +134 -0
- package/src/Client.ts +45 -0
- package/src/Metrics.ts +154 -0
- package/src/Scope.ts +50 -0
- package/src/Webhooks.test.ts +49 -0
- package/src/Webhooks.ts +172 -0
- package/src/admin/Access.test.ts +130 -0
- package/src/admin/Access.ts +87 -0
- package/src/admin/App.test.ts +225 -0
- package/src/admin/App.ts +216 -0
- package/src/admin/apps/api-keys.test.ts +156 -0
- package/src/admin/apps/api-keys.ts +157 -0
- package/src/admin/apps/scopes.test.ts +52 -0
- package/src/admin/apps/scopes.ts +47 -0
- package/src/admin/apps/verified-tokens.test.ts +415 -0
- package/src/admin/apps/verified-tokens.ts +566 -0
- package/src/admin/index.ts +2 -0
- package/src/admin/ui/plugin.ts +135 -0
- package/src/admin/ui/src/components/Checkbox.tsx +22 -0
- package/src/admin/ui/src/components/Dialog.tsx +32 -0
- package/src/admin/ui/src/components/MobileProfile.tsx +31 -0
- package/src/admin/ui/src/components/Page.tsx +53 -0
- package/src/admin/ui/src/components/TempoLogo.tsx +37 -0
- package/src/admin/ui/src/fonts/Pilat-Demi.woff2 +0 -0
- package/src/admin/ui/src/fonts/Pilat-Regular.woff2 +0 -0
- package/src/admin/ui/src/lib/api-keys.ts +63 -0
- package/src/admin/ui/src/lib/client.ts +15 -0
- package/src/admin/ui/src/lib/config.ts +57 -0
- package/src/admin/ui/src/lib/query-client.ts +26 -0
- package/src/admin/ui/src/lib/scopes.ts +25 -0
- package/src/admin/ui/src/lib/verified-tokens.ts +89 -0
- package/src/admin/ui/src/lib/wagmi.ts +18 -0
- package/src/admin/ui/src/routeTree.gen.ts +104 -0
- package/src/admin/ui/src/router.tsx +25 -0
- package/src/admin/ui/src/routes/__root.tsx +219 -0
- package/src/admin/ui/src/routes/api-keys.tsx +329 -0
- package/src/admin/ui/src/routes/index.tsx +7 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +331 -0
- package/src/admin/ui/src/styles.css +20 -0
- package/src/admin/ui/tsconfig.json +16 -0
- package/src/admin/ui/vite.config.ts +29 -0
- package/src/admin/ui.generated.ts +60 -0
- package/src/apps/activities.test.ts +1020 -0
- package/src/apps/activities.ts +3934 -0
- package/src/apps/addresses.ts +24 -0
- package/src/apps/balances.test.ts +274 -0
- package/src/apps/balances.ts +533 -0
- package/src/apps/blocks.test.ts +385 -0
- package/src/apps/blocks.ts +896 -0
- package/src/apps/coingecko.test.ts +218 -0
- package/src/apps/coingecko.ts +1383 -0
- package/src/apps/exchanges.test.ts +958 -0
- package/src/apps/exchanges.ts +4773 -0
- package/src/apps/fee-amm.test.ts +321 -0
- package/src/apps/fee-amm.ts +1121 -0
- package/src/apps/indexer.test.ts +153 -0
- package/src/apps/indexer.ts +330 -0
- package/src/apps/receipts.test.ts +285 -0
- package/src/apps/receipts.ts +1193 -0
- package/src/apps/rpc.test.ts +302 -0
- package/src/apps/rpc.ts +222 -0
- package/src/apps/tokenlist.test.ts +80 -0
- package/src/apps/tokenlist.ts +207 -0
- package/src/apps/tokens.test.ts +1062 -0
- package/src/apps/tokens.ts +2292 -0
- package/src/apps/transactions.test.ts +408 -0
- package/src/apps/transactions.ts +1363 -0
- package/src/apps/transfers.test.ts +371 -0
- package/src/apps/transfers.ts +1116 -0
- package/src/apps/verified-tokens.test.ts +114 -0
- package/src/apps/verified-tokens.ts +295 -0
- package/src/apps/webhooks.test.ts +1937 -0
- package/src/apps/webhooks.ts +2926 -0
- package/src/cloudflare.ts +55 -0
- package/src/index.ts +15 -0
- package/src/internal/Auth.test.ts +980 -0
- package/src/internal/Auth.ts +1012 -0
- package/src/internal/Cache.test.ts +240 -0
- package/src/internal/Cache.ts +262 -0
- package/src/internal/Cursor.test.ts +100 -0
- package/src/internal/Cursor.ts +149 -0
- package/src/internal/EdgeCache.test.ts +234 -0
- package/src/internal/EdgeCache.ts +224 -0
- package/src/internal/Errors.ts +14 -0
- package/src/internal/Log.test.ts +244 -0
- package/src/internal/Log.ts +216 -0
- package/src/internal/MetricSink.ts +220 -0
- package/src/internal/Mpp.test.ts +64 -0
- package/src/internal/Mpp.ts +141 -0
- package/src/internal/OpenApi.fonts.ts +38 -0
- package/src/internal/OpenApi.logo.ts +18 -0
- package/src/internal/OpenApi.ts +488 -0
- package/src/internal/Path.test.ts +14 -0
- package/src/internal/Path.ts +15 -0
- package/src/internal/RateLimit.test.ts +93 -0
- package/src/internal/RateLimit.ts +93 -0
- package/src/internal/Response.ts +131 -0
- package/src/internal/Schema.test.ts +34 -0
- package/src/internal/Schema.ts +523 -0
- package/src/internal/Store.test.ts +545 -0
- package/src/internal/Store.ts +526 -0
- package/src/internal/Tidx.local.test.ts +33 -0
- package/src/internal/Tidx.test.ts +294 -0
- package/src/internal/Tidx.ts +238 -0
- package/src/internal/Timing.test.ts +22 -0
- package/src/internal/Timing.ts +62 -0
- package/src/internal/Ttl.test.ts +18 -0
- package/src/internal/Ttl.ts +59 -0
- package/src/internal/Value.ts +114 -0
- package/src/internal/VerifiedTokens.test.ts +333 -0
- package/src/internal/VerifiedTokens.ts +645 -0
- package/src/internal/Viem.test.ts +115 -0
- package/src/internal/Viem.ts +165 -0
- package/src/internal/WebhookDestination.test.ts +648 -0
- package/src/internal/WebhookDestination.ts +331 -0
- package/src/internal/Webhooks.test.ts +668 -0
- package/src/internal/Webhooks.ts +940 -0
- package/src/internal/webhookDestinations/betterStack.ts +91 -0
- package/src/internal/webhookDestinations/slack.ts +496 -0
- package/src/internal/webhookDestinations/url.ts +128 -0
- package/src/openrpc.json +5302 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Hex } from 'ox'
|
|
2
|
+
|
|
3
|
+
/** Coerce a TIDX numeric column (bigint / number / string) to a JS number. */
|
|
4
|
+
export function toNumber(value: unknown) {
|
|
5
|
+
if (typeof value === 'bigint') return Number(value)
|
|
6
|
+
if (typeof value === 'number') return value
|
|
7
|
+
if (typeof value === 'string') return Number(value)
|
|
8
|
+
return undefined
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Coerce a TIDX text column (address / hash / topic / hex data) to a string.
|
|
13
|
+
* TIDX already returns these columns as strings; this narrows the `unknown`
|
|
14
|
+
* row value without an unsafe `String(...)` on a possible object. Returns
|
|
15
|
+
* undefined for null/non-string values.
|
|
16
|
+
*/
|
|
17
|
+
export function toText(value: unknown): string | undefined {
|
|
18
|
+
return typeof value === 'string' ? value : undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Coerce a TIDX numeric column (bigint / number / string) to a non-negative
|
|
23
|
+
* decimal integer string, preserving precision for values beyond
|
|
24
|
+
* `Number.MAX_SAFE_INTEGER` (e.g. token balances). Returns undefined when the
|
|
25
|
+
* value cannot be interpreted as a non-negative integer.
|
|
26
|
+
*/
|
|
27
|
+
export function toIntegerString(value: unknown) {
|
|
28
|
+
if (typeof value === 'bigint') return value >= 0n ? value.toString() : undefined
|
|
29
|
+
if (typeof value === 'number') {
|
|
30
|
+
if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value)) return undefined
|
|
31
|
+
// Route through BigInt so large integers serialize as plain decimals rather
|
|
32
|
+
// than exponential notation (e.g. `1e+21`).
|
|
33
|
+
return BigInt(value).toString()
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === 'string') {
|
|
36
|
+
const trimmed = value.trim()
|
|
37
|
+
return /^\d+$/.test(trimmed) ? trimmed : undefined
|
|
38
|
+
}
|
|
39
|
+
return undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Coerce a TIDX numeric column (bigint / number / decimal string) to a minimal
|
|
44
|
+
* `0x`-prefixed hex quantity (`0x0` for zero), matching the JSON-RPC wire
|
|
45
|
+
* format. Returns undefined when the value is null/undefined or cannot be
|
|
46
|
+
* interpreted as a non-negative integer.
|
|
47
|
+
*/
|
|
48
|
+
export function toHex(value: unknown): Hex.Hex | undefined {
|
|
49
|
+
let big: bigint
|
|
50
|
+
if (typeof value === 'bigint') big = value
|
|
51
|
+
else if (typeof value === 'number') {
|
|
52
|
+
if (!Number.isFinite(value) || !Number.isInteger(value)) return undefined
|
|
53
|
+
big = BigInt(value)
|
|
54
|
+
} else if (typeof value === 'string') {
|
|
55
|
+
const trimmed = value.trim()
|
|
56
|
+
if (!/^\d+$/.test(trimmed)) return undefined
|
|
57
|
+
big = BigInt(trimmed)
|
|
58
|
+
} else return undefined
|
|
59
|
+
if (big < 0n) return undefined
|
|
60
|
+
return Hex.fromNumber(big)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parse a `0x`-prefixed hex quantity into a non-negative decimal integer string,
|
|
65
|
+
* preserving precision beyond `Number.MAX_SAFE_INTEGER`. Returns undefined when
|
|
66
|
+
* the value is not a valid hex quantity.
|
|
67
|
+
*/
|
|
68
|
+
export function fromHex(value: unknown): string | undefined {
|
|
69
|
+
if (typeof value !== 'string' || !/^0x[0-9a-fA-F]+$/.test(value)) return undefined
|
|
70
|
+
return BigInt(value).toString()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse a `0x`-prefixed hex quantity into a JS number. Returns undefined when
|
|
75
|
+
* the value is not a valid hex quantity.
|
|
76
|
+
*/
|
|
77
|
+
export function hexToNumber(value: unknown): number | undefined {
|
|
78
|
+
const decimal = fromHex(value)
|
|
79
|
+
return decimal === undefined ? undefined : Number(decimal)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Convert a `0x`-prefixed hex Unix-seconds timestamp into an ISO 8601 datetime
|
|
84
|
+
* string. Returns undefined when the value is not a valid hex quantity.
|
|
85
|
+
*/
|
|
86
|
+
export function hexSecondsToIso(value: unknown): string | undefined {
|
|
87
|
+
const seconds = hexToNumber(value)
|
|
88
|
+
return seconds === undefined ? undefined : new Date(seconds * 1000).toISOString()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Coerce a TIDX timestamp column (Date / epoch seconds / epoch ms / ISO string)
|
|
93
|
+
* to an ISO 8601 datetime string. Returns undefined when the value cannot be
|
|
94
|
+
* interpreted as a timestamp.
|
|
95
|
+
*/
|
|
96
|
+
export function toIsoDateTime(value: unknown) {
|
|
97
|
+
if (value instanceof Date) return value.toISOString()
|
|
98
|
+
// TIDX can surface timestamps as either decoded date strings or numeric
|
|
99
|
+
// epochs depending on the query engine and transport codec.
|
|
100
|
+
if (typeof value === 'number')
|
|
101
|
+
return new Date(value > 1_000_000_000_000 ? value : value * 1000).toISOString()
|
|
102
|
+
if (typeof value !== 'string') return undefined
|
|
103
|
+
|
|
104
|
+
// ClickHouse formats `DateTime`/`DateTime64` as `YYYY-MM-DD HH:MM:SS[.sss]`
|
|
105
|
+
// (UTC), which V8's Date parser treats as *local* time. Normalize to a
|
|
106
|
+
// strict ISO 8601 UTC string so both engines hit the same `new Date(...)`
|
|
107
|
+
// path.
|
|
108
|
+
const normalized = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?$/.test(value)
|
|
109
|
+
? `${value.replace(' ', 'T')}Z`
|
|
110
|
+
: value
|
|
111
|
+
const date = new Date(normalized)
|
|
112
|
+
if (Number.isNaN(date.getTime())) return undefined
|
|
113
|
+
return date.toISOString()
|
|
114
|
+
}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import type { Context } from 'hono'
|
|
2
|
+
|
|
3
|
+
import type * as App from '../App.js'
|
|
4
|
+
import * as Store from './Store.js'
|
|
5
|
+
import * as VerifiedTokens from './VerifiedTokens.js'
|
|
6
|
+
|
|
7
|
+
// Seeds a store with the documented head + versioned blob layout for a
|
|
8
|
+
// chain so `read`/`snapshot` can load it.
|
|
9
|
+
async function seed(
|
|
10
|
+
store: Store.State,
|
|
11
|
+
chainId: number,
|
|
12
|
+
version: string,
|
|
13
|
+
list: readonly VerifiedTokens.Token[],
|
|
14
|
+
) {
|
|
15
|
+
const updatedAt = '2024-01-01T00:00:00.000Z'
|
|
16
|
+
await store.put(
|
|
17
|
+
`verified-token:v1:${chainId}:snapshot:${version}`,
|
|
18
|
+
JSON.stringify({ chainId, schema: 1, tokens: list, updatedAt, version }),
|
|
19
|
+
)
|
|
20
|
+
await store.put(
|
|
21
|
+
`verified-token:v1:${chainId}:head`,
|
|
22
|
+
JSON.stringify({ chainId, count: list.length, schema: 1, updatedAt, version }),
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Store wrapper that counts `get` calls per key prefix so tests can assert the
|
|
27
|
+
// hot path does zero (fresh) or head-only (soft-stale) I/O.
|
|
28
|
+
function counting(store: Store.State) {
|
|
29
|
+
const counts = { head: 0, snapshot: 0 }
|
|
30
|
+
return {
|
|
31
|
+
counts,
|
|
32
|
+
store: Store.from({
|
|
33
|
+
...store,
|
|
34
|
+
get(key: string) {
|
|
35
|
+
if (key.endsWith(':head')) counts.head++
|
|
36
|
+
else if (key.includes(':snapshot:')) counts.snapshot++
|
|
37
|
+
return store.get(key)
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Minimal context that returns a verified-tokens feature config (or none).
|
|
44
|
+
function context(config?: App.create.VerifiedTokens): Context<App.Environment> {
|
|
45
|
+
return {
|
|
46
|
+
get: (key: string) => (key === 'verifiedTokens' ? config : undefined),
|
|
47
|
+
} as unknown as Context<App.Environment>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const flush = () => new Promise((resolve) => setTimeout(resolve, 0))
|
|
51
|
+
|
|
52
|
+
const tokens: readonly VerifiedTokens.Token[] = [
|
|
53
|
+
{ address: '0xAAA0000000000000000000000000000000000001', currency: 'USD', decimals: 6, name: 'Alpha USD', symbol: 'aUSD' }, // prettier-ignore
|
|
54
|
+
{ address: '0xBBB0000000000000000000000000000000000002', currency: 'EUR', decimals: 2, name: 'Beta EUR', symbol: 'bEUR' }, // prettier-ignore
|
|
55
|
+
{ address: '0xCCC0000000000000000000000000000000000003', currency: 'usd', decimals: 6, name: 'Gamma USD', symbol: 'cUSD' }, // prettier-ignore
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
describe('compile', () => {
|
|
59
|
+
const snapshot = VerifiedTokens.compile({
|
|
60
|
+
chainId: 4217,
|
|
61
|
+
tokens,
|
|
62
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
63
|
+
version: 'test',
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
test('preserves list order', () => {
|
|
67
|
+
expect(snapshot.list.map((token) => token.symbol)).toMatchInlineSnapshot(`
|
|
68
|
+
[
|
|
69
|
+
"aUSD",
|
|
70
|
+
"bEUR",
|
|
71
|
+
"cUSD",
|
|
72
|
+
]
|
|
73
|
+
`)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('indexes by lowercased address', () => {
|
|
77
|
+
expect(snapshot.byAddress.has('0xaaa0000000000000000000000000000000000001')).toBe(true)
|
|
78
|
+
// Lookups normalize, so the original mixed-case key is not present verbatim.
|
|
79
|
+
expect(snapshot.byAddress.has('0xAAA0000000000000000000000000000000000001')).toBe(false)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('indexes by lowercased symbol', () => {
|
|
83
|
+
expect(snapshot.bySymbol.get('ausd')?.address).toBe(
|
|
84
|
+
'0xAAA0000000000000000000000000000000000001',
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test('groups by lowercased currency, preserving order', () => {
|
|
89
|
+
expect(snapshot.byCurrency.get('usd')?.map((token) => token.symbol)).toMatchInlineSnapshot(`
|
|
90
|
+
[
|
|
91
|
+
"aUSD",
|
|
92
|
+
"cUSD",
|
|
93
|
+
]
|
|
94
|
+
`)
|
|
95
|
+
expect(snapshot.byCurrency.get('eur')?.map((token) => token.symbol)).toMatchInlineSnapshot(`
|
|
96
|
+
[
|
|
97
|
+
"bEUR",
|
|
98
|
+
]
|
|
99
|
+
`)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('derives sorted, distinct (case-sensitive) currencies', () => {
|
|
103
|
+
expect(snapshot.currencies).toMatchInlineSnapshot(`
|
|
104
|
+
[
|
|
105
|
+
"EUR",
|
|
106
|
+
"USD",
|
|
107
|
+
"usd",
|
|
108
|
+
]
|
|
109
|
+
`)
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
describe('read', () => {
|
|
114
|
+
test('returns null when the chain has no head', async () => {
|
|
115
|
+
expect(await VerifiedTokens.read(Store.memory(), 4217)).toBe(null)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('compiles the snapshot the head points at', async () => {
|
|
119
|
+
const store = Store.memory()
|
|
120
|
+
await seed(store, 4217, 'v1', tokens)
|
|
121
|
+
const snapshot = await VerifiedTokens.read(store, 4217)
|
|
122
|
+
expect(snapshot?.version).toBe('v1')
|
|
123
|
+
expect(snapshot?.list.map((token) => token.symbol)).toMatchInlineSnapshot(`
|
|
124
|
+
[
|
|
125
|
+
"aUSD",
|
|
126
|
+
"bEUR",
|
|
127
|
+
"cUSD",
|
|
128
|
+
]
|
|
129
|
+
`)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test('throws when the head points at a missing snapshot blob', async () => {
|
|
133
|
+
const store = Store.memory()
|
|
134
|
+
await store.put(
|
|
135
|
+
'verified-token:v1:4217:head',
|
|
136
|
+
JSON.stringify({
|
|
137
|
+
chainId: 4217,
|
|
138
|
+
count: 0,
|
|
139
|
+
schema: 1,
|
|
140
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
141
|
+
version: 'ghost',
|
|
142
|
+
}),
|
|
143
|
+
)
|
|
144
|
+
await expect(VerifiedTokens.read(store, 4217)).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
145
|
+
`[VerifiedTokens.TornStateError: verified-token head for chain 4217 points at missing snapshot version "ghost".]`,
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
describe('snapshot', () => {
|
|
151
|
+
// Minimal context stub: `Timing.time` only reads the optional `serverTiming`.
|
|
152
|
+
const unconfigured = { get: () => undefined } as unknown as Context<App.Environment>
|
|
153
|
+
|
|
154
|
+
test('serves an empty snapshot when the feature is unconfigured', async () => {
|
|
155
|
+
const snapshot = await VerifiedTokens.snapshot(unconfigured, 4217)
|
|
156
|
+
expect(snapshot.version).toBe('empty')
|
|
157
|
+
expect(snapshot.list).toEqual([])
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// The following cases run in order and share the module-level per-isolate cache
|
|
161
|
+
// for chain 42431: cold load → fresh → soft-stale unchanged → soft-stale changed.
|
|
162
|
+
test('cold-loads from the store when a head exists', async () => {
|
|
163
|
+
const store = Store.memory()
|
|
164
|
+
await seed(store, 42431, 'v1', tokens)
|
|
165
|
+
const snapshot = await VerifiedTokens.snapshot(context({ store }), 42431)
|
|
166
|
+
expect(snapshot.version).toBe('v1')
|
|
167
|
+
expect(snapshot.byAddress.size).toBe(tokens.length)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
test('serves fresh lookups with zero store I/O', async () => {
|
|
171
|
+
const { counts, store } = counting(Store.memory())
|
|
172
|
+
const snapshot = await VerifiedTokens.snapshot(context({ refreshMs: 60_000, store }), 42431)
|
|
173
|
+
expect(snapshot.version).toBe('v1')
|
|
174
|
+
expect(counts).toEqual({ head: 0, snapshot: 0 })
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
test('soft-stale reads only the head when the version is unchanged', async () => {
|
|
178
|
+
const base = Store.memory()
|
|
179
|
+
await seed(base, 42431, 'v1', tokens)
|
|
180
|
+
const { counts, store } = counting(base)
|
|
181
|
+
// refreshMs 0 forces the soft-stale path; the current snapshot is returned
|
|
182
|
+
// immediately and the head-only refresh runs in the background.
|
|
183
|
+
const snapshot = await VerifiedTokens.snapshot(context({ refreshMs: 0, store }), 42431)
|
|
184
|
+
expect(snapshot.version).toBe('v1')
|
|
185
|
+
await flush()
|
|
186
|
+
expect(counts).toEqual({ head: 1, snapshot: 0 })
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
test('soft-stale recompiles when the version changed', async () => {
|
|
190
|
+
const store = Store.memory()
|
|
191
|
+
await seed(store, 42431, 'v2', tokens.slice(0, 1))
|
|
192
|
+
// Stale call returns the existing v1 immediately, refreshes to v2 in background.
|
|
193
|
+
const stale = await VerifiedTokens.snapshot(context({ refreshMs: 0, store }), 42431)
|
|
194
|
+
expect(stale.version).toBe('v1')
|
|
195
|
+
await flush()
|
|
196
|
+
// Next call sees the refreshed cell (fresh window) and returns v2.
|
|
197
|
+
const fresh = await VerifiedTokens.snapshot(context({ refreshMs: 60_000, store }), 42431)
|
|
198
|
+
expect(fresh.version).toBe('v2')
|
|
199
|
+
expect(fresh.list.map((token) => token.symbol)).toEqual(['aUSD'])
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
test('cold-loads an empty snapshot when the store has no head', async () => {
|
|
203
|
+
// Chain 4217 has no configured cell yet and an empty store → empty snapshot.
|
|
204
|
+
const snapshot = await VerifiedTokens.snapshot(context({ store: Store.memory() }), 4217)
|
|
205
|
+
expect(snapshot.version).toBe('empty')
|
|
206
|
+
expect(snapshot.list).toEqual([])
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
const newToken = {
|
|
211
|
+
address: '0xDDD0000000000000000000000000000000000004',
|
|
212
|
+
currency: 'GBP',
|
|
213
|
+
decimals: 8,
|
|
214
|
+
name: 'Delta GBP',
|
|
215
|
+
symbol: 'dGBP',
|
|
216
|
+
} satisfies VerifiedTokens.Token
|
|
217
|
+
|
|
218
|
+
describe('replace', () => {
|
|
219
|
+
test('publishes the list and round-trips through read', async () => {
|
|
220
|
+
const store = Store.memory()
|
|
221
|
+
const { snapshot } = await VerifiedTokens.replace(store, 42431, tokens)
|
|
222
|
+
const read = await VerifiedTokens.read(store, 42431)
|
|
223
|
+
expect(read?.version).toBe(snapshot.version)
|
|
224
|
+
expect(read?.list.map((token) => token.symbol)).toEqual(['aUSD', 'bEUR', 'cUSD'])
|
|
225
|
+
// Addresses are normalized to lowercase on write.
|
|
226
|
+
expect(read?.list[0]?.address).toBe('0xaaa0000000000000000000000000000000000001')
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
test('advances the head version on each publish', async () => {
|
|
230
|
+
const store = Store.memory()
|
|
231
|
+
const first = await VerifiedTokens.replace(store, 42431, tokens)
|
|
232
|
+
const second = await VerifiedTokens.replace(store, 42431, tokens.slice(0, 1))
|
|
233
|
+
expect(second.snapshot.version > first.snapshot.version).toBe(true)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
test('rejects a duplicate address in the input', async () => {
|
|
237
|
+
const store = Store.memory()
|
|
238
|
+
await expect(
|
|
239
|
+
VerifiedTokens.replace(store, 42431, [tokens[0]!, tokens[0]!]),
|
|
240
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
241
|
+
`[VerifiedTokens.DuplicateAddressError: verified token 0xaaa0000000000000000000000000000000000001 already exists on chain 42431.]`,
|
|
242
|
+
)
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
describe('create', () => {
|
|
247
|
+
test('appends a token preserving order', async () => {
|
|
248
|
+
const store = Store.memory()
|
|
249
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
250
|
+
const { snapshot, token } = await VerifiedTokens.create(store, { ...newToken, chainId: 42431 })
|
|
251
|
+
expect(token.address).toBe('0xddd0000000000000000000000000000000000004')
|
|
252
|
+
expect(snapshot.list.map((t) => t.symbol)).toEqual(['aUSD', 'bEUR', 'cUSD', 'dGBP'])
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
test('rejects a duplicate address', async () => {
|
|
256
|
+
const store = Store.memory()
|
|
257
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
258
|
+
await expect(
|
|
259
|
+
VerifiedTokens.create(store, { ...tokens[0]!, chainId: 42431 }),
|
|
260
|
+
).rejects.toThrowError(VerifiedTokens.DuplicateAddressError)
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
test('rejects a case-insensitive duplicate symbol', async () => {
|
|
264
|
+
const store = Store.memory()
|
|
265
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
266
|
+
await expect(
|
|
267
|
+
VerifiedTokens.create(store, { ...newToken, chainId: 42431, symbol: 'AUSD' }),
|
|
268
|
+
).rejects.toThrowError(VerifiedTokens.DuplicateSymbolError)
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
describe('patch', () => {
|
|
273
|
+
test('edits fields in place, preserving order', async () => {
|
|
274
|
+
const store = Store.memory()
|
|
275
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
276
|
+
const { snapshot, token } = await VerifiedTokens.patch(store, 42431, tokens[1]!.address, {
|
|
277
|
+
name: 'Beta Euro',
|
|
278
|
+
})
|
|
279
|
+
expect(token.name).toBe('Beta Euro')
|
|
280
|
+
// Unchanged fields are preserved; order is preserved.
|
|
281
|
+
expect(token.symbol).toBe('bEUR')
|
|
282
|
+
expect(snapshot.list.map((t) => t.symbol)).toEqual(['aUSD', 'bEUR', 'cUSD'])
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
test('throws NotFoundError for an unknown address', async () => {
|
|
286
|
+
const store = Store.memory()
|
|
287
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
288
|
+
await expect(
|
|
289
|
+
VerifiedTokens.patch(store, 42431, newToken.address, { name: 'x' }),
|
|
290
|
+
).rejects.toThrowError(VerifiedTokens.NotFoundError)
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
test('rejects an If-Match version mismatch', async () => {
|
|
294
|
+
const store = Store.memory()
|
|
295
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
296
|
+
await expect(
|
|
297
|
+
VerifiedTokens.patch(store, 42431, tokens[0]!.address, { name: 'x' }, { ifMatch: 'stale' }),
|
|
298
|
+
).rejects.toThrowError(VerifiedTokens.VersionMismatchError)
|
|
299
|
+
})
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
describe('remove', () => {
|
|
303
|
+
test('removes a token and publishes', async () => {
|
|
304
|
+
const store = Store.memory()
|
|
305
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
306
|
+
const { snapshot } = await VerifiedTokens.remove(store, 42431, tokens[0]!.address)
|
|
307
|
+
expect(snapshot.list.map((t) => t.symbol)).toEqual(['bEUR', 'cUSD'])
|
|
308
|
+
expect(snapshot.byAddress.has(tokens[0]!.address.toLowerCase())).toBe(false)
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
test('throws NotFoundError for an unknown address', async () => {
|
|
312
|
+
const store = Store.memory()
|
|
313
|
+
await VerifiedTokens.replace(store, 42431, tokens)
|
|
314
|
+
await expect(VerifiedTokens.remove(store, 42431, newToken.address)).rejects.toThrowError(
|
|
315
|
+
VerifiedTokens.NotFoundError,
|
|
316
|
+
)
|
|
317
|
+
})
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
describe('prime', () => {
|
|
321
|
+
test('gives read-your-write for the priming isolate', async () => {
|
|
322
|
+
const primed = VerifiedTokens.compile({
|
|
323
|
+
chainId: 42431,
|
|
324
|
+
tokens: tokens.slice(0, 2),
|
|
325
|
+
updatedAt: '2024-02-02T00:00:00.000Z',
|
|
326
|
+
version: 'primed',
|
|
327
|
+
})
|
|
328
|
+
VerifiedTokens.prime(42431, primed)
|
|
329
|
+
// Within the fresh window the primed snapshot is served with no store read.
|
|
330
|
+
const snapshot = await VerifiedTokens.snapshot(context({ refreshMs: 60_000, store: Store.memory() }), 42431) // prettier-ignore
|
|
331
|
+
expect(snapshot).toBe(primed)
|
|
332
|
+
})
|
|
333
|
+
})
|