@trezo/evm 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Holiday
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # @trezo/evm
2
+
3
+ A **high‑performance, type‑safe EVM state orchestration layer** for modern Web3 applications.
4
+
5
+ `@trezo/evm` provides a unified interface for **smart‑contract interactions**, **wallet connections**, and **reactive state management**, while keeping your application logic independent from specific wallet kits.
6
+
7
+ ## Core Architecture
8
+
9
+ `@trezo/evm` is built around a **Factory Pattern** that generates a specialized hook and provider for your specific smart contract.
10
+
11
+ ### Store Layer
12
+
13
+ A lightweight **Zustand-based store** that synchronizes:
14
+
15
+ - Wallet state
16
+ - Provider instances
17
+ - Contract abstractions
18
+
19
+ ### Factory Layer
20
+
21
+ Generates **fully type-safe wrappers** for your contract ABI, ensuring:
22
+
23
+ - Compile‑time safety
24
+ - Autocomplete for contract functions
25
+ - Strict argument validation
26
+
27
+ ### Kit Bridge
28
+
29
+ An abstraction layer that allows switching wallet kits without modifying application logic.
30
+
31
+ Supported kits can include:
32
+
33
+ - ConnectKit
34
+ - Reown (AppKit)
35
+ - Additional kits **coming soon**
36
+
37
+ ### Dynamic Loading
38
+
39
+ Wallet kits and their heavy dependencies are **dynamically imported only when required**, ensuring:
40
+
41
+ - Minimal initial bundle size
42
+ - Faster page loads
43
+ - Better tree‑shaking
44
+
45
+ ## Installation
46
+
47
+ Install using your preferred package manager.
48
+
49
+ ```bash
50
+ pnpm add @trezo/evm
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ ### 1. Unified Configuration
56
+
57
+ Initialize your dApp by defining:
58
+
59
+ - Contract address
60
+ - Contract ABI
61
+ - Supported chains
62
+ - Wallet kit configuration
63
+
64
+ Each wallet kit may require **different configuration fields**.
65
+
66
+ ### Example: ConnectKit
67
+
68
+ ```ts
69
+ "use client"; // Required for Next.js
70
+
71
+ import { create, EvmChains } from "@trezo/evm";
72
+
73
+ const MyContractAbi = [...] as const;
74
+
75
+ export const evmConfig = create({
76
+ address: "0x...",
77
+ abi: MyContractAbi,
78
+ chains: [EvmChains.optimismSepolia],
79
+ kit: {
80
+ name: "connectkit",
81
+ config: {
82
+ projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID,
83
+ metadata: {
84
+ appName: "Trezo Dapp",
85
+ appIcon: "https://...",
86
+ appDescription: "...",
87
+ appUrl: "https://..."
88
+ }
89
+ }
90
+ }
91
+ });
92
+
93
+ export const { Provider, ConnectButton } = evmConfig;
94
+ ```
95
+
96
+ ### Example: Reown (AppKit)
97
+
98
+ ```ts
99
+ export const evmConfig = create({
100
+ address: "0x...",
101
+ abi: MyContractAbi,
102
+ chains: [EvmChains.optimismSepolia],
103
+ kit: {
104
+ name: "reown",
105
+ config: {
106
+ projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID,
107
+ ssr: true,
108
+ metadata: {
109
+ name: "Trezo",
110
+ description: "...",
111
+ url: "https://...",
112
+ icons: ["https://..."],
113
+ },
114
+ },
115
+ },
116
+ });
117
+
118
+ export const { Provider, ConnectButton } = evmConfig;
119
+ ```
120
+
121
+ ### 2. Provider Injection
122
+
123
+ Wrap your application (or a specific route) with the generated `Provider`.
124
+
125
+ This provider handles:
126
+
127
+ - Wallet kit initialization
128
+ - State synchronization
129
+ - Provider injection
130
+
131
+ ```tsx
132
+ import { Provider } from "./evm.config";
133
+
134
+ export default function Layout({ children }) {
135
+ return <Provider>{children}</Provider>;
136
+ }
137
+ ```
138
+
139
+ ### 3. Contract Orchestration (Hooks)
140
+
141
+ The `evmConfig()` hook exposes the reactive interface for interacting with:
142
+
143
+ - Smart contracts
144
+ - Wallet state
145
+ - Web3 provider
146
+
147
+ ```ts
148
+ const { call, wallet, web3Provider } = evmConfig();
149
+ ```
150
+
151
+ ### Wallet State
152
+
153
+ Access wallet connection status and account details.
154
+
155
+ ```ts
156
+ const { isConnected, isConnecting, address, chainId, error } = wallet.account;
157
+ ```
158
+
159
+ The wallet state automatically updates when the user:
160
+
161
+ - Connects a wallet
162
+ - Switches accounts
163
+ - Changes networks
164
+
165
+ ### Web3 Provider Availability
166
+
167
+ Check if the user has an injected wallet provider (MetaMask, Rabby, etc).
168
+
169
+ ```ts
170
+ const { isAvailable, error } = web3Provider;
171
+
172
+ if (!isAvailable) {
173
+ console.log("No wallet installed:", error?.message);
174
+ }
175
+ ```
176
+
177
+ ## Read Operations (Queries)
178
+
179
+ Execute **type-safe contract read operations**.
180
+
181
+ Arguments must match the ABI signature.
182
+
183
+ ```ts
184
+ const result = await call.queryFn("getBalance", [address]);
185
+
186
+ if (result.data) {
187
+ console.log(result.data);
188
+ }
189
+ ```
190
+
191
+ Read operations use:
192
+
193
+ - Configured RPC URL
194
+ - OR the connected wallet provider
195
+
196
+ ### Write Operations (Mutations)
197
+
198
+ Execute **state-changing transactions**.
199
+
200
+ These require a connected wallet.
201
+
202
+ ```ts
203
+ const tx = await call.mutateFn("transfer", [to, amount]);
204
+
205
+ if (tx.data) {
206
+ console.log("Transaction Hash:", tx.data.hash);
207
+ }
208
+ ```
209
+
210
+ The orchestration layer automatically handles:
211
+
212
+ - Signer injection
213
+ - Gas estimation
214
+ - Transaction sending
215
+
216
+ ### Real-time Event Listening
217
+
218
+ Listen to contract events with automatic polling fallback when RPC filters are not supported.
219
+
220
+ ```ts
221
+ useEffect(() => {
222
+ const unwatch = call.listenFn("Transfer", (from, to, value) => {
223
+ console.log(`Transfer detected: ${value} from ${from} to ${to}`);
224
+ });
225
+
226
+ return () => unwatch();
227
+ }, []);
228
+ ```
229
+
230
+ ## 4. Custom ConnectButton (Render Props)
231
+
232
+ The default `ConnectButton` works out-of-the-box, but you can build fully custom UI using **render props**.
233
+
234
+ ```tsx
235
+ import { formatAddress } from "@trezo/evm";
236
+
237
+ <ConnectButton>
238
+ {({ isConnected, ensName, address, open }) => (
239
+ <button onClick={open} className="custom-style">
240
+ {isConnected ? (ensName ?? formatAddress(address)) : "Connect Wallet"}
241
+ </button>
242
+ )}
243
+ </ConnectButton>;
244
+ ```
245
+
246
+ This allows complete control over:
247
+
248
+ - UI design
249
+ - Styling
250
+ - Button behavior
251
+
252
+ while still using the wallet kit's internal logic.
253
+
254
+ ## Design Goals
255
+
256
+ `@trezo/evm` is designed to provide:
257
+
258
+ - Type-safe contract interactions
259
+ - Wallet-kit agnostic architecture
260
+ - Minimal bundle size
261
+ - Composable Web3 state
262
+ - Excellent developer experience
263
+
264
+ ---
@@ -0,0 +1,26 @@
1
+ // src/components/KitBridge.tsx
2
+ import { useEffect } from "react";
3
+ import { useAccount, useWalletClient } from "wagmi";
4
+ import { ethers } from "ethers";
5
+ function KitBridge({
6
+ onConnect,
7
+ onDisconnect
8
+ }) {
9
+ const { address, chainId, isConnected } = useAccount();
10
+ const { data: walletClient } = useWalletClient();
11
+ useEffect(() => {
12
+ if (!isConnected || !address || !chainId || !walletClient) {
13
+ onDisconnect();
14
+ return;
15
+ }
16
+ const provider = new ethers.BrowserProvider(walletClient);
17
+ provider.getSigner().then((signer) => {
18
+ onConnect(address, chainId, signer);
19
+ });
20
+ }, [isConnected, address, chainId, walletClient]);
21
+ return null;
22
+ }
23
+
24
+ export {
25
+ KitBridge
26
+ };
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ import {
3
+ KitBridge
4
+ } from "./chunk-I6Z24RI3.mjs";
5
+
6
+ // src/components/providers/connectkit.provider.tsx
7
+ import { WagmiProvider, createConfig, http } from "wagmi";
8
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
9
+ import {
10
+ ConnectKitProvider,
11
+ getDefaultConfig,
12
+ ConnectKitButton
13
+ } from "connectkit";
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ function createConnectkitProvider(kitConfig, chains, rpcUrl, bridgeProps) {
16
+ const wagmiConfig = createConfig(
17
+ getDefaultConfig({
18
+ chains,
19
+ transports: Object.fromEntries(chains.map((c) => [c.id, http(rpcUrl)])),
20
+ walletConnectProjectId: kitConfig.config.projectId,
21
+ appName: kitConfig.config.metadata.appName,
22
+ appDescription: kitConfig.config.metadata.appDescription,
23
+ appUrl: kitConfig.config.metadata.appUrl,
24
+ appIcon: kitConfig.config.metadata.appIcon
25
+ })
26
+ );
27
+ const queryClient = new QueryClient();
28
+ const Provider = ({ children }) => /* @__PURE__ */ jsx(WagmiProvider, { config: wagmiConfig, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxs(ConnectKitProvider, { children: [
29
+ /* @__PURE__ */ jsx(KitBridge, { ...bridgeProps }),
30
+ children
31
+ ] }) }) });
32
+ const ConnectButton = ({
33
+ children,
34
+ ...props
35
+ }) => {
36
+ if (children) {
37
+ return /* @__PURE__ */ jsx(ConnectKitButton.Custom, { children: ({
38
+ isConnected,
39
+ isConnecting,
40
+ show,
41
+ hide,
42
+ address,
43
+ ensName,
44
+ chain
45
+ }) => children({
46
+ isConnected,
47
+ isConnecting,
48
+ address,
49
+ ensName,
50
+ chain,
51
+ open: show ?? (() => {
52
+ }),
53
+ close: hide ?? (() => {
54
+ })
55
+ }) });
56
+ }
57
+ return /* @__PURE__ */ jsx(ConnectKitButton, { ...props });
58
+ };
59
+ return { Provider, ConnectButton };
60
+ }
61
+ export {
62
+ createConnectkitProvider
63
+ };
@@ -0,0 +1,281 @@
1
+ import { Abi, ExtractAbiFunctionNames, AbiParametersToPrimitiveTypes, ExtractAbiFunction, Address, ExtractAbiEventNames, ExtractAbiEvent } from 'abitype';
2
+ export { Abi, AbiParameterToPrimitiveType, AbiParametersToPrimitiveTypes, ExtractAbiEvent, ExtractAbiEventNames, ExtractAbiFunction, ExtractAbiFunctionNames } from 'abitype';
3
+ import * as Chains from 'viem/chains';
4
+ import { ethers } from 'ethers';
5
+ import React from 'react';
6
+
7
+ type EvmAbiType = Abi;
8
+ type EvmAbiFunctionArgsTuple<TAbi extends Abi, FnName extends ExtractAbiFunctionNames<TAbi>> = AbiParametersToPrimitiveTypes<ExtractAbiFunction<TAbi, FnName>["inputs"]>;
9
+ type EvmAbiFunctionReturn<TAbi extends EvmAbiType, FnName extends ExtractAbiFunctionNames<TAbi>> = ExtractAbiFunction<TAbi, FnName>["outputs"] extends readonly [] ? void : AbiParametersToPrimitiveTypes<ExtractAbiFunction<TAbi, FnName>["outputs"]>[0];
10
+
11
+ type ConnectkitConfig = {
12
+ projectId: string;
13
+ metadata: {
14
+ appName: string;
15
+ appIcon?: string;
16
+ appDescription?: string;
17
+ appUrl?: string;
18
+ };
19
+ };
20
+
21
+ type ReownConfig = {
22
+ projectId: string;
23
+ ssr?: boolean;
24
+ metadata: {
25
+ name: string;
26
+ description: string;
27
+ url: string;
28
+ icons: string[];
29
+ };
30
+ };
31
+
32
+ /**
33
+ * ---------------------------------------------------------------------------
34
+ * ⚠️ AUTO-GENERATED FILE — DO NOT EDIT MANUALLY
35
+ * ---------------------------------------------------------------------------
36
+ *
37
+ * Generated by:
38
+ * scripts/genokit.ts
39
+ *
40
+ * Any manual changes will be overwritten.
41
+ *
42
+ * To update kits:
43
+ * 1. Add/remove files in src/kits/
44
+ * 2. Run:
45
+ * pnpm tsx scripts/genokit.ts
46
+ *
47
+ * ---------------------------------------------------------------------------
48
+ */
49
+
50
+ type EvmKitConfigType = {
51
+ name: "connectkit";
52
+ config: ConnectkitConfig;
53
+ } | {
54
+ name: "reown";
55
+ config: ReownConfig;
56
+ };
57
+
58
+ declare const EvmChains: typeof Chains;
59
+ type EvmAddressType = Address;
60
+ type EvmChainsType = typeof EvmChains;
61
+ type EvmConfigType<TAbi extends EvmAbiType> = {
62
+ abi: TAbi;
63
+ address: EvmAddressType;
64
+ chains: [Chains.Chain, ...Chains.Chain[]];
65
+ rpcUrl?: string;
66
+ kit: EvmKitConfigType;
67
+ };
68
+
69
+ type EvmStoreType<TAbi extends EvmAbiType> = {
70
+ wallet: {
71
+ isConnected: boolean;
72
+ isConnecting: boolean;
73
+ address?: EvmAddressType;
74
+ chainId?: number;
75
+ error?: Error;
76
+ };
77
+ provider: {
78
+ isAvailable: boolean;
79
+ error?: Error;
80
+ };
81
+ _signer?: ethers.Signer;
82
+ _provider?: ethers.Provider;
83
+ _contract?: ethers.Contract;
84
+ _abi?: TAbi;
85
+ };
86
+
87
+ declare function create<TAbi extends EvmAbiType>(config: EvmConfigType<TAbi>): {
88
+ (): {
89
+ call: {
90
+ queryFn: <FnName extends ExtractAbiFunctionNames<TAbi, "view" | "pure">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
91
+ data?: EvmAbiFunctionReturn<TAbi, FnName>;
92
+ error?: Error;
93
+ }>;
94
+ mutateFn: <FnName extends ExtractAbiFunctionNames<TAbi, "nonpayable" | "payable">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
95
+ data?: {
96
+ hash: string;
97
+ };
98
+ error?: Error;
99
+ }>;
100
+ listenFn: <EventName extends ExtractAbiEventNames<TAbi>>(eventName: EventName, listener: (...args: AbiParametersToPrimitiveTypes<ExtractAbiEvent<TAbi, EventName>["inputs"]>) => void) => (() => void);
101
+ };
102
+ web3Provider: {
103
+ isAvailable: boolean;
104
+ error?: Error;
105
+ };
106
+ wallet: {
107
+ account: {
108
+ isConnected: boolean;
109
+ isConnecting: boolean;
110
+ address?: EvmAddressType;
111
+ chainId?: number;
112
+ error?: Error;
113
+ };
114
+ };
115
+ };
116
+ call: {
117
+ queryFn: <FnName extends ExtractAbiFunctionNames<TAbi, "view" | "pure">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
118
+ data?: EvmAbiFunctionReturn<TAbi, FnName>;
119
+ error?: Error;
120
+ }>;
121
+ mutateFn: <FnName extends ExtractAbiFunctionNames<TAbi, "nonpayable" | "payable">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
122
+ data?: {
123
+ hash: string;
124
+ };
125
+ error?: Error;
126
+ }>;
127
+ listenFn: <EventName extends ExtractAbiEventNames<TAbi>>(eventName: EventName, listener: (...args: AbiParametersToPrimitiveTypes<ExtractAbiEvent<TAbi, EventName>["inputs"]>) => void) => (() => void);
128
+ };
129
+ getState: () => EvmStoreType<TAbi>;
130
+ subscribe: (onStoreChange: () => void) => () => void;
131
+ Provider: React.FC<{
132
+ children: React.ReactNode;
133
+ }>;
134
+ ConnectButton: React.FC<{
135
+ label?: string;
136
+ showBalance?: boolean;
137
+ showAvatar?: boolean;
138
+ children?: (props: any) => React.ReactNode;
139
+ }>;
140
+ } & {
141
+ call: {
142
+ queryFn: <FnName extends ExtractAbiFunctionNames<TAbi, "view" | "pure">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
143
+ data?: EvmAbiFunctionReturn<TAbi, FnName>;
144
+ error?: Error;
145
+ }>;
146
+ mutateFn: <FnName extends ExtractAbiFunctionNames<TAbi, "nonpayable" | "payable">>(functionName: FnName, args: EvmAbiFunctionArgsTuple<TAbi, FnName>) => Promise<{
147
+ data?: {
148
+ hash: string;
149
+ };
150
+ error?: Error;
151
+ }>;
152
+ listenFn: <EventName extends ExtractAbiEventNames<TAbi>>(eventName: EventName, listener: (...args: AbiParametersToPrimitiveTypes<ExtractAbiEvent<TAbi, EventName>["inputs"]>) => void) => (() => void);
153
+ };
154
+ getState: () => EvmStoreType<TAbi>;
155
+ subscribe: (onStoreChange: () => void) => () => void;
156
+ Provider: React.FC<{
157
+ children: React.ReactNode;
158
+ }>;
159
+ ConnectButton: React.FC<{
160
+ label?: string;
161
+ showBalance?: boolean;
162
+ showAvatar?: boolean;
163
+ children?: (props: any) => React.ReactNode;
164
+ }>;
165
+ };
166
+
167
+ /**
168
+ * Throws an Error with a specified message.
169
+ *
170
+ * This utility can be used to enforce required parameters or invalid states.
171
+ *
172
+ * @param message - Optional custom error message. Defaults to `"An unexpected error occurred"`.
173
+ *
174
+ * @throws Always throws an `Error` with the provided message.
175
+ *
176
+ * @example
177
+ * throwError("Invalid contract address");
178
+ * // Throws Error: "Invalid contract address"
179
+ *
180
+ * @example
181
+ * throwError();
182
+ * // Throws Error: "An unexpected error occurred"
183
+ */
184
+ declare function throwError(message?: string): never;
185
+ /**
186
+ * mapEthersError
187
+ * ------------------------------------------------------------
188
+ * Converts low-level Ethers.js / RPC / wallet errors into
189
+ * human-readable messages suitable for UI display.
190
+ *
191
+ * Ethereum libraries such as ethers.js emit structured errors
192
+ * that include a `code` property. These codes represent
193
+ * categories such as:
194
+ *
195
+ * - Blockchain execution errors
196
+ * - Wallet interaction errors
197
+ * - RPC/network failures
198
+ * - Argument validation problems
199
+ *
200
+ * This utility normalizes those errors into friendly messages.
201
+ *
202
+ * References:
203
+ * https://docs.ethers.org/v6/api/utils/errors/
204
+ */
205
+ declare const mapEthersError: (error: any) => string;
206
+
207
+ interface PollConfig {
208
+ provider: ethers.Provider;
209
+ contract: ethers.Contract;
210
+ eventName: string;
211
+ intervalMs?: number;
212
+ }
213
+ /**
214
+ * Manually polls for logs when eth_newFilter is unavailable
215
+ */
216
+ declare const createEventPoller: ({ provider, contract, eventName, intervalMs }: PollConfig, listener: (...args: any[]) => void) => () => void;
217
+
218
+ /**
219
+ * Converts a value from Wei to Ether.
220
+ *
221
+ * Uses `ethers.formatEther` to format the smallest Ethereum unit (Wei)
222
+ * into a human-readable Ether value.
223
+ *
224
+ * @param num - The value in Wei.
225
+ *
226
+ * @returns A string representing the value converted to Ether.
227
+ *
228
+ * @example
229
+ * fromWei(1000000000000000000)
230
+ * // "1.0"
231
+ */
232
+ declare const fromWei: (value: bigint | string | number, decimals?: number) => string;
233
+ /**
234
+ * Converts a value from Ether to Wei.
235
+ *
236
+ * Uses `ethers.parseEther` to convert a human-readable Ether value
237
+ * into Wei, the smallest Ethereum unit.
238
+ *
239
+ * @param num - The Ether value to convert.
240
+ *
241
+ * @returns A bigint representing the value in Wei.
242
+ *
243
+ * @example
244
+ * toWei(1)
245
+ * // 1000000000000000000n
246
+ */
247
+ declare const toWei: (value: string, decimals?: number) => bigint;
248
+ /**
249
+ * Formats an Ethereum address into a shortened, human-readable string.
250
+ *
251
+ * Keeps the first 4 characters of the address and a specified number of characters at the end.
252
+ * The middle (or end) can be replaced with a custom separator. Supported separators
253
+ * are `"..."`, `"-"`, `">"`, `"→"`.
254
+ *
255
+ * @param address - The full Ethereum address to format.
256
+ * @param options - Optional formatting options:
257
+ * - `endChars` - Number of characters to keep at the end (default `6`).
258
+ * - `separator` - String to place between start and end. Suggestions: `"..." | "-" | ">" | "→"` (default `"..."`).
259
+ * - `position` - `"middle"` (default) or `"end"`. `"end"` appends the separator after the start characters.
260
+ *
261
+ * @returns The formatted address string.
262
+ *
263
+ * @example
264
+ * formatAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e")
265
+ * // "0x74d3...38f44e"
266
+ *
267
+ * @example
268
+ * formatAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e", { endChars: 4, separator: "→" })
269
+ * // "0x74d3→f44e"
270
+ *
271
+ * @example
272
+ * formatAddress("0x742d35Cc6634C0532925a3b844Bc454e4438f44e", { endChars: 0, separator: "...", position: "end" })
273
+ * // "0x74d3..."
274
+ */
275
+ declare function formatAddress(address: string, options?: {
276
+ endChars?: number;
277
+ separator?: "..." | "-" | ">" | "→";
278
+ position?: "middle" | "end";
279
+ }): string;
280
+
281
+ export { type EvmAbiFunctionArgsTuple, type EvmAbiFunctionReturn, type EvmAbiType, type EvmAddressType, EvmChains, type EvmChainsType, type EvmConfigType, type EvmStoreType, create, createEventPoller, formatAddress, fromWei, mapEthersError, throwError, toWei };