@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 +21 -0
- package/README.md +264 -0
- package/dist/chunk-I6Z24RI3.mjs +26 -0
- package/dist/connectkit.provider-6R2D3NSB.mjs +63 -0
- package/dist/index.d.mts +281 -0
- package/dist/index.d.ts +281 -0
- package/dist/index.js +665 -0
- package/dist/index.mjs +439 -0
- package/dist/reown.provider-QWD2VLQQ.mjs +80 -0
- package/package.json +47 -0
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
|
+
};
|
package/dist/index.d.mts
ADDED
|
@@ -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 };
|