@prb/effect-evm 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/dist/gas/estimator.d.ts.map +1 -1
- package/dist/gas/estimator.js +17 -16
- package/dist/gas/estimator.js.map +1 -1
- package/dist/integrations/wagmi/layers.d.ts +2 -2
- package/dist/presets/index.d.ts +1 -0
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +1 -0
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/layers.d.ts +1 -1
- package/dist/{rpc → presets}/routemesh.d.ts +1 -1
- package/dist/presets/routemesh.d.ts.map +1 -0
- package/dist/{rpc → presets}/routemesh.js +1 -1
- package/dist/presets/routemesh.js.map +1 -0
- package/dist/query/client.d.ts +1 -1
- package/dist/rpc/index.d.ts +1 -2
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +1 -2
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/retry.d.ts +1 -0
- package/dist/rpc/retry.d.ts.map +1 -1
- package/dist/rpc/retry.js +8 -1
- package/dist/rpc/retry.js.map +1 -1
- package/dist/transfer/service.d.ts +7 -10
- package/dist/transfer/service.d.ts.map +1 -1
- package/dist/transfer/service.js +29 -10
- package/dist/transfer/service.js.map +1 -1
- package/dist/tx/fees.d.ts.map +1 -1
- package/dist/tx/fees.js +3 -0
- package/dist/tx/fees.js.map +1 -1
- package/dist/tx/internal/receipt-retry.d.ts +5 -0
- package/dist/tx/internal/receipt-retry.d.ts.map +1 -0
- package/dist/tx/internal/receipt-retry.js +31 -0
- package/dist/tx/internal/receipt-retry.js.map +1 -0
- package/dist/tx/manager.d.ts.map +1 -1
- package/dist/tx/manager.js +227 -152
- package/dist/tx/manager.js.map +1 -1
- package/dist/tx/manager.test.integration.js +35 -1
- package/dist/tx/manager.test.integration.js.map +1 -1
- package/dist/tx/policy.d.ts +1 -0
- package/dist/tx/policy.d.ts.map +1 -1
- package/dist/tx/policy.js.map +1 -1
- package/dist/types/tx-overrides.d.ts +1 -1
- package/dist/types/tx-overrides.d.ts.map +1 -1
- package/dist/types/tx-overrides.js.map +1 -1
- package/package.json +3 -4
- package/CONTRIBUTING.md +0 -42
- package/dist/rpc/routemesh.d.ts.map +0 -1
- package/dist/rpc/routemesh.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Common Changelog](https://common-changelog.org/).
|
|
6
|
+
|
|
7
|
+
[1.0.0]: https://github.com/PaulRBerg/prb-effect/releases/tag/%40prb%2Feffect-evm%401.0.0
|
|
8
|
+
|
|
9
|
+
## [1.0.0] - 2026-02-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add Contract services: `ContractReader` (multicall), `ContractWriter`, `ContractPipeline`, `typedContract`
|
|
14
|
+
- Add Transaction management with `TxManager` and reactive state tracking
|
|
15
|
+
- Add Event streams: `EventStream`, `ReliableEventStream` with confirmation filtering and reorg handling
|
|
16
|
+
- Add Chain utilities: `BalanceService`, `BlockService`, `GasService`, `NonceService`
|
|
17
|
+
- Add Deploy and NFT services: `DeployService`, `Erc721Service`
|
|
18
|
+
- Add Signature and simulation: `SignatureService`, `SimulationService` (Tenderly)
|
|
19
|
+
- Add Subscriptions: `SubscriptionService` for blocks, logs, and pending transactions
|
|
20
|
+
- Add EIP-7702 delegation and atomic batching for EOAs
|
|
21
|
+
- Add React hooks via `@prb/effect-evm/react-hooks`
|
|
22
|
+
- Add Safe detection hooks: `useIsSafeAppContext`, `useIsHostSafeApp`, `useIsSafeMultisigWallet`
|
|
23
|
+
- Add Wagmi integration via `@prb/effect-evm/wagmi`
|
|
24
|
+
- Add Browser persistence utilities in `browser` namespace
|
|
25
|
+
- Add Testing kit via `@prb/effect-evm/testing-kit`
|
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimator.d.ts","sourceRoot":"","sources":["../../src/gas/estimator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"estimator.d.ts","sourceRoot":"","sources":["../../src/gas/estimator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAgFF,eAAO,MAAM,mBAAmB,GAC9B,qBAAqB,wBAAwB,EAC7C,SAAS,MAAM,KACd,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,mBAAmB,CAapE,CAAC;AAEL,eAAO,MAAM,sBAAsB,GACjC,qBAAqB,wBAAwB,EAC7C,SAAS,MAAM,KACd,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,wBAAwB,GAAG,mBAAmB,CAkF1F,CAAC"}
|
package/dist/gas/estimator.js
CHANGED
|
@@ -74,24 +74,25 @@ export const getAllFeeEstimatesImpl = (publicClientService, chainId) => Effect.g
|
|
|
74
74
|
const client = yield* publicClientService.get(chainId);
|
|
75
75
|
const supportsEip1559 = yield* supportsEip1559Impl(publicClientService, chainId);
|
|
76
76
|
if (supportsEip1559) {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}),
|
|
86
|
-
Effect.tryPromise({
|
|
87
|
-
catch: (cause) => new GasPriceUnavailableError({
|
|
88
|
-
cause,
|
|
89
|
-
chainId,
|
|
90
|
-
message: `Failed to estimate max priority fee: ${String(cause)}`,
|
|
91
|
-
}),
|
|
92
|
-
try: () => client.estimateMaxPriorityFeePerGas(),
|
|
77
|
+
const getPendingOrLatestBlock = Effect.tryPromise({
|
|
78
|
+
catch: () => "pending-failed",
|
|
79
|
+
try: () => client.getBlock({ blockTag: "pending" }),
|
|
80
|
+
}).pipe(Effect.catchAll(() => Effect.tryPromise({
|
|
81
|
+
catch: (cause) => new GasPriceUnavailableError({
|
|
82
|
+
cause,
|
|
83
|
+
chainId,
|
|
84
|
+
message: `Failed to get block for fee estimation: ${String(cause)}`,
|
|
93
85
|
}),
|
|
86
|
+
try: () => client.getBlock({ blockTag: "latest" }),
|
|
87
|
+
})));
|
|
88
|
+
const [block, maxPriorityFeeResult] = yield* Effect.all([
|
|
89
|
+
getPendingOrLatestBlock,
|
|
90
|
+
Effect.tryPromise(() => client.estimateMaxPriorityFeePerGas()).pipe(Effect.option),
|
|
94
91
|
], { concurrency: 2 });
|
|
92
|
+
if (maxPriorityFeeResult._tag === "None") {
|
|
93
|
+
return yield* getLegacyFeeEstimates(client, chainId);
|
|
94
|
+
}
|
|
95
|
+
const maxPriorityFeePerGas = maxPriorityFeeResult.value;
|
|
95
96
|
let baseFee = block.baseFeePerGas;
|
|
96
97
|
if (isBaseFeeMissing(baseFee)) {
|
|
97
98
|
const latestBlock = yield* Effect.tryPromise({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimator.js","sourceRoot":"","sources":["../../src/gas/estimator.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect } from \"effect\";\nimport type { PublicClient } from \"viem\";\nimport type { ClientNotFoundError } from \"@/src/core/errors/index.js\";\nimport type { PublicClientServiceShape } from \"@/src/core/index.js\";\nimport { GasPriceUnavailableError } from \"@/src/gas/errors.js\";\n\nexport type GasSpeed = \"slow\" | \"standard\" | \"fast\" | \"instant\";\n\nexport type FeeEstimate = {\n confidence: number; // 0-100\n estimatedBaseFee: bigint;\n gasPrice?: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n};\n\n// Priority fee adjustments in gwei\nconst SPEED_ADJUSTMENTS: Record<GasSpeed, bigint> = {\n fast: 2_500_000_000n, // 2.5 gwei\n instant: 5_000_000_000n, // 5 gwei\n slow: 1_000_000_000n, // 1 gwei\n standard: 1_500_000_000n, // 1.5 gwei\n};\n\n// Confidence levels for each speed tier\nconst SPEED_CONFIDENCE: Record<GasSpeed, number> = {\n fast: 95,\n instant: 99,\n slow: 70,\n standard: 85,\n};\n\nfunction isBaseFeeMissing(baseFee: bigint | null | undefined): baseFee is null | undefined {\n return baseFee === null || baseFee === undefined;\n}\n\nfunction getLegacyFeeEstimates(\n client: PublicClient,\n chainId: number\n): Effect.Effect<Record<GasSpeed, FeeEstimate>, GasPriceUnavailableError> {\n return Effect.gen(function* () {\n const gasPrice = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get gas price: ${String(cause)}`,\n }),\n try: () => client.getGasPrice(),\n });\n\n const estimates: Record<GasSpeed, FeeEstimate> = {\n fast: {\n confidence: SPEED_CONFIDENCE.fast,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 125n) / 100n, // 1.25x\n maxFeePerGas: (gasPrice * 125n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n instant: {\n confidence: SPEED_CONFIDENCE.instant,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 150n) / 100n, // 1.5x\n maxFeePerGas: (gasPrice * 150n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n slow: {\n confidence: SPEED_CONFIDENCE.slow,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 90n) / 100n, // 0.9x\n maxFeePerGas: (gasPrice * 90n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n standard: {\n confidence: SPEED_CONFIDENCE.standard,\n estimatedBaseFee: 0n,\n gasPrice,\n maxFeePerGas: gasPrice,\n maxPriorityFeePerGas: 0n,\n },\n };\n\n return estimates;\n });\n}\n\nexport const supportsEip1559Impl = (\n publicClientService: PublicClientServiceShape,\n chainId: number\n): Effect.Effect<boolean, GasPriceUnavailableError | ClientNotFoundError> =>\n Effect.gen(function* () {\n const client = yield* publicClientService.get(chainId);\n const block = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to check EIP-1559 support: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n });\n return block.baseFeePerGas !== null && block.baseFeePerGas !== undefined;\n });\n\nexport const getAllFeeEstimatesImpl = (\n publicClientService: PublicClientServiceShape,\n chainId: number\n): Effect.Effect<Record<GasSpeed, FeeEstimate>, GasPriceUnavailableError | ClientNotFoundError> =>\n Effect.gen(function* () {\n const client = yield* publicClientService.get(chainId);\n const supportsEip1559 = yield* supportsEip1559Impl(publicClientService, chainId);\n\n if (supportsEip1559) {\n // EIP-1559 fee estimation\n const [block, maxPriorityFeePerGas] = yield* Effect.all(\n [\n Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get pending block: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"pending\" }),\n }),\n Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to estimate max priority fee: ${String(cause)}`,\n }),\n try: () => client.estimateMaxPriorityFeePerGas(),\n }),\n ],\n { concurrency: 2 }\n );\n\n let baseFee = block.baseFeePerGas;\n if (isBaseFeeMissing(baseFee)) {\n const latestBlock = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get latest block: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n });\n baseFee = latestBlock.baseFeePerGas;\n }\n\n if (isBaseFeeMissing(baseFee)) {\n return yield* getLegacyFeeEstimates(client, chainId);\n }\n\n // Build estimates for each speed tier\n const makeEstimate = (speed: GasSpeed): FeeEstimate => {\n const priority = maxPriorityFeePerGas + SPEED_ADJUSTMENTS[speed];\n return {\n confidence: SPEED_CONFIDENCE[speed],\n estimatedBaseFee: baseFee,\n maxFeePerGas: baseFee * 2n + priority,\n maxPriorityFeePerGas: priority,\n };\n };\n\n const estimates: Record<GasSpeed, FeeEstimate> = {\n fast: makeEstimate(\"fast\"),\n instant: makeEstimate(\"instant\"),\n slow: makeEstimate(\"slow\"),\n standard: makeEstimate(\"standard\"),\n };\n\n return estimates;\n }\n\n return yield* getLegacyFeeEstimates(client, chainId);\n });\n"]}
|
|
1
|
+
{"version":3,"file":"estimator.js","sourceRoot":"","sources":["../../src/gas/estimator.ts"],"names":[],"mappings":"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","sourcesContent":["import { Effect } from \"effect\";\nimport type { PublicClient } from \"viem\";\nimport type { ClientNotFoundError } from \"@/src/core/errors/index.js\";\nimport type { PublicClientServiceShape } from \"@/src/core/index.js\";\nimport { GasPriceUnavailableError } from \"@/src/gas/errors.js\";\n\nexport type GasSpeed = \"slow\" | \"standard\" | \"fast\" | \"instant\";\n\nexport type FeeEstimate = {\n confidence: number; // 0-100\n estimatedBaseFee: bigint;\n gasPrice?: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n};\n\n// Priority fee adjustments in gwei\nconst SPEED_ADJUSTMENTS: Record<GasSpeed, bigint> = {\n fast: 2_500_000_000n, // 2.5 gwei\n instant: 5_000_000_000n, // 5 gwei\n slow: 1_000_000_000n, // 1 gwei\n standard: 1_500_000_000n, // 1.5 gwei\n};\n\n// Confidence levels for each speed tier\nconst SPEED_CONFIDENCE: Record<GasSpeed, number> = {\n fast: 95,\n instant: 99,\n slow: 70,\n standard: 85,\n};\n\n/**\n * Type guard for missing base fee. Some chains (e.g., BNB Chain) report EIP-1559 support\n * inconsistently - the latest block may have `baseFeePerGas` while pending blocks do not.\n */\nfunction isBaseFeeMissing(baseFee: bigint | null | undefined): baseFee is null | undefined {\n return baseFee === null || baseFee === undefined;\n}\n\n/**\n * Legacy fee estimation using `eth_gasPrice`. Used for chains without EIP-1559 support\n * (e.g., BNB Chain) or as a fallback when base fee is unavailable.\n */\nfunction getLegacyFeeEstimates(\n client: PublicClient,\n chainId: number\n): Effect.Effect<Record<GasSpeed, FeeEstimate>, GasPriceUnavailableError> {\n return Effect.gen(function* () {\n const gasPrice = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get gas price: ${String(cause)}`,\n }),\n try: () => client.getGasPrice(),\n });\n\n const estimates: Record<GasSpeed, FeeEstimate> = {\n fast: {\n confidence: SPEED_CONFIDENCE.fast,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 125n) / 100n, // 1.25x\n maxFeePerGas: (gasPrice * 125n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n instant: {\n confidence: SPEED_CONFIDENCE.instant,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 150n) / 100n, // 1.5x\n maxFeePerGas: (gasPrice * 150n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n slow: {\n confidence: SPEED_CONFIDENCE.slow,\n estimatedBaseFee: 0n,\n gasPrice: (gasPrice * 90n) / 100n, // 0.9x\n maxFeePerGas: (gasPrice * 90n) / 100n,\n maxPriorityFeePerGas: 0n,\n },\n standard: {\n confidence: SPEED_CONFIDENCE.standard,\n estimatedBaseFee: 0n,\n gasPrice,\n maxFeePerGas: gasPrice,\n maxPriorityFeePerGas: 0n,\n },\n };\n\n return estimates;\n });\n}\n\nexport const supportsEip1559Impl = (\n publicClientService: PublicClientServiceShape,\n chainId: number\n): Effect.Effect<boolean, GasPriceUnavailableError | ClientNotFoundError> =>\n Effect.gen(function* () {\n const client = yield* publicClientService.get(chainId);\n const block = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to check EIP-1559 support: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n });\n return block.baseFeePerGas !== null && block.baseFeePerGas !== undefined;\n });\n\nexport const getAllFeeEstimatesImpl = (\n publicClientService: PublicClientServiceShape,\n chainId: number\n): Effect.Effect<Record<GasSpeed, FeeEstimate>, GasPriceUnavailableError | ClientNotFoundError> =>\n Effect.gen(function* () {\n const client = yield* publicClientService.get(chainId);\n const supportsEip1559 = yield* supportsEip1559Impl(publicClientService, chainId);\n\n if (supportsEip1559) {\n // EIP-1559 fee estimation\n // Try pending block first, fall back to latest for chains that don't support pending (L2s)\n const getPendingOrLatestBlock = Effect.tryPromise({\n catch: () => \"pending-failed\" as const,\n try: () => client.getBlock({ blockTag: \"pending\" }),\n }).pipe(\n Effect.catchAll(() =>\n Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get block for fee estimation: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n })\n )\n );\n\n const [block, maxPriorityFeeResult] = yield* Effect.all(\n [\n getPendingOrLatestBlock,\n Effect.tryPromise(() => client.estimateMaxPriorityFeePerGas()).pipe(Effect.option),\n ],\n { concurrency: 2 }\n );\n\n // Fall back to legacy estimation if priority fee estimation is unsupported\n if (maxPriorityFeeResult._tag === \"None\") {\n return yield* getLegacyFeeEstimates(client, chainId);\n }\n\n const maxPriorityFeePerGas = maxPriorityFeeResult.value;\n\n let baseFee = block.baseFeePerGas;\n if (isBaseFeeMissing(baseFee)) {\n const latestBlock = yield* Effect.tryPromise({\n catch: (cause) =>\n new GasPriceUnavailableError({\n cause,\n chainId,\n message: `Failed to get latest block: ${String(cause)}`,\n }),\n try: () => client.getBlock({ blockTag: \"latest\" }),\n });\n baseFee = latestBlock.baseFeePerGas;\n }\n\n // BNB Chain and similar networks may pass the EIP-1559 check but lack base fees\n // in practice. Fall back to legacy estimation when this occurs.\n if (isBaseFeeMissing(baseFee)) {\n return yield* getLegacyFeeEstimates(client, chainId);\n }\n\n // Build estimates for each speed tier\n const makeEstimate = (speed: GasSpeed): FeeEstimate => {\n const priority = maxPriorityFeePerGas + SPEED_ADJUSTMENTS[speed];\n return {\n confidence: SPEED_CONFIDENCE[speed],\n estimatedBaseFee: baseFee,\n maxFeePerGas: baseFee * 2n + priority,\n maxPriorityFeePerGas: priority,\n };\n };\n\n const estimates: Record<GasSpeed, FeeEstimate> = {\n fast: makeEstimate(\"fast\"),\n instant: makeEstimate(\"instant\"),\n slow: makeEstimate(\"slow\"),\n standard: makeEstimate(\"standard\"),\n };\n\n return estimates;\n }\n\n return yield* getLegacyFeeEstimates(client, chainId);\n });\n"]}
|
|
@@ -7,6 +7,6 @@ export type WagmiWalletClientOptions = {
|
|
|
7
7
|
};
|
|
8
8
|
export declare function makePublicClientLayerFromWagmi(config: Config): Layer.Layer<PublicClientService>;
|
|
9
9
|
export declare function makeWalletClientLayerFromWagmi(config: Config, options?: WagmiWalletClientOptions): Layer.Layer<WalletClientService>;
|
|
10
|
-
export declare function makeEffectEvmLayerFromWagmi(config: Config, options?: WagmiWalletClientOptions): Layer.Layer<PublicClientService | WalletClientService | import("../../index.js").ContractReader | import("../../index.js").EventBackfill | import("../../index.js").CursorStore | import("../../index.js").CursorStream | import("../../index.js").EventStream | import("../../index.js").ReliableEventStream | import("../../index.js").GasService | import("../../index.js").NonceService | import("../../index.js").
|
|
11
|
-
export declare function makeEffectEvmLayerFromWagmiWithWalletProviderRef(config: Config, options?: WagmiWalletClientOptions): Layer.Layer<import("../../wallet/index.js").WalletLifecycle | import("../../wallet/index.js").WalletProviderRef | import("../../wallet/index.js").WalletService | PublicClientService | WalletClientService | import("../../index.js").ContractReader | import("../../index.js").EventBackfill | import("../../index.js").CursorStore | import("../../index.js").CursorStream | import("../../index.js").EventStream | import("../../index.js").ReliableEventStream | import("../../index.js").GasService | import("../../index.js").NonceService | import("../../index.js").
|
|
10
|
+
export declare function makeEffectEvmLayerFromWagmi(config: Config, options?: WagmiWalletClientOptions): Layer.Layer<PublicClientService | WalletClientService | import("../../index.js").ContractReader | import("../../index.js").EventBackfill | import("../../index.js").CursorStore | import("../../index.js").CursorStream | import("../../index.js").EventStream | import("../../index.js").ReliableEventStream | import("../../index.js").GasService | import("../../index.js").NonceService | import("../../index.js").RpcCache | import("../../index.js").RequestDedup | import("../../index.js").TxReplacement | import("../../index.js").TxManager | import("../../index.js").ContractPipeline | import("../../index.js").ContractWriter | import("../../index.js").BalanceService | import("../../index.js").BlockService | import("../../index.js").DeployService | import("../../index.js").Eip7702Service | import("../../index.js").EnsResolver | import("../../index.js").Erc721Service | import("../../index.js").SubscriptionService | import("../../index.js").ChainHead | import("../../index.js").QueryClient | import("../../index.js").MulticallBatcher | import("../../index.js").ContractQuery | import("../../index.js").SignatureService | import("../../index.js").SimulationService, never, never>;
|
|
11
|
+
export declare function makeEffectEvmLayerFromWagmiWithWalletProviderRef(config: Config, options?: WagmiWalletClientOptions): Layer.Layer<import("../../wallet/index.js").WalletLifecycle | import("../../wallet/index.js").WalletProviderRef | import("../../wallet/index.js").WalletService | PublicClientService | WalletClientService | import("../../index.js").ContractReader | import("../../index.js").EventBackfill | import("../../index.js").CursorStore | import("../../index.js").CursorStream | import("../../index.js").EventStream | import("../../index.js").ReliableEventStream | import("../../index.js").GasService | import("../../index.js").NonceService | import("../../index.js").RpcCache | import("../../index.js").RequestDedup | import("../../index.js").TxReplacement | import("../../index.js").TxManager | import("../../index.js").ContractPipeline | import("../../index.js").ContractWriter | import("../../index.js").BalanceService | import("../../index.js").BlockService | import("../../index.js").DeployService | import("../../index.js").Eip7702Service | import("../../index.js").EnsResolver | import("../../index.js").Erc721Service | import("../../index.js").SubscriptionService | import("../../index.js").ChainHead | import("../../index.js").QueryClient | import("../../index.js").MulticallBatcher | import("../../index.js").ContractQuery | import("../../index.js").SignatureService | import("../../index.js").SimulationService, never, never>;
|
|
12
12
|
//# sourceMappingURL=layers.d.ts.map
|
package/dist/presets/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
package/dist/presets/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC","sourcesContent":["export * from \"./layers.js\";\nexport * from \"./transports.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC","sourcesContent":["export * from \"./layers.js\";\nexport * from \"./routemesh.js\";\nexport * from \"./transports.js\";\n"]}
|
package/dist/presets/layers.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export declare function makeWalletClientLayer(provider: {
|
|
|
51
51
|
request: (...args: unknown[]) => Promise<unknown>;
|
|
52
52
|
}, chains: Map<number, Chain>): Layer.Layer<WalletClientService>;
|
|
53
53
|
export declare function makeWalletClientLayerFromProviderRef(chains: Map<number, Chain>): Layer.Layer<WalletClientService, never, WalletProviderRef>;
|
|
54
|
-
export declare const effectEvmServices: Layer.Layer<ContractReader | EventBackfill | CursorStore | CursorStream | EventStream | ReliableEventStream | GasService | NonceService | TxReplacement | TxManager | ContractPipeline | ContractWriter | BalanceService | BlockService | DeployService | Eip7702Service | EnsResolver | Erc721Service | SubscriptionService | ChainHead |
|
|
54
|
+
export declare const effectEvmServices: Layer.Layer<ContractReader | EventBackfill | CursorStore | CursorStream | EventStream | ReliableEventStream | GasService | NonceService | RpcCache | RequestDedup | TxReplacement | TxManager | ContractPipeline | ContractWriter | BalanceService | BlockService | DeployService | Eip7702Service | EnsResolver | Erc721Service | SubscriptionService | ChainHead | QueryClient | MulticallBatcher | ContractQuery | SignatureService | SimulationService, never, PublicClientService | WalletClientService>;
|
|
55
55
|
export declare function makeEffectEvmLayer(configs: ChainConfig[], provider: {
|
|
56
56
|
request: (...args: unknown[]) => Promise<unknown>;
|
|
57
57
|
}): Layer.Layer<PublicClientService | WalletClientService | BalanceService | BlockService | ChainHead | ContractReader | ContractQuery | ContractWriter | ContractPipeline | Eip7702Service | DeployService | Erc721Service | GasService | NonceService | QueryClient | MulticallBatcher | RpcCache | RequestDedup | SignatureService | SimulationService | SubscriptionService | TxManager | TxReplacement | EventBackfill | EventStream | CursorStore | CursorStream | ReliableEventStream | EnsResolver | WalletService | WalletLifecycle>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import type { Chain, Transport } from "viem";
|
|
3
|
-
import type { ChainConfig } from "
|
|
3
|
+
import type { ChainConfig } from "./layers.js";
|
|
4
4
|
export declare const ROUTEMESH_BASE_URL = "https://lb.routeme.sh/rpc";
|
|
5
5
|
export type RouteMeshChainEntry = {
|
|
6
6
|
readonly chainId: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routemesh.d.ts","sourceRoot":"","sources":["../../src/presets/routemesh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAO9D,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB,CAAC;AAKF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACjD,CAAC;AAKF,MAAM,MAAM,2BAA2B,GAAG,mBAAmB,GAAG;IAC9D,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C,CAAC;;;;;;AAIF,qBAAa,2BAA4B,SAAQ,gCAKhD;CAAG;AAaJ,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,MACjB,CAAC;AAa/C,eAAO,MAAM,YAAY,GACtB,SAAS,MAAM,KAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAEf,CAAC;AAwBlC,eAAO,MAAM,uBAAuB,GAAI,QAAQ,eAAe,KAAG,WAAW,EAKxE,CAAC;AAmBN,eAAO,MAAM,qBAAqB,GAChC,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,cAAc,SAAS,MAAM,EAAE,KAC9B,MAAM,EAAsD,CAAC;AAsBhE,eAAO,MAAM,uBAAuB,GAClC,QAAQ,MAAM,EACd,QAAQ,SAAS,2BAA2B,EAAE,KAC7C,MAAM,CAAC,MAAM,EAAE,SAAS,CAQxB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { makeFallbackTransport } from "
|
|
2
|
+
import { makeFallbackTransport } from "./transports.js";
|
|
3
3
|
export const ROUTEMESH_BASE_URL = "https://lb.routeme.sh/rpc";
|
|
4
4
|
export class RouteMeshApiKeyMissingError extends Schema.TaggedError()("RouteMeshApiKeyMissingError", {
|
|
5
5
|
message: Schema.String,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routemesh.js","sourceRoot":"","sources":["../../src/presets/routemesh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AA6B9D,MAAM,OAAO,2BAA4B,SAAQ,MAAM,CAAC,WAAW,EAA+B,CAChG,6BAA6B,EAC7B;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAaJ,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,MAAc,EAAU,EAAE,CACtE,GAAG,kBAAkB,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;AAa/C,MAAM,CAAC,MAAM,YAAY,GACvB,CAAC,OAAe,EAAgC,EAAE,CAClD,CAAC,MAAM,EAAE,EAAE,CACT,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAwBlC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAuB,EAAiB,EAAE,CAChF,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;IAClB,OAAO,EAAE,KAAK,CAAC,OAAO;IACtB,OAAO,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC,CAAC,CAAC;AAmBN,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,OAAe,EACf,MAAc,EACd,YAA+B,EACrB,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC;AAsBhE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,MAAc,EACd,MAA8C,EACnB,EAAE,CAC7B,MAAM,CAAC,MAAM,CACX,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACb,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACpF,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC;AACb,CAAC,EACD,EAA+B,CAChC,CAAC","sourcesContent":["import { Schema } from \"effect\";\nimport type { Chain, Transport } from \"viem\";\n\nimport type { ChainConfig } from \"./layers.js\";\nimport { makeFallbackTransport } from \"./transports.js\";\n\n// === Constants ===\n\nexport const ROUTEMESH_BASE_URL = \"https://lb.routeme.sh/rpc\";\n\n// === Types ===\n\n/**\n * Configuration for a single chain using RouteMesh\n */\nexport type RouteMeshChainEntry = {\n readonly chainId: number;\n readonly chain: Chain;\n};\n\n/**\n * Full RouteMesh configuration with API key\n */\nexport type RouteMeshConfig = {\n readonly apiKey: string;\n readonly chains: readonly RouteMeshChainEntry[];\n};\n\n/**\n * Configuration for a chain with RouteMesh primary + optional fallback URLs\n */\nexport type RouteMeshFallbackChainEntry = RouteMeshChainEntry & {\n readonly fallbackUrls?: readonly string[];\n};\n\n// === Errors ===\n\nexport class RouteMeshApiKeyMissingError extends Schema.TaggedError<RouteMeshApiKeyMissingError>()(\n \"RouteMeshApiKeyMissingError\",\n {\n message: Schema.String,\n }\n) {}\n\n// === URL Generation ===\n\n/**\n * Generate a RouteMesh RPC URL for a specific chain\n *\n * @example\n * ```ts\n * const url = routemeshUrl(1, \"my-api-key\");\n * // => \"https://lb.routeme.sh/rpc/1/my-api-key\"\n * ```\n */\nexport const routemeshUrl = (chainId: number, apiKey: string): string =>\n `${ROUTEMESH_BASE_URL}/${chainId}/${apiKey}`;\n\n/**\n * Create a URL generator function for a specific chain.\n * Useful for deferred API key resolution.\n *\n * @example\n * ```ts\n * const mainnetRpc = routemeshRpc(1);\n * const url = mainnetRpc(\"my-api-key\");\n * // => \"https://lb.routeme.sh/rpc/1/my-api-key\"\n * ```\n */\nexport const routemeshRpc =\n (chainId: number): ((apiKey: string) => string) =>\n (apiKey) =>\n routemeshUrl(chainId, apiKey);\n\n// === ChainConfig Integration ===\n\n/**\n * Convert RouteMesh configuration to ChainConfig array.\n * Primary integration point with existing layer factories.\n *\n * @example\n * ```ts\n * import { mainnet, arbitrum } from \"viem/chains\";\n * import { makePublicClientLayer, routemeshToChainConfigs } from \"effect-evm\";\n *\n * const configs = routemeshToChainConfigs({\n * apiKey: \"my-api-key\",\n * chains: [\n * { chainId: mainnet.id, chain: mainnet },\n * { chainId: arbitrum.id, chain: arbitrum },\n * ],\n * });\n *\n * const layer = makePublicClientLayer(configs);\n * ```\n */\nexport const routemeshToChainConfigs = (config: RouteMeshConfig): ChainConfig[] =>\n config.chains.map((entry) => ({\n chain: entry.chain,\n chainId: entry.chainId,\n rpcUrls: [routemeshUrl(entry.chainId, config.apiKey)],\n }));\n\n// === Fallback Composition ===\n\n/**\n * Create fallback URLs combining RouteMesh with other providers.\n * RouteMesh URL is placed first (primary).\n *\n * @example\n * ```ts\n * import { mainnet } from \"viem/chains\";\n *\n * const urls = routemeshWithFallback(mainnet.id, \"api-key\", [\n * \"https://eth.llamarpc.com\",\n * \"https://rpc.ankr.com/eth\",\n * ]);\n * // => [\"https://lb.routeme.sh/rpc/1/api-key\", \"https://eth.llamarpc.com\", ...]\n * ```\n */\nexport const routemeshWithFallback = (\n chainId: number,\n apiKey: string,\n fallbackUrls: readonly string[]\n): string[] => [routemeshUrl(chainId, apiKey), ...fallbackUrls];\n\n/**\n * Create chain transports with RouteMesh as primary and optional fallbacks.\n *\n * @example\n * ```ts\n * import { mainnet, arbitrum } from \"viem/chains\";\n * import { makeRouteMeshTransports } from \"effect-evm\";\n *\n * const transports = makeRouteMeshTransports(\"my-api-key\", [\n * { chainId: mainnet.id, chain: mainnet, fallbackUrls: [\"https://eth.llamarpc.com\"] },\n * { chainId: arbitrum.id, chain: arbitrum },\n * ]);\n *\n * // Use with viem directly\n * const client = createPublicClient({\n * chain: mainnet,\n * transport: transports[mainnet.id],\n * });\n * ```\n */\nexport const makeRouteMeshTransports = (\n apiKey: string,\n chains: readonly RouteMeshFallbackChainEntry[]\n): Record<number, Transport> =>\n chains.reduce(\n (acc, entry) => {\n const urls = routemeshWithFallback(entry.chainId, apiKey, entry.fallbackUrls ?? []);\n acc[entry.chainId] = makeFallbackTransport(urls);\n return acc;\n },\n {} as Record<number, Transport>\n );\n"]}
|
package/dist/query/client.d.ts
CHANGED
|
@@ -16,6 +16,6 @@ export type QueryClientShape = {
|
|
|
16
16
|
declare const QueryClient_base: Context.TagClass<QueryClient, "ew3/QueryClient", QueryClientShape>;
|
|
17
17
|
export declare class QueryClient extends QueryClient_base {
|
|
18
18
|
}
|
|
19
|
-
export declare const QueryClientLive: Layer.Layer<QueryClient, never,
|
|
19
|
+
export declare const QueryClientLive: Layer.Layer<QueryClient, never, RpcCache | RequestDedup | ChainHead>;
|
|
20
20
|
export {};
|
|
21
21
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/rpc/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from "./cache.js";
|
|
2
2
|
export { type CircuitBreaker, type CircuitBreakerConfig, CircuitBreakerConfigFromEnv, CircuitOpenError, type CircuitState, makeCircuitBreaker, } from "./circuit-breaker.js";
|
|
3
3
|
export * from "./dedup.js";
|
|
4
|
-
export { defaultRetryableErrors, makeRetrySchedule, type RetryConfig, RetryConfigFromEnv, withRetry, } from "./retry.js";
|
|
5
|
-
export * from "./routemesh.js";
|
|
4
|
+
export { defaultRetryableErrors, isRetryableError, makeRetrySchedule, type RetryConfig, RetryConfigFromEnv, withRetry, } from "./retry.js";
|
|
6
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/rpc/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,2BAA2B,EAC3B,gBAAgB,EAChB,KAAK,YAAY,EACjB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,WAAW,EAChB,kBAAkB,EAClB,SAAS,GACV,MAAM,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,2BAA2B,EAC3B,gBAAgB,EAChB,KAAK,YAAY,EACjB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,WAAW,EAChB,kBAAkB,EAClB,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/rpc/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from "./cache.js";
|
|
2
2
|
export { CircuitBreakerConfigFromEnv, CircuitOpenError, makeCircuitBreaker, } from "./circuit-breaker.js";
|
|
3
3
|
export * from "./dedup.js";
|
|
4
|
-
export { defaultRetryableErrors, makeRetrySchedule, RetryConfigFromEnv, withRetry, } from "./retry.js";
|
|
5
|
-
export * from "./routemesh.js";
|
|
4
|
+
export { defaultRetryableErrors, isRetryableError, makeRetrySchedule, RetryConfigFromEnv, withRetry, } from "./retry.js";
|
|
6
5
|
//# sourceMappingURL=index.js.map
|
package/dist/rpc/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAGL,2BAA2B,EAC3B,gBAAgB,EAEhB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EAEjB,kBAAkB,EAClB,SAAS,GACV,MAAM,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAGL,2BAA2B,EAC3B,gBAAgB,EAEhB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EAEjB,kBAAkB,EAClB,SAAS,GACV,MAAM,YAAY,CAAC","sourcesContent":["export * from \"./cache.js\";\nexport {\n type CircuitBreaker,\n type CircuitBreakerConfig,\n CircuitBreakerConfigFromEnv,\n CircuitOpenError,\n type CircuitState,\n makeCircuitBreaker,\n} from \"./circuit-breaker.js\";\nexport * from \"./dedup.js\";\nexport {\n defaultRetryableErrors,\n isRetryableError,\n makeRetrySchedule,\n type RetryConfig,\n RetryConfigFromEnv,\n withRetry,\n} from \"./retry.js\";\n"]}
|
package/dist/rpc/retry.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare const RetryConfigFromEnv: Config.Config<{
|
|
|
10
10
|
maxRetries: number;
|
|
11
11
|
}>;
|
|
12
12
|
export declare const defaultRetryableErrors: string[];
|
|
13
|
+
export declare const isRetryableError: (error: unknown, retryablePatterns: string[]) => boolean;
|
|
13
14
|
export declare const makeRetrySchedule: <E>(config?: RetryConfig) => Schedule.Schedule<number, E>;
|
|
14
15
|
export declare const withRetry: (config?: RetryConfig) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
15
16
|
//# sourceMappingURL=retry.d.ts.map
|
package/dist/rpc/retry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/rpc/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG;IAExC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAsBF,eAAO,MAAM,kBAAkB;;;;;EAKI,CAAC;AAMpC,eAAO,MAAM,sBAAsB,UAQlC,CAAC;
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/rpc/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG;IAExC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAsBF,eAAO,MAAM,kBAAkB;;;;;EAKI,CAAC;AAMpC,eAAO,MAAM,sBAAsB,UAQlC,CAAC;AAMF,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,EAAE,mBAAmB,MAAM,EAAE,KAAG,OAoB9E,CAAC;AASF,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,SAAS,WAAW,KAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAMtF,CAAC;AAUF,eAAO,MAAM,SAAS,GACnB,SAAS,WAAW,MACpB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CACZ,CAAC"}
|
package/dist/rpc/retry.js
CHANGED
|
@@ -15,7 +15,7 @@ export const defaultRetryableErrors = [
|
|
|
15
15
|
"502",
|
|
16
16
|
"429",
|
|
17
17
|
];
|
|
18
|
-
const isRetryableError = (error, retryablePatterns) => {
|
|
18
|
+
export const isRetryableError = (error, retryablePatterns) => {
|
|
19
19
|
if (error instanceof Error) {
|
|
20
20
|
const message = error.message.toLowerCase();
|
|
21
21
|
return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));
|
|
@@ -24,6 +24,13 @@ const isRetryableError = (error, retryablePatterns) => {
|
|
|
24
24
|
const message = error.toLowerCase();
|
|
25
25
|
return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));
|
|
26
26
|
}
|
|
27
|
+
if (error !== null &&
|
|
28
|
+
typeof error === "object" &&
|
|
29
|
+
"message" in error &&
|
|
30
|
+
typeof error.message === "string") {
|
|
31
|
+
const message = error.message.toLowerCase();
|
|
32
|
+
return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));
|
|
33
|
+
}
|
|
27
34
|
return false;
|
|
28
35
|
};
|
|
29
36
|
export const makeRetrySchedule = (config) => {
|
package/dist/rpc/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/rpc/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AA2B9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACrE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACrE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAMpC,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,WAAW;IACX,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/rpc/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AA2B9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACrE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACrE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAMpC,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,WAAW;IACX,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAMF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAE,iBAA2B,EAAW,EAAE;IACvF,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACpC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EACjC,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAI,MAAoB,EAAgC,EAAE;IACzF,MAAM,EAAE,eAAe,GAAG,sBAAsB,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;IAEpF,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAC,IAAI,CAC5C,QAAQ,CAAC,UAAU,CAAI,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAC5E,CAAC;AACJ,CAAC,CAAC;AAUF,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,MAAoB,EAAE,EAAE,CACzB,CAAU,MAA8B,EAA0B,EAAE,CAClE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAI,MAAM,CAAC,CAAC,CAAC","sourcesContent":["import { Config, Effect, Schedule } from \"effect\";\nimport type { BackoffConfig } from \"@/src/internal/index.js\";\nimport { makeBackoffSchedule } from \"@/src/internal/index.js\";\n\nexport type RetryConfig = BackoffConfig & {\n /** Array of error message patterns that should trigger retries */\n retryableErrors?: string[];\n};\n\n/**\n * Config-based retry configuration from environment variables.\n *\n * Environment variables (all optional, nested under `EW3_RETRY_` prefix):\n * - `EW3_RETRY_MAX_RETRIES`: Maximum retry attempts (default: 3)\n * - `EW3_RETRY_BASE_DELAY`: Base delay in milliseconds (default: 100)\n * - `EW3_RETRY_MAX_DELAY`: Maximum delay cap in milliseconds (default: 10_000)\n * - `EW3_RETRY_JITTER`: Enable jitter for delays (default: true)\n *\n * @example\n * ```typescript\n * import { Effect } from \"effect\";\n * import { RetryConfigFromEnv } from \"effect-evm/rpc\";\n *\n * const program = Effect.gen(function* () {\n * const config = yield* RetryConfigFromEnv;\n * // Use config for retry logic\n * });\n * ```\n */\nexport const RetryConfigFromEnv = Config.all({\n baseDelay: Config.number(\"BASE_DELAY\").pipe(Config.withDefault(100)),\n jitter: Config.boolean(\"JITTER\").pipe(Config.withDefault(true)),\n maxDelay: Config.number(\"MAX_DELAY\").pipe(Config.withDefault(10_000)),\n maxRetries: Config.number(\"MAX_RETRIES\").pipe(Config.withDefault(3)),\n}).pipe(Config.nested(\"EW3_RETRY\"));\n\n/**\n * Default retryable error patterns for RPC calls\n * Includes rate limits, timeouts, network errors, and transient HTTP errors\n */\nexport const defaultRetryableErrors = [\n \"rate limit\",\n \"timeout\",\n \"ECONNRESET\",\n \"ETIMEDOUT\",\n \"503\",\n \"502\",\n \"429\",\n];\n\n/**\n * Check if an error should be retried based on its message.\n * Handles Error instances, strings, and plain objects with a message property.\n */\nexport const isRetryableError = (error: unknown, retryablePatterns: string[]): boolean => {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));\n }\n if (typeof error === \"string\") {\n const message = error.toLowerCase();\n return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));\n }\n // Handle plain objects with message property (some RPC transports throw these)\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n const message = error.message.toLowerCase();\n return retryablePatterns.some((pattern) => message.includes(pattern.toLowerCase()));\n }\n return false;\n};\n\n/**\n * Create a retry schedule with exponential backoff\n * Only retries on errors matching the configured retryable patterns\n *\n * @param config - Retry configuration options\n * @returns Schedule that implements exponential backoff with jitter\n */\nexport const makeRetrySchedule = <E>(config?: RetryConfig): Schedule.Schedule<number, E> => {\n const { retryableErrors = defaultRetryableErrors, ...backoffConfig } = config ?? {};\n\n return makeBackoffSchedule(backoffConfig).pipe(\n Schedule.whileInput<E>((error) => isRetryableError(error, retryableErrors))\n );\n};\n\n/**\n * Apply retry logic to an Effect\n * Will retry the effect according to the configured schedule on retryable errors\n *\n * @param effect - The Effect to retry\n * @param config - Retry configuration options\n * @returns Effect that will be retried on transient failures\n */\nexport const withRetry =\n (config?: RetryConfig) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.retry(effect, makeRetrySchedule<E>(config));\n"]}
|
|
@@ -2,27 +2,24 @@ import { Context, Effect, Layer } from "effect";
|
|
|
2
2
|
import type { Address, Hash, TransactionReceipt } from "viem";
|
|
3
3
|
import type { ClientNotFoundError, WrongNetworkError } from "../core/index.js";
|
|
4
4
|
import { InsufficientFundsError, PublicClientService, ReceiptTimeoutError, TxFailedError, UserRejectedError, WalletClientService, WalletNotConnectedError } from "../core/index.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
readonly maxPriorityFeePerGas?: bigint;
|
|
10
|
-
readonly nonce?: number;
|
|
11
|
-
};
|
|
5
|
+
import type { GasPriceUnavailableError } from "../gas/index.js";
|
|
6
|
+
import { GasService } from "../gas/index.js";
|
|
7
|
+
import type { TxOverrides } from "../types/index.js";
|
|
8
|
+
export type TransferOverrides = TxOverrides;
|
|
12
9
|
export type TransferServiceShape = {
|
|
13
10
|
readonly send: (params: {
|
|
14
11
|
chainId: number;
|
|
15
12
|
to: Address;
|
|
16
13
|
value: bigint;
|
|
17
14
|
overrides?: TransferOverrides;
|
|
18
|
-
}) => Effect.Effect<Hash, InsufficientFundsError | UserRejectedError | WalletNotConnectedError | WrongNetworkError | ClientNotFoundError | TxFailedError>;
|
|
15
|
+
}) => Effect.Effect<Hash, InsufficientFundsError | UserRejectedError | WalletNotConnectedError | WrongNetworkError | ClientNotFoundError | TxFailedError | GasPriceUnavailableError>;
|
|
19
16
|
readonly sendAndWait: (params: {
|
|
20
17
|
chainId: number;
|
|
21
18
|
to: Address;
|
|
22
19
|
value: bigint;
|
|
23
20
|
confirmations?: number;
|
|
24
21
|
overrides?: TransferOverrides;
|
|
25
|
-
}) => Effect.Effect<TransactionReceipt, InsufficientFundsError | UserRejectedError | WalletNotConnectedError | WrongNetworkError | ClientNotFoundError | TxFailedError | ReceiptTimeoutError>;
|
|
22
|
+
}) => Effect.Effect<TransactionReceipt, InsufficientFundsError | UserRejectedError | WalletNotConnectedError | WrongNetworkError | ClientNotFoundError | TxFailedError | ReceiptTimeoutError | GasPriceUnavailableError>;
|
|
26
23
|
readonly estimateGas: (params: {
|
|
27
24
|
chainId: number;
|
|
28
25
|
to: Address;
|
|
@@ -32,6 +29,6 @@ export type TransferServiceShape = {
|
|
|
32
29
|
declare const TransferService_base: Context.TagClass<TransferService, "ew3/TransferService", TransferServiceShape>;
|
|
33
30
|
export declare class TransferService extends TransferService_base {
|
|
34
31
|
}
|
|
35
|
-
export declare const TransferServiceLive: Layer.Layer<TransferService, never, PublicClientService | WalletClientService>;
|
|
32
|
+
export declare const TransferServiceLive: Layer.Layer<TransferService, never, PublicClientService | WalletClientService | GasService>;
|
|
36
33
|
export {};
|
|
37
34
|
//# sourceMappingURL=service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/transfer/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAgB,MAAM,MAAM,CAAC;AAE5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EACL,sBAAsB,EAGtB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/transfer/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAgB,MAAM,MAAM,CAAC;AAE5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EACL,sBAAsB,EAGtB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,iBAAiB,CAAC;KAC/B,KAAK,MAAM,CAAC,MAAM,CACjB,IAAI,EACF,sBAAsB,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,aAAa,GACb,wBAAwB,CAC3B,CAAC;IAEF,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,iBAAiB,CAAC;KAC/B,KAAK,MAAM,CAAC,MAAM,CACjB,kBAAkB,EAChB,sBAAsB,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,aAAa,GACb,mBAAmB,GACnB,wBAAwB,CAC3B,CAAC;IAEF,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAClD,CAAC;;AAEF,qBAAa,eAAgB,SAAQ,oBAGlC;CAAG;AA8BN,eAAO,MAAM,mBAAmB,6FAwK/B,CAAC"}
|
package/dist/transfer/service.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
import { MIN_TX_GAS } from "../constants/index.js";
|
|
3
3
|
import { InsufficientFundsError, isInsufficientFunds, isUserRejection, PublicClientService, ReceiptTimeoutError, TxFailedError, UserRejectedError, WalletClientService, WalletNotConnectedError, } from "../core/index.js";
|
|
4
|
+
import { GasService } from "../gas/index.js";
|
|
5
|
+
import { deriveFeeOverrides, deriveTxType } from "../tx/index.js";
|
|
4
6
|
export class TransferService extends Context.Tag("ew3/TransferService")() {
|
|
5
7
|
}
|
|
6
8
|
const classifyTransferError = (error, to) => {
|
|
@@ -25,6 +27,7 @@ const classifyTransferError = (error, to) => {
|
|
|
25
27
|
export const TransferServiceLive = Layer.effect(TransferService, Effect.gen(function* () {
|
|
26
28
|
const walletClientService = yield* WalletClientService;
|
|
27
29
|
const publicClientService = yield* PublicClientService;
|
|
30
|
+
const gasService = yield* GasService;
|
|
28
31
|
return TransferService.of({
|
|
29
32
|
estimateGas: Effect.fn("TransferService.estimateGas")(function* (params) {
|
|
30
33
|
const publicClient = yield* publicClientService.get(params.chainId);
|
|
@@ -51,15 +54,23 @@ export const TransferServiceLive = Layer.effect(TransferService, Effect.gen(func
|
|
|
51
54
|
message: "No account connected",
|
|
52
55
|
}));
|
|
53
56
|
}
|
|
54
|
-
const
|
|
57
|
+
const txType = yield* deriveTxType({
|
|
58
|
+
chainId: params.chainId,
|
|
59
|
+
userOverrides: params.overrides,
|
|
60
|
+
}).pipe(Effect.provideService(GasService, gasService));
|
|
61
|
+
const feeOverrides = yield* deriveFeeOverrides({
|
|
62
|
+
chainId: params.chainId,
|
|
63
|
+
userOverrides: params.overrides,
|
|
64
|
+
}).pipe(Effect.provideService(GasService, gasService));
|
|
65
|
+
const isLegacy = txType === "legacy";
|
|
55
66
|
return yield* Effect.tryPromise({
|
|
56
67
|
catch: (error) => classifyTransferError(error, params.to),
|
|
57
|
-
try: () =>
|
|
68
|
+
try: () => isLegacy
|
|
58
69
|
? walletClient.sendTransaction({
|
|
59
70
|
account,
|
|
60
71
|
chain: null,
|
|
61
72
|
gas: params.overrides?.gas,
|
|
62
|
-
gasPrice:
|
|
73
|
+
gasPrice: feeOverrides.gasPrice,
|
|
63
74
|
nonce: params.overrides?.nonce,
|
|
64
75
|
to: params.to,
|
|
65
76
|
type: "legacy",
|
|
@@ -69,8 +80,8 @@ export const TransferServiceLive = Layer.effect(TransferService, Effect.gen(func
|
|
|
69
80
|
account,
|
|
70
81
|
chain: null,
|
|
71
82
|
gas: params.overrides?.gas,
|
|
72
|
-
maxFeePerGas:
|
|
73
|
-
maxPriorityFeePerGas:
|
|
83
|
+
maxFeePerGas: feeOverrides.maxFeePerGas,
|
|
84
|
+
maxPriorityFeePerGas: feeOverrides.maxPriorityFeePerGas,
|
|
74
85
|
nonce: params.overrides?.nonce,
|
|
75
86
|
to: params.to,
|
|
76
87
|
type: "eip1559",
|
|
@@ -94,15 +105,23 @@ export const TransferServiceLive = Layer.effect(TransferService, Effect.gen(func
|
|
|
94
105
|
message: "No account connected",
|
|
95
106
|
}));
|
|
96
107
|
}
|
|
97
|
-
const
|
|
108
|
+
const txType = yield* deriveTxType({
|
|
109
|
+
chainId: params.chainId,
|
|
110
|
+
userOverrides: params.overrides,
|
|
111
|
+
}).pipe(Effect.provideService(GasService, gasService));
|
|
112
|
+
const feeOverrides = yield* deriveFeeOverrides({
|
|
113
|
+
chainId: params.chainId,
|
|
114
|
+
userOverrides: params.overrides,
|
|
115
|
+
}).pipe(Effect.provideService(GasService, gasService));
|
|
116
|
+
const isLegacy = txType === "legacy";
|
|
98
117
|
const hash = yield* Effect.tryPromise({
|
|
99
118
|
catch: (error) => classifyTransferError(error, params.to),
|
|
100
|
-
try: () =>
|
|
119
|
+
try: () => isLegacy
|
|
101
120
|
? walletClient.sendTransaction({
|
|
102
121
|
account,
|
|
103
122
|
chain: null,
|
|
104
123
|
gas: params.overrides?.gas,
|
|
105
|
-
gasPrice:
|
|
124
|
+
gasPrice: feeOverrides.gasPrice,
|
|
106
125
|
nonce: params.overrides?.nonce,
|
|
107
126
|
to: params.to,
|
|
108
127
|
type: "legacy",
|
|
@@ -112,8 +131,8 @@ export const TransferServiceLive = Layer.effect(TransferService, Effect.gen(func
|
|
|
112
131
|
account,
|
|
113
132
|
chain: null,
|
|
114
133
|
gas: params.overrides?.gas,
|
|
115
|
-
maxFeePerGas:
|
|
116
|
-
maxPriorityFeePerGas:
|
|
134
|
+
maxFeePerGas: feeOverrides.maxFeePerGas,
|
|
135
|
+
maxPriorityFeePerGas: feeOverrides.maxPriorityFeePerGas,
|
|
117
136
|
nonce: params.overrides?.nonce,
|
|
118
137
|
to: params.to,
|
|
119
138
|
type: "eip1559",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/transfer/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Context, Effect, Layer } from \"effect\";\nimport type { Address, Hash, TransactionReceipt, WalletClient } from \"viem\";\nimport { MIN_TX_GAS } from \"@/src/constants/index.js\";\nimport type { ClientNotFoundError, WrongNetworkError } from \"@/src/core/index.js\";\nimport {\n InsufficientFundsError,\n isInsufficientFunds,\n isUserRejection,\n PublicClientService,\n ReceiptTimeoutError,\n TxFailedError,\n UserRejectedError,\n WalletClientService,\n WalletNotConnectedError,\n} from \"@/src/core/index.js\";\n\nexport type TransferOverrides = {\n readonly gas?: bigint;\n readonly gasPrice?: bigint;\n readonly maxFeePerGas?: bigint;\n readonly maxPriorityFeePerGas?: bigint;\n readonly nonce?: number;\n};\n\nexport type TransferServiceShape = {\n readonly send: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n overrides?: TransferOverrides;\n }) => Effect.Effect<\n Hash,\n | InsufficientFundsError\n | UserRejectedError\n | WalletNotConnectedError\n | WrongNetworkError\n | ClientNotFoundError\n | TxFailedError\n >;\n\n readonly sendAndWait: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n confirmations?: number;\n overrides?: TransferOverrides;\n }) => Effect.Effect<\n TransactionReceipt,\n | InsufficientFundsError\n | UserRejectedError\n | WalletNotConnectedError\n | WrongNetworkError\n | ClientNotFoundError\n | TxFailedError\n | ReceiptTimeoutError\n >;\n\n readonly estimateGas: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n }) => Effect.Effect<bigint, ClientNotFoundError>;\n};\n\nexport class TransferService extends Context.Tag(\"ew3/TransferService\")<\n TransferService,\n TransferServiceShape\n>() {}\n\n/**\n * Classify transfer errors into appropriate error types\n */\nconst classifyTransferError = (\n error: unknown,\n to: Address\n): InsufficientFundsError | UserRejectedError | TxFailedError => {\n if (isUserRejection(error)) {\n return new UserRejectedError({\n message: error instanceof Error ? error.message : \"User rejected the transaction\",\n });\n }\n\n if (isInsufficientFunds(error)) {\n return new InsufficientFundsError({\n available: \"0\",\n message: error instanceof Error ? error.message : \"Insufficient funds for transfer\",\n required: \"0\",\n });\n }\n\n return new TxFailedError({\n cause: error,\n hash: \"0x\",\n message: error instanceof Error ? error.message : `Failed to send transfer to ${to}`,\n });\n};\n\nexport const TransferServiceLive = Layer.effect(\n TransferService,\n Effect.gen(function* () {\n const walletClientService = yield* WalletClientService;\n const publicClientService = yield* PublicClientService;\n\n return TransferService.of({\n estimateGas: Effect.fn(\"TransferService.estimateGas\")(function* (params) {\n const publicClient = yield* publicClientService.get(params.chainId);\n\n // Try to estimate, fallback to standard transfer gas on failure\n return yield* Effect.tryPromise({\n catch: () => MIN_TX_GAS,\n try: () =>\n publicClient.estimateGas({\n to: params.to,\n value: params.value,\n }),\n }).pipe(Effect.catchAll(() => Effect.succeed(MIN_TX_GAS)));\n }),\n\n send: Effect.fn(\"TransferService.send\")(function* (params) {\n const walletClient = yield* walletClientService.get(params.chainId);\n const [account] = yield* Effect.tryPromise({\n catch: () =>\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account found\",\n }),\n try: () => walletClient.getAddresses(),\n });\n\n if (!account) {\n return yield* Effect.fail(\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account connected\",\n })\n );\n }\n\n // Determine if we should use legacy or EIP-1559 transaction type\n const useLegacy = params.overrides?.gasPrice !== undefined;\n\n return yield* Effect.tryPromise({\n catch: (error) => classifyTransferError(error, params.to),\n try: () =>\n useLegacy\n ? (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n gasPrice: params.overrides?.gasPrice,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"legacy\",\n value: params.value,\n })\n : (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n maxFeePerGas: params.overrides?.maxFeePerGas,\n maxPriorityFeePerGas: params.overrides?.maxPriorityFeePerGas,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"eip1559\",\n value: params.value,\n }),\n });\n }),\n\n sendAndWait: Effect.fn(\"TransferService.sendAndWait\")(function* (params) {\n const walletClient = yield* walletClientService.get(params.chainId);\n const publicClient = yield* publicClientService.get(params.chainId);\n const [account] = yield* Effect.tryPromise({\n catch: () =>\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account found\",\n }),\n try: () => walletClient.getAddresses(),\n });\n\n if (!account) {\n return yield* Effect.fail(\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account connected\",\n })\n );\n }\n\n // Determine if we should use legacy or EIP-1559 transaction type\n const useLegacy = params.overrides?.gasPrice !== undefined;\n\n const hash = yield* Effect.tryPromise({\n catch: (error) => classifyTransferError(error, params.to),\n try: () =>\n useLegacy\n ? (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n gasPrice: params.overrides?.gasPrice,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"legacy\",\n value: params.value,\n })\n : (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n maxFeePerGas: params.overrides?.maxFeePerGas,\n maxPriorityFeePerGas: params.overrides?.maxPriorityFeePerGas,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"eip1559\",\n value: params.value,\n }),\n });\n\n return yield* Effect.tryPromise({\n catch: (error) => {\n if (error instanceof Error && error.message.includes(\"timeout\")) {\n return new ReceiptTimeoutError({\n hash,\n message: `Transaction receipt timeout for ${hash}`,\n timeout: 30_000,\n });\n }\n return new TxFailedError({\n cause: error,\n hash,\n message: `Failed to wait for transaction ${hash}`,\n });\n },\n try: () =>\n publicClient.waitForTransactionReceipt({\n confirmations: params.confirmations,\n hash,\n }),\n });\n }),\n });\n })\n);\n"]}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/transfer/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Context, Effect, Layer } from \"effect\";\nimport type { Address, Hash, TransactionReceipt, WalletClient } from \"viem\";\nimport { MIN_TX_GAS } from \"@/src/constants/index.js\";\nimport type { ClientNotFoundError, WrongNetworkError } from \"@/src/core/index.js\";\nimport {\n InsufficientFundsError,\n isInsufficientFunds,\n isUserRejection,\n PublicClientService,\n ReceiptTimeoutError,\n TxFailedError,\n UserRejectedError,\n WalletClientService,\n WalletNotConnectedError,\n} from \"@/src/core/index.js\";\nimport type { GasPriceUnavailableError } from \"@/src/gas/index.js\";\nimport { GasService } from \"@/src/gas/index.js\";\nimport { deriveFeeOverrides, deriveTxType } from \"@/src/tx/index.js\";\nimport type { TxOverrides } from \"@/src/types/index.js\";\n\nexport type TransferOverrides = TxOverrides;\n\nexport type TransferServiceShape = {\n readonly send: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n overrides?: TransferOverrides;\n }) => Effect.Effect<\n Hash,\n | InsufficientFundsError\n | UserRejectedError\n | WalletNotConnectedError\n | WrongNetworkError\n | ClientNotFoundError\n | TxFailedError\n | GasPriceUnavailableError\n >;\n\n readonly sendAndWait: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n confirmations?: number;\n overrides?: TransferOverrides;\n }) => Effect.Effect<\n TransactionReceipt,\n | InsufficientFundsError\n | UserRejectedError\n | WalletNotConnectedError\n | WrongNetworkError\n | ClientNotFoundError\n | TxFailedError\n | ReceiptTimeoutError\n | GasPriceUnavailableError\n >;\n\n readonly estimateGas: (params: {\n chainId: number;\n to: Address;\n value: bigint;\n }) => Effect.Effect<bigint, ClientNotFoundError>;\n};\n\nexport class TransferService extends Context.Tag(\"ew3/TransferService\")<\n TransferService,\n TransferServiceShape\n>() {}\n\n/**\n * Classify transfer errors into appropriate error types\n */\nconst classifyTransferError = (\n error: unknown,\n to: Address\n): InsufficientFundsError | UserRejectedError | TxFailedError => {\n if (isUserRejection(error)) {\n return new UserRejectedError({\n message: error instanceof Error ? error.message : \"User rejected the transaction\",\n });\n }\n\n if (isInsufficientFunds(error)) {\n return new InsufficientFundsError({\n available: \"0\",\n message: error instanceof Error ? error.message : \"Insufficient funds for transfer\",\n required: \"0\",\n });\n }\n\n return new TxFailedError({\n cause: error,\n hash: \"0x\",\n message: error instanceof Error ? error.message : `Failed to send transfer to ${to}`,\n });\n};\n\nexport const TransferServiceLive = Layer.effect(\n TransferService,\n Effect.gen(function* () {\n const walletClientService = yield* WalletClientService;\n const publicClientService = yield* PublicClientService;\n const gasService = yield* GasService;\n\n return TransferService.of({\n estimateGas: Effect.fn(\"TransferService.estimateGas\")(function* (params) {\n const publicClient = yield* publicClientService.get(params.chainId);\n\n // Try to estimate, fallback to standard transfer gas on failure\n return yield* Effect.tryPromise({\n catch: () => MIN_TX_GAS,\n try: () =>\n publicClient.estimateGas({\n to: params.to,\n value: params.value,\n }),\n }).pipe(Effect.catchAll(() => Effect.succeed(MIN_TX_GAS)));\n }),\n\n send: Effect.fn(\"TransferService.send\")(function* (params) {\n const walletClient = yield* walletClientService.get(params.chainId);\n const [account] = yield* Effect.tryPromise({\n catch: () =>\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account found\",\n }),\n try: () => walletClient.getAddresses(),\n });\n\n if (!account) {\n return yield* Effect.fail(\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account connected\",\n })\n );\n }\n\n // Get derived tx type and fees\n const txType = yield* deriveTxType({\n chainId: params.chainId,\n userOverrides: params.overrides,\n }).pipe(Effect.provideService(GasService, gasService));\n\n const feeOverrides = yield* deriveFeeOverrides({\n chainId: params.chainId,\n userOverrides: params.overrides,\n }).pipe(Effect.provideService(GasService, gasService));\n\n const isLegacy = txType === \"legacy\";\n\n return yield* Effect.tryPromise({\n catch: (error) => classifyTransferError(error, params.to),\n try: () =>\n isLegacy\n ? (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n gasPrice: feeOverrides.gasPrice,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"legacy\",\n value: params.value,\n })\n : (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n maxFeePerGas: feeOverrides.maxFeePerGas,\n maxPriorityFeePerGas: feeOverrides.maxPriorityFeePerGas,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"eip1559\",\n value: params.value,\n }),\n });\n }),\n\n sendAndWait: Effect.fn(\"TransferService.sendAndWait\")(function* (params) {\n const walletClient = yield* walletClientService.get(params.chainId);\n const publicClient = yield* publicClientService.get(params.chainId);\n const [account] = yield* Effect.tryPromise({\n catch: () =>\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account found\",\n }),\n try: () => walletClient.getAddresses(),\n });\n\n if (!account) {\n return yield* Effect.fail(\n new WalletNotConnectedError({\n chainId: params.chainId,\n message: \"No account connected\",\n })\n );\n }\n\n // Get derived tx type and fees\n const txType = yield* deriveTxType({\n chainId: params.chainId,\n userOverrides: params.overrides,\n }).pipe(Effect.provideService(GasService, gasService));\n\n const feeOverrides = yield* deriveFeeOverrides({\n chainId: params.chainId,\n userOverrides: params.overrides,\n }).pipe(Effect.provideService(GasService, gasService));\n\n const isLegacy = txType === \"legacy\";\n\n const hash = yield* Effect.tryPromise({\n catch: (error) => classifyTransferError(error, params.to),\n try: () =>\n isLegacy\n ? (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n gasPrice: feeOverrides.gasPrice,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"legacy\",\n value: params.value,\n })\n : (walletClient as WalletClient).sendTransaction({\n account,\n chain: null,\n gas: params.overrides?.gas,\n maxFeePerGas: feeOverrides.maxFeePerGas,\n maxPriorityFeePerGas: feeOverrides.maxPriorityFeePerGas,\n nonce: params.overrides?.nonce,\n to: params.to,\n type: \"eip1559\",\n value: params.value,\n }),\n });\n\n return yield* Effect.tryPromise({\n catch: (error) => {\n if (error instanceof Error && error.message.includes(\"timeout\")) {\n return new ReceiptTimeoutError({\n hash,\n message: `Transaction receipt timeout for ${hash}`,\n timeout: 30_000,\n });\n }\n return new TxFailedError({\n cause: error,\n hash,\n message: `Failed to wait for transaction ${hash}`,\n });\n },\n try: () =>\n publicClient.waitForTransactionReceipt({\n confirmations: params.confirmations,\n hash,\n }),\n });\n }),\n });\n })\n);\n"]}
|
package/dist/tx/fees.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../../src/tx/fees.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiB5C,eAAO,MAAM,YAAY,GAAI,QAAQ;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACzC,KAAG,MAAM,CAAC,MAAM,CACf,WAAW,CAAC,MAAM,CAAC,EACnB,wBAAwB,GAAG,mBAAmB,EAC9C,UAAU,
|
|
1
|
+
{"version":3,"file":"fees.d.ts","sourceRoot":"","sources":["../../src/tx/fees.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiB5C,eAAO,MAAM,YAAY,GAAI,QAAQ;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACzC,KAAG,MAAM,CAAC,MAAM,CACf,WAAW,CAAC,MAAM,CAAC,EACnB,wBAAwB,GAAG,mBAAmB,EAC9C,UAAU,CAsBR,CAAC;AAEL,eAAO,MAAM,kBAAkB,GAAI,QAAQ;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACzC,KAAG,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,wBAAwB,GAAG,mBAAmB,EAAE,UAAU,CAwCtF,CAAC"}
|
package/dist/tx/fees.js
CHANGED
|
@@ -8,6 +8,9 @@ export const deriveTxType = (params) => Effect.gen(function* () {
|
|
|
8
8
|
if (userOverrides?.type) {
|
|
9
9
|
return userOverrides.type;
|
|
10
10
|
}
|
|
11
|
+
if (params.policy?.txType) {
|
|
12
|
+
return params.policy.txType;
|
|
13
|
+
}
|
|
11
14
|
if (userOverrides?.gasPrice !== undefined) {
|
|
12
15
|
return "legacy";
|
|
13
16
|
}
|