From f8aef97de8d09901cde5d00b7407ec8bebbbe5c7 Mon Sep 17 00:00:00 2001 From: Gheorghe Pinzaru Date: Sat, 8 Feb 2025 10:23:22 +0700 Subject: [PATCH] Make in memory stores more flexible --- .changeset/silent-squids-sparkle.md | 5 ++ .../content/docs/welcome/getting-started.mdx | 26 ++++++--- .../src/in-memory/abi-store.ts | 53 ++++--------------- .../src/in-memory/contract-meta-store.ts | 20 +++---- .../src/in-memory/index.ts | 4 +- 5 files changed, 43 insertions(+), 65 deletions(-) create mode 100644 .changeset/silent-squids-sparkle.md diff --git a/.changeset/silent-squids-sparkle.md b/.changeset/silent-squids-sparkle.md new file mode 100644 index 00000000..ef8ceb54 --- /dev/null +++ b/.changeset/silent-squids-sparkle.md @@ -0,0 +1,5 @@ +--- +'@3loop/transaction-decoder': minor +--- + +Make in-memory store more flexible by folllowing the same API as SQL diff --git a/apps/docs/src/content/docs/welcome/getting-started.mdx b/apps/docs/src/content/docs/welcome/getting-started.mdx index d61d4c1a..c0348635 100644 --- a/apps/docs/src/content/docs/welcome/getting-started.mdx +++ b/apps/docs/src/content/docs/welcome/getting-started.mdx @@ -40,12 +40,15 @@ The `InMemoryAbiStoreLive` provides default ABI loading and caching functionalit ```ts import { InMemoryAbiStoreLive } from '@3loop/transaction-decoder/in-memory' -import { ConfigProvider, Layer } from 'effect' - -// We use Effect library to provide custom configuration -const Config = ConfigProvider.fromMap(new Map([['ETHERSCAN_API_KEY', 'YourApiKey']])) -const ABILoaderLayer = Layer.setConfigProvider(Config) -const abiStore = InMemoryAbiStoreLive.pipe(Layer.provide(ABILoaderLayer)) +import { EtherscanV2StrategyResolver } from '@3loop/transaction-decoder' + +const abiStore = InMemoryAbiStoreLive.make({ + default: [ + EtherscanV2StrategyResolver({ + apikey: 'YourApiKey', // provide Etherscan V2 API key + }), + ], +}) ``` For a custom implementation, see our [How To Decode Transaction (ABI Data Store)](/guides/decode-transaction/#2-abi-data-store) guide. @@ -59,8 +62,17 @@ The `InMemoryContractMetaStoreLive` handles contract metadata resolution: ```ts import { InMemoryContractMetaStoreLive } from '@3loop/transaction-decoder/in-memory' +import { Layer } from 'effect' + +const contractMetaStore = Layer.unwrapEffect( + Effect.gen(function* () { + const service = yield* PublicClient -const contractMetaStore = InMemoryContractMetaStoreLive + return InMemoryContractMetaStoreLive.make({ + default: [ERC20RPCStrategyResolver(service), ProxyRPCStrategyResolver(service)], + }) + }), +) ``` For a custom implementation, see our [How To Decode Transaction (Contract Metadata Store)](/guides/decode-transaction/#3-contract-metadata-store) guide. diff --git a/packages/transaction-decoder/src/in-memory/abi-store.ts b/packages/transaction-decoder/src/in-memory/abi-store.ts index 7b5ec627..f6803078 100644 --- a/packages/transaction-decoder/src/in-memory/abi-store.ts +++ b/packages/transaction-decoder/src/in-memory/abi-store.ts @@ -1,47 +1,13 @@ -import { - EtherscanStrategyResolver, - FourByteStrategyResolver, - ContractABI, - AbiStore, - SourcifyStrategyResolver, - OpenchainStrategyResolver, - EtherscanV2StrategyResolver, -} from '../effect.js' -import { Config, Effect, Layer } from 'effect' +import { ContractABI, AbiStore } from '../effect.js' +import { Effect, Layer } from 'effect' const abiCache = new Map() -export const InMemoryAbiStoreLive = Layer.effect( - AbiStore, - Effect.gen(function* () { - const etherscanApiKey = yield* Config.string('ETHERSCAN_API_KEY').pipe( - Effect.catchTag('ConfigError', () => { - return Effect.succeed(undefined) - }), - ) - const etherscanEndpoint = yield* Config.string('ETHERSCAN_ENDPOINT').pipe(Effect.orElseSucceed(() => undefined)) - - const etherscanStrategy = - etherscanEndpoint && etherscanApiKey - ? EtherscanStrategyResolver({ - apikey: etherscanApiKey, - endpoint: etherscanEndpoint, - }) - : etherscanApiKey - ? EtherscanV2StrategyResolver({ - apikey: etherscanApiKey, - }) - : undefined - - return AbiStore.of({ - strategies: { - default: [ - etherscanStrategy, - SourcifyStrategyResolver(), - OpenchainStrategyResolver(), - FourByteStrategyResolver(), - ].filter(Boolean), - }, +export const make = (strategies: AbiStore['strategies']) => + Layer.succeed( + AbiStore, + AbiStore.of({ + strategies, set: (_key, value) => Effect.sync(() => { if (value.status === 'success') { @@ -82,6 +48,5 @@ export const InMemoryAbiStoreLive = Layer.effect( result: null, } }), - }) - }), -) + }), + ) diff --git a/packages/transaction-decoder/src/in-memory/contract-meta-store.ts b/packages/transaction-decoder/src/in-memory/contract-meta-store.ts index f7850dc9..7786c379 100644 --- a/packages/transaction-decoder/src/in-memory/contract-meta-store.ts +++ b/packages/transaction-decoder/src/in-memory/contract-meta-store.ts @@ -1,17 +1,14 @@ import type { ContractData } from '../types.js' -import { ContractMetaStore, ERC20RPCStrategyResolver, NFTRPCStrategyResolver, PublicClient } from '../effect.js' +import { ContractMetaStore } from '../effect.js' import { Effect, Layer } from 'effect' const contractMetaCache = new Map() -export const InMemoryContractMetaStoreLive = Layer.effect( - ContractMetaStore, - Effect.gen(function* () { - const publicClient = yield* PublicClient - const erc20Loader = ERC20RPCStrategyResolver(publicClient) - const nftLoader = NFTRPCStrategyResolver(publicClient) - return ContractMetaStore.of({ - strategies: { default: [erc20Loader, nftLoader] }, +export const make = (strategies: ContractMetaStore['strategies']) => + Layer.succeed( + ContractMetaStore, + ContractMetaStore.of({ + strategies, get: ({ address, chainID }) => Effect.sync(() => { const key = `${address}-${chainID}`.toLowerCase() @@ -37,6 +34,5 @@ export const InMemoryContractMetaStoreLive = Layer.effect( contractMetaCache.set(key, result.result) } }), - }) - }), -) + }), + ) diff --git a/packages/transaction-decoder/src/in-memory/index.ts b/packages/transaction-decoder/src/in-memory/index.ts index 574c4a60..de7b79bc 100644 --- a/packages/transaction-decoder/src/in-memory/index.ts +++ b/packages/transaction-decoder/src/in-memory/index.ts @@ -1,2 +1,2 @@ -export * from './abi-store.js' -export * from './contract-meta-store.js' +export * as InMemoryAbiStoreLive from './abi-store.js' +export * as InMemoryContractMetaStoreLive from './contract-meta-store.js'