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,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps store operations into a {@link Store}, defaulting to an authoritative
|
|
3
|
+
* {@link State} store. Omit `type` for the common authoritative case; pass
|
|
4
|
+
* `type: 'cache'` to opt into a cache-kind store (non-enumerable, lossy — e.g.
|
|
5
|
+
* the Web Cache).
|
|
6
|
+
*/
|
|
7
|
+
export function from(store) {
|
|
8
|
+
// Default the discriminant so only cache-kind stores have to opt in.
|
|
9
|
+
return { ...store, type: store.type ?? 'state' };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Increments an integer counter on a store and returns the new value. A
|
|
13
|
+
* missing or expired key restarts at `1`; `ttl` applies like {@link Store.put}.
|
|
14
|
+
*
|
|
15
|
+
* Uses the store's native {@link Store.increment} when implemented (atomic
|
|
16
|
+
* where the backend executes it in one place — in-memory, inside a Durable
|
|
17
|
+
* Object). Otherwise falls back to a get + put read-modify-write, which
|
|
18
|
+
* costs two round trips on remote stores and can race under concurrency —
|
|
19
|
+
* fine for dev/in-process backends, not for enforced distributed counters.
|
|
20
|
+
*/
|
|
21
|
+
export async function increment(store, key, options = {}) {
|
|
22
|
+
if (store.increment)
|
|
23
|
+
return store.increment(key, options);
|
|
24
|
+
const count = Number((await store.get(key)) ?? 0) + 1;
|
|
25
|
+
await store.put(key, String(count), options);
|
|
26
|
+
return count;
|
|
27
|
+
}
|
|
28
|
+
/** Creates an in-memory store with TTL support. */
|
|
29
|
+
export function memory(options = {}) {
|
|
30
|
+
const cells = new Map((options.entries ?? []).map(([key, value]) => [key, { expiresAt: undefined, value }]));
|
|
31
|
+
function read(key) {
|
|
32
|
+
const cell = cells.get(key);
|
|
33
|
+
if (!cell)
|
|
34
|
+
return null;
|
|
35
|
+
if (cell.expiresAt !== undefined && cell.expiresAt <= Date.now()) {
|
|
36
|
+
cells.delete(key);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return cell;
|
|
40
|
+
}
|
|
41
|
+
return from({
|
|
42
|
+
async delete(key) {
|
|
43
|
+
cells.delete(key);
|
|
44
|
+
},
|
|
45
|
+
async get(key) {
|
|
46
|
+
return read(key)?.value ?? null;
|
|
47
|
+
},
|
|
48
|
+
// Native increment: the read-modify-write is synchronous, so concurrent
|
|
49
|
+
// consumers cannot interleave between the read and the write.
|
|
50
|
+
async increment(key, options = {}) {
|
|
51
|
+
const count = Number(read(key)?.value ?? 0) + 1;
|
|
52
|
+
const expiresAt = options.ttl === undefined ? undefined : Date.now() + options.ttl;
|
|
53
|
+
cells.set(key, { expiresAt, value: String(count) });
|
|
54
|
+
return count;
|
|
55
|
+
},
|
|
56
|
+
async list(options = {}) {
|
|
57
|
+
const keys = Array.from(cells.keys())
|
|
58
|
+
.filter((key) => (!options.prefix || key.startsWith(options.prefix)) && read(key))
|
|
59
|
+
.sort()
|
|
60
|
+
.map((name) => ({ name }));
|
|
61
|
+
return { keys };
|
|
62
|
+
},
|
|
63
|
+
async put(key, value, options = {}) {
|
|
64
|
+
const expiresAt = options.ttl === undefined ? undefined : Date.now() + options.ttl;
|
|
65
|
+
cells.set(key, { expiresAt, value });
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Creates a store backed by a Web Cache API instance (e.g. Cloudflare's
|
|
71
|
+
* colo-local `caches.default`). Values are stored as cache entries keyed by a
|
|
72
|
+
* synthetic URL, with `ttl` mapped to `Cache-Control: max-age`. The Web Cache
|
|
73
|
+
* cannot enumerate keys, so `list` returns no keys — use this for caching
|
|
74
|
+
* (get/put/delete) only, e.g. the origin read cache and edge response cache.
|
|
75
|
+
*/
|
|
76
|
+
export function cache(webCache) {
|
|
77
|
+
const request = (key) => new Request(`https://tempo-api.cache/${encodeURIComponent(key)}`);
|
|
78
|
+
return from({
|
|
79
|
+
async delete(key) {
|
|
80
|
+
await webCache.delete(request(key));
|
|
81
|
+
},
|
|
82
|
+
async get(key) {
|
|
83
|
+
const hit = await webCache.match(request(key));
|
|
84
|
+
return hit ? hit.text() : null;
|
|
85
|
+
},
|
|
86
|
+
async list() {
|
|
87
|
+
return { keys: [] };
|
|
88
|
+
},
|
|
89
|
+
async put(key, value, options = {}) {
|
|
90
|
+
// The Web Cache only persists responses with a positive freshness lifetime.
|
|
91
|
+
const seconds = Math.max(1, Math.ceil((options.ttl ?? 0) / 1_000));
|
|
92
|
+
const headers = new Headers({ 'Cache-Control': `max-age=${seconds}` });
|
|
93
|
+
await webCache.put(request(key), new Response(value, { headers }));
|
|
94
|
+
},
|
|
95
|
+
type: 'cache',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** Creates a store backed by a Cloudflare Workers KV namespace. */
|
|
99
|
+
export function cloudflareKv(namespace) {
|
|
100
|
+
return from({
|
|
101
|
+
async delete(key) {
|
|
102
|
+
await namespace.delete(key);
|
|
103
|
+
},
|
|
104
|
+
async get(key) {
|
|
105
|
+
return namespace.get(key);
|
|
106
|
+
},
|
|
107
|
+
async list(options = {}) {
|
|
108
|
+
const result = await namespace.list(options.prefix === undefined ? undefined : { prefix: options.prefix });
|
|
109
|
+
return { keys: result.keys.map(({ name }) => ({ name })) };
|
|
110
|
+
},
|
|
111
|
+
async put(key, value, options = {}) {
|
|
112
|
+
const expirationTtl = cloudflareKvExpirationTtl(options.ttl);
|
|
113
|
+
if (expirationTtl === 0) {
|
|
114
|
+
await namespace.delete(key);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await namespace.put(key, value, expirationTtl === undefined ? undefined : { expirationTtl });
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/** Creates a store backed by Cloudflare Durable Object storage or namespace RPC. */
|
|
122
|
+
export function durableObject(target, options) {
|
|
123
|
+
if (durableObjectNamespace(target)) {
|
|
124
|
+
const name = options?.name;
|
|
125
|
+
if (name === undefined)
|
|
126
|
+
throw new TypeError('Durable Object name is required');
|
|
127
|
+
return durableObjectStub(target, name);
|
|
128
|
+
}
|
|
129
|
+
return durableObjectStorage(target);
|
|
130
|
+
}
|
|
131
|
+
function durableObjectStorage(storage) {
|
|
132
|
+
return from({
|
|
133
|
+
async delete(key) {
|
|
134
|
+
await storage.delete(key);
|
|
135
|
+
},
|
|
136
|
+
async get(key) {
|
|
137
|
+
return (await durableObjectRead(storage, key, await storage.get(key)))?.value ?? null;
|
|
138
|
+
},
|
|
139
|
+
async list(options = {}) {
|
|
140
|
+
const values = await storage.list(options);
|
|
141
|
+
const keys = [];
|
|
142
|
+
for (const [key, value] of values) {
|
|
143
|
+
if (await durableObjectRead(storage, key, value))
|
|
144
|
+
keys.push({ name: key });
|
|
145
|
+
}
|
|
146
|
+
return { keys };
|
|
147
|
+
},
|
|
148
|
+
async put(key, value, options = {}) {
|
|
149
|
+
if (options.ttl !== undefined && options.ttl <= 0) {
|
|
150
|
+
await storage.delete(key);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
await storage.put(key, durableObjectValue(value, options));
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Wraps an async producer with store-backed caching. Returns the cached value if
|
|
159
|
+
* present and valid; otherwise runs `fetch`, stores the JSON-encoded result
|
|
160
|
+
* under `key` with `ttl` milliseconds, and returns it.
|
|
161
|
+
*/
|
|
162
|
+
export async function memoize(fetch, options) {
|
|
163
|
+
const { key, store, ttl } = options;
|
|
164
|
+
const raw = await store.get(key);
|
|
165
|
+
if (raw) {
|
|
166
|
+
try {
|
|
167
|
+
return JSON.parse(raw);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Corrupt entries are treated as misses so the next call refreshes.
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const flights = flightsFor(store);
|
|
174
|
+
const existing = flights.get(key);
|
|
175
|
+
if (existing)
|
|
176
|
+
return existing;
|
|
177
|
+
// Coalesce concurrent misses for this process. The store remains the cache
|
|
178
|
+
// boundary; this only prevents a local cold-key stampede while the first
|
|
179
|
+
// fetch is still in flight.
|
|
180
|
+
const flight = (async () => {
|
|
181
|
+
const value = await fetch();
|
|
182
|
+
await store.put(key, JSON.stringify(value), { ttl });
|
|
183
|
+
return value;
|
|
184
|
+
})();
|
|
185
|
+
flights.set(key, flight);
|
|
186
|
+
try {
|
|
187
|
+
return await flight;
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
flights.delete(key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const flights = new WeakMap();
|
|
194
|
+
function flightsFor(store) {
|
|
195
|
+
let inFlight = flights.get(store);
|
|
196
|
+
if (!inFlight) {
|
|
197
|
+
inFlight = new Map();
|
|
198
|
+
flights.set(store, inFlight);
|
|
199
|
+
}
|
|
200
|
+
return inFlight;
|
|
201
|
+
}
|
|
202
|
+
function durableObjectNamespace(target) {
|
|
203
|
+
return typeof target === 'object' && target !== null && 'getByName' in target;
|
|
204
|
+
}
|
|
205
|
+
function durableObjectStub(namespace, name) {
|
|
206
|
+
// Durable Object stubs are request-scoped I/O objects in Workers, so
|
|
207
|
+
// resolve the stub inside each store operation instead of caching it.
|
|
208
|
+
const stub = (key) => namespace.getByName(typeof name === 'function' ? name(key) : name);
|
|
209
|
+
return from({
|
|
210
|
+
async delete(key) {
|
|
211
|
+
await durableObjectRetry(() => stub(key).delete(key));
|
|
212
|
+
},
|
|
213
|
+
async get(key) {
|
|
214
|
+
return durableObjectRetry(() => stub(key).get(key));
|
|
215
|
+
},
|
|
216
|
+
// Native RPC increment: the read-modify-write runs inside the object
|
|
217
|
+
// (one round trip, atomic) instead of the get + put fallback (two).
|
|
218
|
+
async increment(key, options) {
|
|
219
|
+
return durableObjectRetry(() => stub(key).increment(key, options));
|
|
220
|
+
},
|
|
221
|
+
async list(options) {
|
|
222
|
+
// A sharded store scatters keys across objects, so no single object can
|
|
223
|
+
// enumerate them.
|
|
224
|
+
if (typeof name === 'function')
|
|
225
|
+
throw new TypeError('cannot list a sharded Durable Object store');
|
|
226
|
+
return durableObjectRetry(() => stub('').list(options));
|
|
227
|
+
},
|
|
228
|
+
async put(key, value, options) {
|
|
229
|
+
await durableObjectRetry(() => stub(key).put(key, value, options));
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Runs a Durable Object stub call, retrying once when workerd marks the error
|
|
235
|
+
* retryable (transient transport failures, e.g. "Network connection lost.")
|
|
236
|
+
* and not overloaded. Callers pass a thunk so the retry resolves a fresh
|
|
237
|
+
* stub: a stub that threw is disconnected.
|
|
238
|
+
*/
|
|
239
|
+
async function durableObjectRetry(call) {
|
|
240
|
+
try {
|
|
241
|
+
return await call();
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
const { overloaded, retryable } = (error ?? {});
|
|
245
|
+
if (retryable !== true || overloaded === true)
|
|
246
|
+
throw error;
|
|
247
|
+
return call();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function cloudflareKvExpirationTtl(ttl) {
|
|
251
|
+
if (ttl === undefined)
|
|
252
|
+
return undefined;
|
|
253
|
+
if (ttl <= 0)
|
|
254
|
+
return 0;
|
|
255
|
+
// Workers KV expects TTLs in seconds and rejects values under 60 seconds.
|
|
256
|
+
const seconds = Math.ceil(ttl / 1_000);
|
|
257
|
+
if (seconds < 60)
|
|
258
|
+
throw new RangeError('Cloudflare KV expirationTtl must be at least 60 seconds');
|
|
259
|
+
return seconds;
|
|
260
|
+
}
|
|
261
|
+
const durableObjectValueType = 'cadent:store:v1';
|
|
262
|
+
function durableObjectValue(value, options) {
|
|
263
|
+
if (options.ttl === undefined)
|
|
264
|
+
return value;
|
|
265
|
+
// Durable Object storage does not expose per-key TTL in the current Worker
|
|
266
|
+
// API, so this adapter stores expirations in-band and evicts lazily on read.
|
|
267
|
+
return { expiresAt: Date.now() + options.ttl, type: durableObjectValueType, value };
|
|
268
|
+
}
|
|
269
|
+
async function durableObjectRead(storage, key, value) {
|
|
270
|
+
if (typeof value === 'string')
|
|
271
|
+
return { value };
|
|
272
|
+
if (!isDurableObjectValue(value))
|
|
273
|
+
return null;
|
|
274
|
+
if (value.expiresAt !== undefined && value.expiresAt <= Date.now()) {
|
|
275
|
+
await storage.delete(key);
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
return value;
|
|
279
|
+
}
|
|
280
|
+
function isDurableObjectValue(value) {
|
|
281
|
+
if (!value || typeof value !== 'object')
|
|
282
|
+
return false;
|
|
283
|
+
return ('type' in value &&
|
|
284
|
+
value.type === durableObjectValueType &&
|
|
285
|
+
'value' in value &&
|
|
286
|
+
typeof value.value === 'string' &&
|
|
287
|
+
(!('expiresAt' in value) ||
|
|
288
|
+
value.expiresAt === undefined ||
|
|
289
|
+
typeof value.expiresAt === 'number'));
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=Store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Store.js","sourceRoot":"","sources":["../../src/internal/Store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Tidx } from 'tidx.ts';
|
|
2
|
+
import type * as Auth from './Auth.js';
|
|
3
|
+
import * as Viem from './Viem.js';
|
|
4
|
+
/** Default Tempo indexer (TIDX) base URLs. */
|
|
5
|
+
export declare const url: Record<number, string>;
|
|
6
|
+
/** TIDX query client. */
|
|
7
|
+
export type Client = Tidx.Tidx;
|
|
8
|
+
/** Gets a TIDX query client for a Tempo chain id and request principal. */
|
|
9
|
+
export type GetClient = (chainId?: Viem.ChainId, principal?: Auth.Principal | null) => Client;
|
|
10
|
+
/**
|
|
11
|
+
* Resolves a TIDX base URL for a Tempo chain id. May return `undefined` to fall
|
|
12
|
+
* back to the built-in {@link url} map (e.g. for a chain the resolver doesn't
|
|
13
|
+
* serve).
|
|
14
|
+
*/
|
|
15
|
+
export type UrlResolver = (chainId: Viem.ChainId) => string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the effective TIDX config for a single request.
|
|
18
|
+
*
|
|
19
|
+
* Accepts either a static config object or a per-request resolver function that
|
|
20
|
+
* receives a {@link Viem.resolve.Context} (`chainId` plus the request
|
|
21
|
+
* `principal`), so callers can route traffic per caller — e.g. send anonymous
|
|
22
|
+
* (`principal.type === 'public'`) traffic to a separate, no-auth indexer. A
|
|
23
|
+
* missing `baseUrl` falls back to the built-in public host map ({@link url}); a
|
|
24
|
+
* missing `basicAuth` means no Basic auth is sent.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolve(tidx: getClient.Tidx | undefined, context: Viem.resolve.Context): resolve.Resolved;
|
|
27
|
+
export declare namespace resolve {
|
|
28
|
+
/** Resolved TIDX config for a single request. */
|
|
29
|
+
type Resolved = {
|
|
30
|
+
/**
|
|
31
|
+
* Resolved TIDX base URL, or `undefined` when neither a configured `tidx`
|
|
32
|
+
* nor the built-in {@link url} map covers the chain (e.g. an unconfigured
|
|
33
|
+
* localnet). A `undefined` base URL falls through to the TIDX client default.
|
|
34
|
+
*/
|
|
35
|
+
baseUrl: string | undefined;
|
|
36
|
+
/** Basic auth credentials, or undefined to send no Basic auth. */
|
|
37
|
+
basicAuth?: string | undefined;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export declare function getClient(options: getClient.Options): Client;
|
|
41
|
+
/**
|
|
42
|
+
* Builds a memoized {@link GetClient} that constructs one TIDX client per
|
|
43
|
+
* resolved upstream and reuses it. Clients are stateless HTTP transports, so
|
|
44
|
+
* reusing them avoids per-call construction cost. The cache key is the resolved
|
|
45
|
+
* output (`baseUrl` + `basicAuth` + `chainId`), not the principal, so a resolver
|
|
46
|
+
* `tidx` may branch on any principal field while client cardinality stays
|
|
47
|
+
* bounded by the number of distinct upstreams — callers that resolve to the same
|
|
48
|
+
* upstream share a client. Shared by `App.create` (per-request reads) and
|
|
49
|
+
* `Webhooks.createPoller` (the scheduled poller) so the resolver logic lives in
|
|
50
|
+
* one place.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createGetClient(options?: createGetClient.Options): GetClient;
|
|
53
|
+
/**
|
|
54
|
+
* Escapes a free-form string for safe embedding inside a single-quoted SQL
|
|
55
|
+
* string literal sent to the indexer. TIDX parses every query with an ANSI
|
|
56
|
+
* SQL parser before re-rendering it for the engine, and ANSI strings have
|
|
57
|
+
* exactly one special character inside `'…'`: the quote itself, escaped by
|
|
58
|
+
* doubling (`''`). Backslash escaping (`\'`) is **rejected** with a parse
|
|
59
|
+
* error, and a backslash is an ordinary character on both engines (verified
|
|
60
|
+
* against the deployed indexer on `postgres` and `clickhouse`).
|
|
61
|
+
*
|
|
62
|
+
* Most interpolated values (addresses, hashes, ISO timestamps) are already
|
|
63
|
+
* schema-constrained to charsets that cannot contain a quote; reach for this
|
|
64
|
+
* whenever a query must interpolate genuinely free-form user input (e.g. the
|
|
65
|
+
* token `currency` filter).
|
|
66
|
+
*/
|
|
67
|
+
export declare function escape(value: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Wraps a TIDX client so `fetch` retries transient errors under **one**
|
|
70
|
+
* shared budget ({@link transientRetryCount} retries with backoff).
|
|
71
|
+
*
|
|
72
|
+
* Two transient failure modes are covered: HTTP-level failures (408/429/5xx)
|
|
73
|
+
* and the indexer's transient ClickHouse errors, which arrive as **HTTP 200**
|
|
74
|
+
* with an `{ ok: false, error: 'db error' }` body (a `FetchRequestError`
|
|
75
|
+
* whose `status` is 200). The raw `tidx.ts` client would retry the HTTP-level
|
|
76
|
+
* mode itself (5 attempts), which stacked multiplicatively under this wrapper
|
|
77
|
+
* — one flapping query shape could cost ~25 upstream executions — so the
|
|
78
|
+
* wrapper disables the client-level retries (`retryCount: 1`) and owns the
|
|
79
|
+
* whole budget: at most {@link transientRetryCount} + 1 upstream executions.
|
|
80
|
+
* Deterministic errors (e.g. a malformed query) fall through immediately.
|
|
81
|
+
*/
|
|
82
|
+
export declare function withTransientRetry(client: Client): Client;
|
|
83
|
+
export declare namespace getClient {
|
|
84
|
+
/** Options for getting a TIDX query client. */
|
|
85
|
+
type Options = {
|
|
86
|
+
/** Tempo chain id. */
|
|
87
|
+
chainId?: Viem.ChainId | undefined;
|
|
88
|
+
/** Request principal, or `null`/omitted for a trusted non-request caller. */
|
|
89
|
+
principal?: Auth.Principal | null | undefined;
|
|
90
|
+
/** TIDX query client options. */
|
|
91
|
+
tidx?: Tidx | undefined;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* TIDX query client options: either a static config, or a per-request
|
|
95
|
+
* resolver function that receives a {@link Viem.resolve.Context} and returns
|
|
96
|
+
* the config to use (e.g. routing anonymous callers to a public, no-auth
|
|
97
|
+
* indexer).
|
|
98
|
+
*/
|
|
99
|
+
type Tidx = {
|
|
100
|
+
/** Resolves the TIDX base URL for a Tempo chain id, or a static base URL. */
|
|
101
|
+
baseUrl?: UrlResolver | string | undefined;
|
|
102
|
+
/** Basic auth credentials for TIDX requests. */
|
|
103
|
+
basicAuth?: string | undefined;
|
|
104
|
+
} | ((context: Viem.resolve.Context) => {
|
|
105
|
+
/** TIDX base URL to use; falls back to the built-in public host when omitted. */
|
|
106
|
+
baseUrl?: string | undefined;
|
|
107
|
+
/** Basic auth credentials for TIDX requests, or undefined for none. */
|
|
108
|
+
basicAuth?: string | undefined;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export declare namespace createGetClient {
|
|
112
|
+
/** Options for building a memoized TIDX client resolver. */
|
|
113
|
+
type Options = {
|
|
114
|
+
/** Tempo chain id used when a caller omits one. */
|
|
115
|
+
defaultChainId?: Viem.ChainId | undefined;
|
|
116
|
+
/** TIDX query client options applied to every constructed client. */
|
|
117
|
+
tidx?: getClient.Tidx | undefined;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=Tidx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tidx.d.ts","sourceRoot":"","sources":["../../src/internal/Tidx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE9B,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,8CAA8C;AAC9C,eAAO,MAAM,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGtC,CAAA;AAED,yBAAyB;AACzB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAA;AAE9B,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,KAAK,MAAM,CAAA;AAE7F;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,MAAM,GAAG,SAAS,CAAA;AAEvE;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,SAAS,CAAC,IAAI,GAAG,SAAS,EAChC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,GAC5B,OAAO,CAAC,QAAQ,CAQlB;AAED,MAAM,CAAC,OAAO,WAAW,OAAO,CAAC;IAC/B,iDAAiD;IACjD,KAAK,QAAQ,GAAG;QACd;;;;WAIG;QACH,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;QAC3B,kEAAkE;QAClE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC/B,CAAA;CACF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,CAI5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,eAAe,CAAC,OAAY,GAAG,SAAS,CAgBhF;AA6BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,UAEnC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBzD;AAqBD,MAAM,CAAC,OAAO,WAAW,SAAS,CAAC;IACjC,+CAA+C;IAC/C,KAAK,OAAO,GAAG;QACb,sBAAsB;QACtB,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAClC,6EAA6E;QAC7E,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,SAAS,CAAA;QAC7C,iCAAiC;QACjC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;KACxB,CAAA;IAED;;;;;OAKG;IACH,KAAK,IAAI,GACL;QACE,6EAA6E;QAC7E,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAAA;QAC1C,gDAAgD;QAChD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC/B,GACD,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK;QAClC,iFAAiF;QACjF,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5B,uEAAuE;QACvE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC/B,CAAC,CAAA;CACP;AAED,MAAM,CAAC,OAAO,WAAW,eAAe,CAAC;IACvC,4DAA4D;IAC5D,KAAK,OAAO,GAAG;QACb,mDAAmD;QACnD,cAAc,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACzC,qEAAqE;QACrE,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,GAAG,SAAS,CAAA;KAClC,CAAA;CACF"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Tidx } from 'tidx.ts';
|
|
2
|
+
import * as Viem from './Viem.js';
|
|
3
|
+
/** Default Tempo indexer (TIDX) base URLs. */
|
|
4
|
+
export const url = {
|
|
5
|
+
4217: 'https://indexer.tempo.xyz',
|
|
6
|
+
42431: 'https://indexer.testnet.tempo.xyz',
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the effective TIDX config for a single request.
|
|
10
|
+
*
|
|
11
|
+
* Accepts either a static config object or a per-request resolver function that
|
|
12
|
+
* receives a {@link Viem.resolve.Context} (`chainId` plus the request
|
|
13
|
+
* `principal`), so callers can route traffic per caller — e.g. send anonymous
|
|
14
|
+
* (`principal.type === 'public'`) traffic to a separate, no-auth indexer. A
|
|
15
|
+
* missing `baseUrl` falls back to the built-in public host map ({@link url}); a
|
|
16
|
+
* missing `basicAuth` means no Basic auth is sent.
|
|
17
|
+
*/
|
|
18
|
+
export function resolve(tidx, context) {
|
|
19
|
+
const config = typeof tidx === 'function' ? tidx(context) : tidx;
|
|
20
|
+
return {
|
|
21
|
+
baseUrl: (typeof config?.baseUrl === 'function' ? config.baseUrl(context.chainId) : config?.baseUrl) ??
|
|
22
|
+
url[context.chainId],
|
|
23
|
+
basicAuth: config?.basicAuth,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function getClient(options) {
|
|
27
|
+
const { chainId = Viem.defaultChainId, principal = null, tidx } = options;
|
|
28
|
+
const { baseUrl, basicAuth } = resolve(tidx, { chainId, principal });
|
|
29
|
+
return withTransientRetry(Tidx.create({ baseUrl, basicAuth, chainId }));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Builds a memoized {@link GetClient} that constructs one TIDX client per
|
|
33
|
+
* resolved upstream and reuses it. Clients are stateless HTTP transports, so
|
|
34
|
+
* reusing them avoids per-call construction cost. The cache key is the resolved
|
|
35
|
+
* output (`baseUrl` + `basicAuth` + `chainId`), not the principal, so a resolver
|
|
36
|
+
* `tidx` may branch on any principal field while client cardinality stays
|
|
37
|
+
* bounded by the number of distinct upstreams — callers that resolve to the same
|
|
38
|
+
* upstream share a client. Shared by `App.create` (per-request reads) and
|
|
39
|
+
* `Webhooks.createPoller` (the scheduled poller) so the resolver logic lives in
|
|
40
|
+
* one place.
|
|
41
|
+
*/
|
|
42
|
+
export function createGetClient(options = {}) {
|
|
43
|
+
const { defaultChainId = Viem.defaultChainId, tidx } = options;
|
|
44
|
+
const clients = new Map();
|
|
45
|
+
return (chainId = defaultChainId, principal = null) => {
|
|
46
|
+
// Resolve to derive the cache key; `getClient` re-resolves to build the
|
|
47
|
+
// client on a miss. `resolve` is pure and cheap, so the extra call is free.
|
|
48
|
+
const { baseUrl, basicAuth } = resolve(tidx, { chainId, principal });
|
|
49
|
+
const cacheKey = `${baseUrl}|${basicAuth ?? ''}|${chainId}`;
|
|
50
|
+
const existing = clients.get(cacheKey);
|
|
51
|
+
if (existing)
|
|
52
|
+
return existing;
|
|
53
|
+
const client = getClient({ chainId, principal, tidx });
|
|
54
|
+
clients.set(cacheKey, client);
|
|
55
|
+
return client;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Number of additional `fetch` attempts for transient application-level
|
|
60
|
+
* indexer errors. The first attempt plus this many retries.
|
|
61
|
+
*
|
|
62
|
+
* Combined with {@link transientRetryDelay} this gives a ~3.75s backoff window
|
|
63
|
+
* (250 + 500 + 1000 + 2000ms over five attempts). The heaviest reads — e.g.
|
|
64
|
+
* the unfiltered global swap scan — can momentarily trip the indexer's `db
|
|
65
|
+
* error` under concurrent load, and a ~1s window was too short to ride those
|
|
66
|
+
* bursts out, surfacing them to callers as a 502.
|
|
67
|
+
*/
|
|
68
|
+
const transientRetryCount = 4;
|
|
69
|
+
/** Base backoff (ms) between transient-error retries; doubles each attempt. */
|
|
70
|
+
const transientRetryDelay = 250;
|
|
71
|
+
/**
|
|
72
|
+
* Application-level indexer failures that are transient and safe to retry on
|
|
73
|
+
* an idempotent read. The indexer surfaces transient ClickHouse failures (a
|
|
74
|
+
* busy/contended planner, a query-execution hiccup) as the literal message
|
|
75
|
+
* `db error`; timeouts and connection resets are likewise non-deterministic.
|
|
76
|
+
* `error sending request` is how TIDX reports a ClickHouse Cloud connection
|
|
77
|
+
* dropped at the server's execution cap — typically a cold object-storage
|
|
78
|
+
* cache read that warms across attempts, so retrying genuinely helps.
|
|
79
|
+
*/
|
|
80
|
+
const transientErrorPattern = /db error|timeout|timed out|connection reset|connection refused|error sending request/i;
|
|
81
|
+
/**
|
|
82
|
+
* Escapes a free-form string for safe embedding inside a single-quoted SQL
|
|
83
|
+
* string literal sent to the indexer. TIDX parses every query with an ANSI
|
|
84
|
+
* SQL parser before re-rendering it for the engine, and ANSI strings have
|
|
85
|
+
* exactly one special character inside `'…'`: the quote itself, escaped by
|
|
86
|
+
* doubling (`''`). Backslash escaping (`\'`) is **rejected** with a parse
|
|
87
|
+
* error, and a backslash is an ordinary character on both engines (verified
|
|
88
|
+
* against the deployed indexer on `postgres` and `clickhouse`).
|
|
89
|
+
*
|
|
90
|
+
* Most interpolated values (addresses, hashes, ISO timestamps) are already
|
|
91
|
+
* schema-constrained to charsets that cannot contain a quote; reach for this
|
|
92
|
+
* whenever a query must interpolate genuinely free-form user input (e.g. the
|
|
93
|
+
* token `currency` filter).
|
|
94
|
+
*/
|
|
95
|
+
export function escape(value) {
|
|
96
|
+
return value.replaceAll("'", "''");
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Wraps a TIDX client so `fetch` retries transient errors under **one**
|
|
100
|
+
* shared budget ({@link transientRetryCount} retries with backoff).
|
|
101
|
+
*
|
|
102
|
+
* Two transient failure modes are covered: HTTP-level failures (408/429/5xx)
|
|
103
|
+
* and the indexer's transient ClickHouse errors, which arrive as **HTTP 200**
|
|
104
|
+
* with an `{ ok: false, error: 'db error' }` body (a `FetchRequestError`
|
|
105
|
+
* whose `status` is 200). The raw `tidx.ts` client would retry the HTTP-level
|
|
106
|
+
* mode itself (5 attempts), which stacked multiplicatively under this wrapper
|
|
107
|
+
* — one flapping query shape could cost ~25 upstream executions — so the
|
|
108
|
+
* wrapper disables the client-level retries (`retryCount: 1`) and owns the
|
|
109
|
+
* whole budget: at most {@link transientRetryCount} + 1 upstream executions.
|
|
110
|
+
* Deterministic errors (e.g. a malformed query) fall through immediately.
|
|
111
|
+
*/
|
|
112
|
+
export function withTransientRetry(client) {
|
|
113
|
+
const fetch = client.fetch.bind(client);
|
|
114
|
+
return {
|
|
115
|
+
...client,
|
|
116
|
+
fetch: async (options) => {
|
|
117
|
+
let lastError;
|
|
118
|
+
for (let attempt = 0; attempt <= transientRetryCount; attempt++) {
|
|
119
|
+
try {
|
|
120
|
+
// `retryCount: 1` caps the inner client at a single HTTP attempt so
|
|
121
|
+
// the combined budget stays this wrapper's alone.
|
|
122
|
+
return await fetch({ ...options, retryCount: 1 });
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (!isTransientError(error))
|
|
126
|
+
throw error;
|
|
127
|
+
lastError = error;
|
|
128
|
+
if (attempt < transientRetryCount)
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, transientRetryDelay * 2 ** attempt));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
throw lastError;
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* True for transient indexer errors: an HTTP-level transient failure
|
|
138
|
+
* (408/429/5xx), or a `FetchRequestError` that came back on a **2xx** HTTP
|
|
139
|
+
* response whose message matches a known transient failure.
|
|
140
|
+
*
|
|
141
|
+
* The 2xx gate on the message pattern matters. The indexer reports two
|
|
142
|
+
* different `db error`s: a transient ClickHouse hiccup arrives on an HTTP 200
|
|
143
|
+
* with `{ ok: false, error: 'db error' }` (worth retrying), whereas an HTTP
|
|
144
|
+
* 422 `db error` means the planner cannot execute that query shape at all — a
|
|
145
|
+
* deterministic failure that will never succeed on retry. Retrying the latter
|
|
146
|
+
* would just burn the backoff budget before failing anyway, so 4xx statuses
|
|
147
|
+
* other than 408/429 are excluded.
|
|
148
|
+
*/
|
|
149
|
+
function isTransientError(error) {
|
|
150
|
+
if (!(error instanceof Tidx.FetchRequestError))
|
|
151
|
+
return false;
|
|
152
|
+
if (error.status === 408 || error.status === 429 || error.status >= 500)
|
|
153
|
+
return true;
|
|
154
|
+
return error.status >= 200 && error.status < 300 && transientErrorPattern.test(error.message);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=Tidx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tidx.js","sourceRoot":"","sources":["../../src/internal/Tidx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Context, MiddlewareHandler } from 'hono';
|
|
2
|
+
/** Hono variables used to collect Server-Timing metrics. */
|
|
3
|
+
export type Variables = {
|
|
4
|
+
/** Metrics emitted in the `Server-Timing` response header. */
|
|
5
|
+
serverTiming?: Metric[] | undefined;
|
|
6
|
+
};
|
|
7
|
+
/** Hono environment shape used by timing helpers. */
|
|
8
|
+
export type Environment = {
|
|
9
|
+
Variables: Variables;
|
|
10
|
+
};
|
|
11
|
+
/** One Server-Timing metric. */
|
|
12
|
+
export type Metric = {
|
|
13
|
+
/** Metric duration in milliseconds. */
|
|
14
|
+
duration: number;
|
|
15
|
+
/** Metric name. */
|
|
16
|
+
name: string;
|
|
17
|
+
};
|
|
18
|
+
/** Adds a `Server-Timing` header with total request duration. */
|
|
19
|
+
export declare function middleware<environment extends Environment = Environment>(): MiddlewareHandler<environment>;
|
|
20
|
+
/** Measures one async operation and adds it to the current request timings. */
|
|
21
|
+
export declare function time<environment extends Environment, value>(c: Context<environment>, name: string, fn: () => Promise<value> | value): Promise<value>;
|
|
22
|
+
//# sourceMappingURL=Timing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timing.d.ts","sourceRoot":"","sources":["../../src/internal/Timing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAA;AAEtD,4DAA4D;AAC5D,MAAM,MAAM,SAAS,GAAG;IACtB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CACpC,CAAA;AAED,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAED,gCAAgC;AAChC,MAAM,MAAM,MAAM,GAAG;IACnB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CACxB,WAAW,SAAS,WAAW,GAAG,WAAW,KAC1C,iBAAiB,CAAC,WAAW,CAAC,CAalC;AAED,+EAA+E;AAC/E,wBAAsB,IAAI,CAAC,WAAW,SAAS,WAAW,EAAE,KAAK,EAC/D,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EACvB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,kBAQjC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Adds a `Server-Timing` header with total request duration. */
|
|
2
|
+
export function middleware() {
|
|
3
|
+
return async (c, next) => {
|
|
4
|
+
const metrics = [];
|
|
5
|
+
c.set('serverTiming', metrics);
|
|
6
|
+
const start = performance.now();
|
|
7
|
+
await next();
|
|
8
|
+
metrics.push({ duration: performance.now() - start, name: 'request' });
|
|
9
|
+
const value = format(metrics);
|
|
10
|
+
const existing = c.res.headers.get('Server-Timing');
|
|
11
|
+
c.res.headers.set('Server-Timing', existing ? `${existing}, ${value}` : value);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Measures one async operation and adds it to the current request timings. */
|
|
15
|
+
export async function time(c, name, fn) {
|
|
16
|
+
const start = performance.now();
|
|
17
|
+
try {
|
|
18
|
+
return await fn();
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
c.get('serverTiming')?.push({ duration: performance.now() - start, name });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function format(metrics) {
|
|
25
|
+
return metrics
|
|
26
|
+
.map((metric) => `${name(metric.name)};dur=${metric.duration.toFixed(1)}`)
|
|
27
|
+
.join(', ');
|
|
28
|
+
}
|
|
29
|
+
function name(value) {
|
|
30
|
+
return value.replace(/[^A-Za-z0-9_.*-]/g, '_');
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=Timing.js.map
|