@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/dist/index.js
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/components/KitBridge.tsx
|
|
34
|
+
function KitBridge({
|
|
35
|
+
onConnect,
|
|
36
|
+
onDisconnect
|
|
37
|
+
}) {
|
|
38
|
+
const { address, chainId, isConnected } = (0, import_wagmi.useAccount)();
|
|
39
|
+
const { data: walletClient } = (0, import_wagmi.useWalletClient)();
|
|
40
|
+
(0, import_react.useEffect)(() => {
|
|
41
|
+
if (!isConnected || !address || !chainId || !walletClient) {
|
|
42
|
+
onDisconnect();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const provider = new import_ethers2.ethers.BrowserProvider(walletClient);
|
|
46
|
+
provider.getSigner().then((signer) => {
|
|
47
|
+
onConnect(address, chainId, signer);
|
|
48
|
+
});
|
|
49
|
+
}, [isConnected, address, chainId, walletClient]);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
var import_react, import_wagmi, import_ethers2;
|
|
53
|
+
var init_KitBridge = __esm({
|
|
54
|
+
"src/components/KitBridge.tsx"() {
|
|
55
|
+
"use strict";
|
|
56
|
+
"use client";
|
|
57
|
+
import_react = require("react");
|
|
58
|
+
import_wagmi = require("wagmi");
|
|
59
|
+
import_ethers2 = require("ethers");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// src/components/providers/connectkit.provider.tsx
|
|
64
|
+
var connectkit_provider_exports = {};
|
|
65
|
+
__export(connectkit_provider_exports, {
|
|
66
|
+
createConnectkitProvider: () => createConnectkitProvider
|
|
67
|
+
});
|
|
68
|
+
function createConnectkitProvider(kitConfig, chains, rpcUrl, bridgeProps) {
|
|
69
|
+
const wagmiConfig = (0, import_wagmi2.createConfig)(
|
|
70
|
+
(0, import_connectkit.getDefaultConfig)({
|
|
71
|
+
chains,
|
|
72
|
+
transports: Object.fromEntries(chains.map((c) => [c.id, (0, import_wagmi2.http)(rpcUrl)])),
|
|
73
|
+
walletConnectProjectId: kitConfig.config.projectId,
|
|
74
|
+
appName: kitConfig.config.metadata.appName,
|
|
75
|
+
appDescription: kitConfig.config.metadata.appDescription,
|
|
76
|
+
appUrl: kitConfig.config.metadata.appUrl,
|
|
77
|
+
appIcon: kitConfig.config.metadata.appIcon
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
const queryClient = new import_react_query.QueryClient();
|
|
81
|
+
const Provider = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wagmi2.WagmiProvider, { config: wagmiConfig, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_query.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_connectkit.ConnectKitProvider, { children: [
|
|
82
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(KitBridge, { ...bridgeProps }),
|
|
83
|
+
children
|
|
84
|
+
] }) }) });
|
|
85
|
+
const ConnectButton = ({
|
|
86
|
+
children,
|
|
87
|
+
...props
|
|
88
|
+
}) => {
|
|
89
|
+
if (children) {
|
|
90
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_connectkit.ConnectKitButton.Custom, { children: ({
|
|
91
|
+
isConnected,
|
|
92
|
+
isConnecting,
|
|
93
|
+
show,
|
|
94
|
+
hide,
|
|
95
|
+
address,
|
|
96
|
+
ensName,
|
|
97
|
+
chain
|
|
98
|
+
}) => children({
|
|
99
|
+
isConnected,
|
|
100
|
+
isConnecting,
|
|
101
|
+
address,
|
|
102
|
+
ensName,
|
|
103
|
+
chain,
|
|
104
|
+
open: show ?? (() => {
|
|
105
|
+
}),
|
|
106
|
+
close: hide ?? (() => {
|
|
107
|
+
})
|
|
108
|
+
}) });
|
|
109
|
+
}
|
|
110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_connectkit.ConnectKitButton, { ...props });
|
|
111
|
+
};
|
|
112
|
+
return { Provider, ConnectButton };
|
|
113
|
+
}
|
|
114
|
+
var import_wagmi2, import_react_query, import_connectkit, import_jsx_runtime;
|
|
115
|
+
var init_connectkit_provider = __esm({
|
|
116
|
+
"src/components/providers/connectkit.provider.tsx"() {
|
|
117
|
+
"use strict";
|
|
118
|
+
"use client";
|
|
119
|
+
import_wagmi2 = require("wagmi");
|
|
120
|
+
import_react_query = require("@tanstack/react-query");
|
|
121
|
+
import_connectkit = require("connectkit");
|
|
122
|
+
init_KitBridge();
|
|
123
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// src/components/providers/reown.provider.tsx
|
|
128
|
+
var reown_provider_exports = {};
|
|
129
|
+
__export(reown_provider_exports, {
|
|
130
|
+
createReownProvider: () => createReownProvider
|
|
131
|
+
});
|
|
132
|
+
function createReownProvider(kitConfig, chains, rpcUrl, bridgeProps) {
|
|
133
|
+
const wagmiAdapter = new import_appkit_adapter_wagmi.WagmiAdapter({
|
|
134
|
+
networks: chains,
|
|
135
|
+
projectId: kitConfig.config.projectId,
|
|
136
|
+
ssr: kitConfig.config.ssr
|
|
137
|
+
});
|
|
138
|
+
const metadata = {
|
|
139
|
+
...kitConfig.config.metadata,
|
|
140
|
+
url: typeof window !== "undefined" && window.location.hostname === "localhost" ? window.location.origin : kitConfig.config.metadata.url
|
|
141
|
+
};
|
|
142
|
+
if (typeof window !== "undefined") {
|
|
143
|
+
(0, import_react3.createAppKit)({
|
|
144
|
+
adapters: [wagmiAdapter],
|
|
145
|
+
networks: chains,
|
|
146
|
+
projectId: kitConfig.config.projectId,
|
|
147
|
+
metadata,
|
|
148
|
+
features: {
|
|
149
|
+
analytics: true
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const queryClient = new import_react_query2.QueryClient();
|
|
154
|
+
const Provider = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wagmi3.WagmiProvider, { config: wagmiAdapter.wagmiConfig, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_query2.QueryClientProvider, { client: queryClient, children: [
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(KitBridge, { ...bridgeProps }),
|
|
156
|
+
children
|
|
157
|
+
] }) });
|
|
158
|
+
const ConnectButton = ({
|
|
159
|
+
children,
|
|
160
|
+
...props
|
|
161
|
+
}) => {
|
|
162
|
+
const { open: reownOpen, close } = (0, import_react3.useAppKit)();
|
|
163
|
+
const { address, isConnected, isConnecting, chainId } = (0, import_wagmi4.useAccount)();
|
|
164
|
+
const open = import_react2.default.useCallback(async () => {
|
|
165
|
+
try {
|
|
166
|
+
await reownOpen();
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.error("AppKit open error, retrying...", e);
|
|
169
|
+
}
|
|
170
|
+
}, [reownOpen]);
|
|
171
|
+
if (children) {
|
|
172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: children({
|
|
173
|
+
isConnected,
|
|
174
|
+
isConnecting,
|
|
175
|
+
address,
|
|
176
|
+
ensName: null,
|
|
177
|
+
// AppKit doesn't expose ENS directly in useAccount easily without extra hooks
|
|
178
|
+
chain: chainId ? { id: chainId } : void 0,
|
|
179
|
+
open,
|
|
180
|
+
close
|
|
181
|
+
}) });
|
|
182
|
+
}
|
|
183
|
+
return (
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
186
|
+
"appkit-button",
|
|
187
|
+
{
|
|
188
|
+
label: props.label,
|
|
189
|
+
balance: props.showBalance ? "show" : "hide"
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
return { Provider, ConnectButton };
|
|
195
|
+
}
|
|
196
|
+
var import_react2, import_wagmi3, import_react_query2, import_react3, import_wagmi4, import_appkit_adapter_wagmi, import_jsx_runtime2;
|
|
197
|
+
var init_reown_provider = __esm({
|
|
198
|
+
"src/components/providers/reown.provider.tsx"() {
|
|
199
|
+
"use strict";
|
|
200
|
+
"use client";
|
|
201
|
+
import_react2 = __toESM(require("react"));
|
|
202
|
+
import_wagmi3 = require("wagmi");
|
|
203
|
+
import_react_query2 = require("@tanstack/react-query");
|
|
204
|
+
import_react3 = require("@reown/appkit/react");
|
|
205
|
+
import_wagmi4 = require("wagmi");
|
|
206
|
+
import_appkit_adapter_wagmi = require("@reown/appkit-adapter-wagmi");
|
|
207
|
+
init_KitBridge();
|
|
208
|
+
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// src/index.ts
|
|
213
|
+
var index_exports = {};
|
|
214
|
+
__export(index_exports, {
|
|
215
|
+
EvmChains: () => EvmChains,
|
|
216
|
+
create: () => create,
|
|
217
|
+
createEventPoller: () => createEventPoller,
|
|
218
|
+
formatAddress: () => formatAddress,
|
|
219
|
+
fromWei: () => fromWei,
|
|
220
|
+
mapEthersError: () => mapEthersError,
|
|
221
|
+
throwError: () => throwError,
|
|
222
|
+
toWei: () => toWei
|
|
223
|
+
});
|
|
224
|
+
module.exports = __toCommonJS(index_exports);
|
|
225
|
+
|
|
226
|
+
// src/types/config.ts
|
|
227
|
+
var Chains = __toESM(require("viem/chains"));
|
|
228
|
+
var EvmChains = Chains;
|
|
229
|
+
|
|
230
|
+
// src/factory/create.tsx
|
|
231
|
+
var import_react4 = __toESM(require("react"));
|
|
232
|
+
|
|
233
|
+
// src/store/evm.store.ts
|
|
234
|
+
var import_ethers = require("ethers");
|
|
235
|
+
|
|
236
|
+
// src/store/state.ts
|
|
237
|
+
var getInitialState = () => ({
|
|
238
|
+
wallet: {
|
|
239
|
+
isConnected: false,
|
|
240
|
+
isConnecting: false,
|
|
241
|
+
address: void 0,
|
|
242
|
+
chainId: void 0,
|
|
243
|
+
error: void 0
|
|
244
|
+
},
|
|
245
|
+
provider: {
|
|
246
|
+
isAvailable: typeof window !== "undefined" && !!window.ethereum,
|
|
247
|
+
error: void 0
|
|
248
|
+
},
|
|
249
|
+
_signer: void 0,
|
|
250
|
+
_provider: void 0,
|
|
251
|
+
_contract: void 0,
|
|
252
|
+
_abi: void 0
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// src/utils/events.ts
|
|
256
|
+
var createEventPoller = ({ provider, contract, eventName, intervalMs = 5e3 }, listener) => {
|
|
257
|
+
let lastBlock;
|
|
258
|
+
const poll = async () => {
|
|
259
|
+
try {
|
|
260
|
+
const currentBlock = await provider.getBlockNumber();
|
|
261
|
+
if (!lastBlock) {
|
|
262
|
+
lastBlock = currentBlock;
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (currentBlock > lastBlock) {
|
|
266
|
+
const logs = await provider.getLogs({
|
|
267
|
+
address: await contract.getAddress(),
|
|
268
|
+
fromBlock: lastBlock + 1,
|
|
269
|
+
toBlock: currentBlock,
|
|
270
|
+
topics: [contract.interface.getEvent(eventName).topicHash]
|
|
271
|
+
});
|
|
272
|
+
logs.forEach((log) => {
|
|
273
|
+
const parsed = contract.interface.parseLog(log);
|
|
274
|
+
if (parsed) listener(...parsed.args);
|
|
275
|
+
});
|
|
276
|
+
lastBlock = currentBlock;
|
|
277
|
+
}
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error("Event Polling Error:", err);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const intervalId = setInterval(poll, intervalMs);
|
|
283
|
+
return () => clearInterval(intervalId);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/utils/errors.ts
|
|
287
|
+
function throwError(message) {
|
|
288
|
+
throw new Error(message ?? "An unexpected error occurred");
|
|
289
|
+
}
|
|
290
|
+
var mapEthersError = (error) => {
|
|
291
|
+
if (!error) return "Unknown blockchain error.";
|
|
292
|
+
const message = error.message?.toLowerCase?.() || "";
|
|
293
|
+
if (error.code === "ACTION_REJECTED" || error.code === 4001) {
|
|
294
|
+
return "Transaction was rejected in the wallet.";
|
|
295
|
+
}
|
|
296
|
+
if (error.code === "CANCELLED") {
|
|
297
|
+
return "The blockchain request was cancelled.";
|
|
298
|
+
}
|
|
299
|
+
if (error.code === "CALL_EXCEPTION") {
|
|
300
|
+
return `Smart contract execution reverted${error.reason ? `: ${error.reason}` : "."}`;
|
|
301
|
+
}
|
|
302
|
+
if (error.code === "INSUFFICIENT_FUNDS" || message.includes("insufficient funds")) {
|
|
303
|
+
return "Your wallet does not have enough ETH to pay for gas or value.";
|
|
304
|
+
}
|
|
305
|
+
if (error.code === "NONCE_EXPIRED") {
|
|
306
|
+
return "Transaction nonce is too low. Try resetting your wallet nonce.";
|
|
307
|
+
}
|
|
308
|
+
if (error.code === "REPLACEMENT_UNDERPRICED") {
|
|
309
|
+
return "Replacement transaction gas price is too low.";
|
|
310
|
+
}
|
|
311
|
+
if (error.code === "TRANSACTION_REPLACED") {
|
|
312
|
+
return "The transaction was replaced by another transaction.";
|
|
313
|
+
}
|
|
314
|
+
if (error.code === "NETWORK_ERROR") {
|
|
315
|
+
return "Network connection failed. Check your internet or RPC endpoint.";
|
|
316
|
+
}
|
|
317
|
+
if (error.code === "SERVER_ERROR") {
|
|
318
|
+
return "Blockchain RPC server returned an error.";
|
|
319
|
+
}
|
|
320
|
+
if (error.code === "TIMEOUT") {
|
|
321
|
+
return "Blockchain request timed out. Please try again.";
|
|
322
|
+
}
|
|
323
|
+
if (message.includes("network mismatch")) {
|
|
324
|
+
return "Please switch to the correct blockchain network in your wallet.";
|
|
325
|
+
}
|
|
326
|
+
if (error.code === "INVALID_ARGUMENT") {
|
|
327
|
+
return "Invalid argument passed to a blockchain function.";
|
|
328
|
+
}
|
|
329
|
+
if (error.code === "MISSING_ARGUMENT") {
|
|
330
|
+
return "Missing required argument for blockchain call.";
|
|
331
|
+
}
|
|
332
|
+
if (error.code === "UNEXPECTED_ARGUMENT") {
|
|
333
|
+
return "Unexpected argument passed to blockchain function.";
|
|
334
|
+
}
|
|
335
|
+
if (error.code === "VALUE_MISMATCH") {
|
|
336
|
+
return "Provided values do not match the expected format.";
|
|
337
|
+
}
|
|
338
|
+
if (error.code === "BAD_DATA") {
|
|
339
|
+
return "Received malformed data from the blockchain.";
|
|
340
|
+
}
|
|
341
|
+
if (error.code === "BUFFER_OVERRUN") {
|
|
342
|
+
return "Data buffer overflow occurred while decoding blockchain response.";
|
|
343
|
+
}
|
|
344
|
+
if (error.code === "NUMERIC_FAULT") {
|
|
345
|
+
return "Numeric overflow or underflow occurred.";
|
|
346
|
+
}
|
|
347
|
+
if (error.code === "NOT_IMPLEMENTED") {
|
|
348
|
+
return "This blockchain operation is not implemented.";
|
|
349
|
+
}
|
|
350
|
+
if (error.code === "UNSUPPORTED_OPERATION") {
|
|
351
|
+
return "This operation is not supported by the current provider.";
|
|
352
|
+
}
|
|
353
|
+
if (error.code === "UNCONFIGURED_NAME") {
|
|
354
|
+
return "ENS name is not configured correctly.";
|
|
355
|
+
}
|
|
356
|
+
if (error.code === "OFFCHAIN_FAULT") {
|
|
357
|
+
return "Off-chain data lookup failed.";
|
|
358
|
+
}
|
|
359
|
+
if (error.code === "UNKNOWN_ERROR") {
|
|
360
|
+
return "An unknown blockchain error occurred.";
|
|
361
|
+
}
|
|
362
|
+
return error.reason || error.message || "An unexpected blockchain error occurred.";
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// src/store/evm.store.ts
|
|
366
|
+
function createEvmStore(config) {
|
|
367
|
+
let state = getInitialState();
|
|
368
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
369
|
+
const getState = () => state;
|
|
370
|
+
const subscribe = (onStoreChange) => {
|
|
371
|
+
listeners.add(onStoreChange);
|
|
372
|
+
return () => {
|
|
373
|
+
listeners.delete(onStoreChange);
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
const setState = (partial) => {
|
|
377
|
+
const next = typeof partial === "function" ? partial(state) : { ...state, ...partial };
|
|
378
|
+
if (next !== state) {
|
|
379
|
+
state = next;
|
|
380
|
+
listeners.forEach((listener) => listener());
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
const getProvider = () => {
|
|
384
|
+
if (state._signer) return state._signer.provider;
|
|
385
|
+
if (state._provider) return state._provider;
|
|
386
|
+
if (config.rpcUrl) {
|
|
387
|
+
const provider = config.rpcUrl.startsWith("wss") ? new import_ethers.ethers.WebSocketProvider(config.rpcUrl) : new import_ethers.ethers.JsonRpcProvider(config.rpcUrl);
|
|
388
|
+
setState({ _provider: provider });
|
|
389
|
+
return provider;
|
|
390
|
+
}
|
|
391
|
+
if (typeof window !== "undefined" && window.ethereum) {
|
|
392
|
+
const provider = new import_ethers.ethers.BrowserProvider(window.ethereum);
|
|
393
|
+
setState({ _provider: provider });
|
|
394
|
+
return provider;
|
|
395
|
+
}
|
|
396
|
+
throwError(
|
|
397
|
+
"getProvider: No provider available (no wallet connected, no RPC URL, and no injected provider)"
|
|
398
|
+
);
|
|
399
|
+
};
|
|
400
|
+
const getSigner = () => {
|
|
401
|
+
if (state._signer) return state._signer;
|
|
402
|
+
if (config.rpcUrl) {
|
|
403
|
+
const provider = new import_ethers.ethers.JsonRpcProvider(config.rpcUrl);
|
|
404
|
+
const wallet = import_ethers.ethers.Wallet.createRandom().connect(provider);
|
|
405
|
+
setState({ _signer: wallet });
|
|
406
|
+
return wallet;
|
|
407
|
+
}
|
|
408
|
+
throwError("getSigner: No signer available");
|
|
409
|
+
};
|
|
410
|
+
const getContract = (forWrite = false) => {
|
|
411
|
+
const signerOrProvider = forWrite ? getSigner() : getProvider();
|
|
412
|
+
if (state._contract && state._contract.runner === signerOrProvider) {
|
|
413
|
+
return state._contract;
|
|
414
|
+
}
|
|
415
|
+
const contract = new import_ethers.ethers.Contract(
|
|
416
|
+
config.address,
|
|
417
|
+
config.abi,
|
|
418
|
+
signerOrProvider
|
|
419
|
+
);
|
|
420
|
+
setState({ _contract: contract });
|
|
421
|
+
return contract;
|
|
422
|
+
};
|
|
423
|
+
const queryRegistry = /* @__PURE__ */ new Map();
|
|
424
|
+
const queryFn = async (functionName, args) => {
|
|
425
|
+
const safeArgs = JSON.stringify(
|
|
426
|
+
args,
|
|
427
|
+
(_, value) => typeof value === "bigint" ? value.toString() : value
|
|
428
|
+
);
|
|
429
|
+
const queryKey = `${functionName}:${safeArgs}`;
|
|
430
|
+
const execute = async () => {
|
|
431
|
+
try {
|
|
432
|
+
const contract = getContract(false);
|
|
433
|
+
const result = await contract[functionName](...args);
|
|
434
|
+
return { data: result };
|
|
435
|
+
} catch (error) {
|
|
436
|
+
return { error: new Error(mapEthersError(error)) };
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
queryRegistry.set(queryKey, async () => {
|
|
440
|
+
await execute();
|
|
441
|
+
});
|
|
442
|
+
return execute();
|
|
443
|
+
};
|
|
444
|
+
const invalidate = (functionName) => {
|
|
445
|
+
queryRegistry.forEach((refresh, key) => {
|
|
446
|
+
if (key.startsWith(`${functionName}:`)) {
|
|
447
|
+
refresh();
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
const mutateFn = async (functionName, args) => {
|
|
452
|
+
if (!state.wallet.isConnected)
|
|
453
|
+
return { error: new Error("mutateFn: Wallet not connected") };
|
|
454
|
+
const targetChain = config.chains.find(
|
|
455
|
+
(c) => c.id === state.wallet.chainId
|
|
456
|
+
);
|
|
457
|
+
if (!targetChain) {
|
|
458
|
+
return {
|
|
459
|
+
error: new Error(
|
|
460
|
+
`targetChain: Chain ${state.wallet.chainId} not supported`
|
|
461
|
+
)
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
try {
|
|
465
|
+
const contract = getContract(true);
|
|
466
|
+
const tx = await contract[functionName](...args);
|
|
467
|
+
const receipt = await tx.wait();
|
|
468
|
+
return { data: { hash: tx.hash, receipt } };
|
|
469
|
+
} catch (error) {
|
|
470
|
+
return { error: new Error(mapEthersError(error)) };
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
const listenFn = (eventName, listener) => {
|
|
474
|
+
let contract = getContract(false);
|
|
475
|
+
let cleanupFallback;
|
|
476
|
+
const startListening = async () => {
|
|
477
|
+
try {
|
|
478
|
+
await contract.on(eventName, listener);
|
|
479
|
+
} catch (error) {
|
|
480
|
+
const isRpcRestriction = error.message.includes("eth_newFilter") || error.message.includes("whitelisted");
|
|
481
|
+
if (isRpcRestriction) {
|
|
482
|
+
console.warn(`Polling fallback for event: ${eventName}`);
|
|
483
|
+
cleanupFallback = createEventPoller(
|
|
484
|
+
{
|
|
485
|
+
provider: getProvider(),
|
|
486
|
+
contract,
|
|
487
|
+
eventName
|
|
488
|
+
},
|
|
489
|
+
listener
|
|
490
|
+
);
|
|
491
|
+
} else {
|
|
492
|
+
console.error("Failed to set up event listener:", error);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
startListening();
|
|
497
|
+
return () => {
|
|
498
|
+
contract.off(eventName, listener);
|
|
499
|
+
if (cleanupFallback) cleanupFallback();
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
return {
|
|
503
|
+
getState,
|
|
504
|
+
setState,
|
|
505
|
+
subscribe,
|
|
506
|
+
queryFn,
|
|
507
|
+
invalidate,
|
|
508
|
+
mutateFn,
|
|
509
|
+
listenFn
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// src/factory/create.tsx
|
|
514
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
515
|
+
function create(config) {
|
|
516
|
+
const store = createEvmStore(config);
|
|
517
|
+
let kitPromise = null;
|
|
518
|
+
const getKit = () => {
|
|
519
|
+
if (kitPromise) return kitPromise;
|
|
520
|
+
kitPromise = (async () => {
|
|
521
|
+
const kit = config.kit;
|
|
522
|
+
const bridgeProps = {
|
|
523
|
+
onConnect: (address, chainId, signer) => {
|
|
524
|
+
store.setState({
|
|
525
|
+
wallet: {
|
|
526
|
+
...store.getState().wallet,
|
|
527
|
+
isConnected: true,
|
|
528
|
+
isConnecting: false,
|
|
529
|
+
address,
|
|
530
|
+
chainId
|
|
531
|
+
},
|
|
532
|
+
_signer: signer,
|
|
533
|
+
_provider: signer.provider,
|
|
534
|
+
_contract: void 0
|
|
535
|
+
});
|
|
536
|
+
},
|
|
537
|
+
onDisconnect: () => {
|
|
538
|
+
store.setState({
|
|
539
|
+
wallet: {
|
|
540
|
+
...store.getState().wallet,
|
|
541
|
+
isConnected: false,
|
|
542
|
+
address: void 0,
|
|
543
|
+
chainId: void 0
|
|
544
|
+
},
|
|
545
|
+
_signer: void 0,
|
|
546
|
+
_contract: void 0
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
if (kit.name === "connectkit") {
|
|
551
|
+
const { createConnectkitProvider: createConnectkitProvider2 } = await Promise.resolve().then(() => (init_connectkit_provider(), connectkit_provider_exports));
|
|
552
|
+
return createConnectkitProvider2(
|
|
553
|
+
kit,
|
|
554
|
+
config.chains,
|
|
555
|
+
config.rpcUrl || "",
|
|
556
|
+
bridgeProps
|
|
557
|
+
);
|
|
558
|
+
} else if (kit.name === "reown") {
|
|
559
|
+
const { createReownProvider: createReownProvider2 } = await Promise.resolve().then(() => (init_reown_provider(), reown_provider_exports));
|
|
560
|
+
return createReownProvider2(
|
|
561
|
+
kit,
|
|
562
|
+
config.chains,
|
|
563
|
+
config.rpcUrl || "",
|
|
564
|
+
bridgeProps
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
})();
|
|
568
|
+
return kitPromise;
|
|
569
|
+
};
|
|
570
|
+
const call = {
|
|
571
|
+
// Query (view/pure) – args as tuple
|
|
572
|
+
queryFn: (functionName, args) => {
|
|
573
|
+
return store.queryFn(functionName, [...args]);
|
|
574
|
+
},
|
|
575
|
+
// Mutation (nonpayable/payable) – args as tuple
|
|
576
|
+
mutateFn: (functionName, args) => {
|
|
577
|
+
return store.mutateFn(functionName, [...args]);
|
|
578
|
+
},
|
|
579
|
+
// Event listener – args are spread naturally
|
|
580
|
+
listenFn: (eventName, listener) => {
|
|
581
|
+
return store.listenFn(eventName, listener);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
const Provider = ({ children }) => {
|
|
585
|
+
const [KitProvider, setKitProvider] = import_react4.default.useState(null);
|
|
586
|
+
import_react4.default.useEffect(() => {
|
|
587
|
+
getKit().then((kitInstance) => {
|
|
588
|
+
if (kitInstance) {
|
|
589
|
+
setKitProvider(() => kitInstance.Provider);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
}, []);
|
|
593
|
+
if (config.kit && !KitProvider) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
if (KitProvider) {
|
|
597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KitProvider, { children });
|
|
598
|
+
}
|
|
599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
|
|
600
|
+
};
|
|
601
|
+
const ConnectButton = ({ children, ...props }) => {
|
|
602
|
+
const [KitButton, setKitButton] = import_react4.default.useState(
|
|
603
|
+
null
|
|
604
|
+
);
|
|
605
|
+
import_react4.default.useEffect(() => {
|
|
606
|
+
getKit().then((kitInstance) => {
|
|
607
|
+
if (kitInstance) {
|
|
608
|
+
setKitButton(() => kitInstance.ConnectButton);
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
}, []);
|
|
612
|
+
if (config.kit && !KitButton) return null;
|
|
613
|
+
if (KitButton) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KitButton, { ...props, children });
|
|
614
|
+
return null;
|
|
615
|
+
};
|
|
616
|
+
function useStore() {
|
|
617
|
+
const state = (0, import_react4.useSyncExternalStore)(
|
|
618
|
+
store.subscribe,
|
|
619
|
+
store.getState,
|
|
620
|
+
() => store.getState()
|
|
621
|
+
// SSR Snapshot for Next.js
|
|
622
|
+
);
|
|
623
|
+
return {
|
|
624
|
+
call,
|
|
625
|
+
web3Provider: state.provider,
|
|
626
|
+
wallet: {
|
|
627
|
+
account: state.wallet
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
useStore.call = call;
|
|
632
|
+
useStore.getState = store.getState;
|
|
633
|
+
useStore.subscribe = store.subscribe;
|
|
634
|
+
useStore.Provider = Provider;
|
|
635
|
+
useStore.ConnectButton = ConnectButton;
|
|
636
|
+
return useStore;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// src/utils/formatter.ts
|
|
640
|
+
var import_ethers3 = require("ethers");
|
|
641
|
+
var fromWei = (value, decimals = 18) => import_ethers3.ethers.formatUnits(value.toString(), decimals);
|
|
642
|
+
var toWei = (value, decimals = 18) => import_ethers3.ethers.parseUnits(value, decimals);
|
|
643
|
+
function formatAddress(address, options) {
|
|
644
|
+
if (!address) throwError("formatAddress: address is required");
|
|
645
|
+
const endChars = options?.endChars ?? 6;
|
|
646
|
+
const separator = options?.separator ?? "...";
|
|
647
|
+
const position = options?.position ?? "middle";
|
|
648
|
+
const start = address.slice(0, 4);
|
|
649
|
+
const end = address.slice(-endChars);
|
|
650
|
+
if (position === "end") {
|
|
651
|
+
return `${start}${separator}`;
|
|
652
|
+
}
|
|
653
|
+
return `${start}${separator}${end}`;
|
|
654
|
+
}
|
|
655
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
656
|
+
0 && (module.exports = {
|
|
657
|
+
EvmChains,
|
|
658
|
+
create,
|
|
659
|
+
createEventPoller,
|
|
660
|
+
formatAddress,
|
|
661
|
+
fromWei,
|
|
662
|
+
mapEthersError,
|
|
663
|
+
throwError,
|
|
664
|
+
toWei
|
|
665
|
+
});
|