@naculus/connect-appkit-core 0.2.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/dist/index.cjs +352 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +325 -0
- package/dist/index.d.ts +325 -0
- package/dist/index.js +301 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Naculus
|
|
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/dist/index.cjs
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
__resetResolverForTests: () => __resetResolverForTests,
|
|
24
|
+
chainNamespace: () => chainNamespace,
|
|
25
|
+
chainNumber: () => chainNumber,
|
|
26
|
+
chainsForNamespace: () => chainsForNamespace,
|
|
27
|
+
createDecimalsCache: () => createDecimalsCache,
|
|
28
|
+
decodeRevertReason: () => decodeRevertReason,
|
|
29
|
+
describeChain: () => describeChain,
|
|
30
|
+
eip155ChainIdToNumber: () => eip155ChainIdToNumber,
|
|
31
|
+
getResolver: () => getResolver,
|
|
32
|
+
initialWeb3State: () => initialWeb3State,
|
|
33
|
+
isEvmChainId: () => isEvmChainId,
|
|
34
|
+
normalizeEip155ChainId: () => normalizeEip155ChainId,
|
|
35
|
+
readDecimals: () => readDecimals,
|
|
36
|
+
resolveChain: () => resolveChain,
|
|
37
|
+
resolveEvmChainId: () => resolveEvmChainId,
|
|
38
|
+
resolveRevertReason: () => resolveRevertReason,
|
|
39
|
+
toChainSwitchError: () => toChainSwitchError,
|
|
40
|
+
toEip155Accounts: () => toEip155Accounts,
|
|
41
|
+
toViemChain: () => toViemChain,
|
|
42
|
+
tokenChainMismatch: () => tokenChainMismatch,
|
|
43
|
+
tokenKey: () => tokenKey,
|
|
44
|
+
web3Reducer: () => web3Reducer,
|
|
45
|
+
withRetry: () => withRetry,
|
|
46
|
+
withTimeout: () => withTimeout,
|
|
47
|
+
writeDecimals: () => writeDecimals
|
|
48
|
+
});
|
|
49
|
+
module.exports = __toCommonJS(src_exports);
|
|
50
|
+
|
|
51
|
+
// src/chain-selection.ts
|
|
52
|
+
var import_connect_core = require("@naculus/connect-core");
|
|
53
|
+
function chainNumber(chain) {
|
|
54
|
+
return (0, import_connect_core.eip155Reference)(chain.caip2);
|
|
55
|
+
}
|
|
56
|
+
function chainNamespace(chain) {
|
|
57
|
+
return (0, import_connect_core.namespaceOf)(chain.caip2);
|
|
58
|
+
}
|
|
59
|
+
function resolveChain(chains, chainId) {
|
|
60
|
+
if (!chainId) return null;
|
|
61
|
+
return chains.find((c) => c.caip2 === chainId) ?? null;
|
|
62
|
+
}
|
|
63
|
+
function chainsForNamespace(chains, chainId) {
|
|
64
|
+
if (!chainId) return chains;
|
|
65
|
+
const namespace = (0, import_connect_core.namespaceOf)(chainId);
|
|
66
|
+
if (!namespace) return chains;
|
|
67
|
+
return chains.filter((c) => chainNamespace(c) === namespace);
|
|
68
|
+
}
|
|
69
|
+
function describeChain(chains, chainId) {
|
|
70
|
+
if (!chainId) return null;
|
|
71
|
+
const namespace = (0, import_connect_core.namespaceOf)(chainId);
|
|
72
|
+
if (!namespace) return null;
|
|
73
|
+
const known = resolveChain(chains, chainId);
|
|
74
|
+
if (known) {
|
|
75
|
+
return { namespace, chainId, name: known.name, selected: true };
|
|
76
|
+
}
|
|
77
|
+
const reference = chainId.slice(namespace.length + 1);
|
|
78
|
+
return {
|
|
79
|
+
namespace,
|
|
80
|
+
chainId,
|
|
81
|
+
name: namespace === "eip155" ? `Chain ${reference}` : reference,
|
|
82
|
+
selected: true
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/viem-chain.ts
|
|
87
|
+
var import_connect_core2 = require("@naculus/connect-core");
|
|
88
|
+
function toViemChain(chain, chainNumber2) {
|
|
89
|
+
if (chainNumber2 === null || !chain.rpcUrl) return null;
|
|
90
|
+
const symbol = chain.token ?? import_connect_core2.CHAINS[chainNumber2]?.nativeCurrency?.symbol ?? "";
|
|
91
|
+
return {
|
|
92
|
+
id: chainNumber2,
|
|
93
|
+
name: chain.name,
|
|
94
|
+
// Every EIP-155 native currency is 18 decimals by protocol, so this is a
|
|
95
|
+
// constant rather than an assumption. ERC-20 decimals are per-token and
|
|
96
|
+
// are never guessed anywhere in this codebase.
|
|
97
|
+
nativeCurrency: { name: symbol, symbol, decimals: 18 },
|
|
98
|
+
rpcUrls: {
|
|
99
|
+
default: { http: [chain.rpcUrl] },
|
|
100
|
+
public: { http: [chain.rpcUrl] }
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/aa-chain.ts
|
|
106
|
+
var EVM_CHAIN_ID = /^eip155:[1-9][0-9]*$/;
|
|
107
|
+
function isEvmChainId(value) {
|
|
108
|
+
return typeof value === "string" && EVM_CHAIN_ID.test(value);
|
|
109
|
+
}
|
|
110
|
+
function resolveEvmChainId(requested, connected) {
|
|
111
|
+
const candidate = requested ?? connected ?? void 0;
|
|
112
|
+
return isEvmChainId(candidate) ? candidate : void 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/token-chain.ts
|
|
116
|
+
var import_connect_core3 = require("@naculus/connect-core");
|
|
117
|
+
function tokenChainMismatch(token, activeChainId) {
|
|
118
|
+
if (typeof token?.chainId !== "number" || !Number.isFinite(token.chainId)) {
|
|
119
|
+
return void 0;
|
|
120
|
+
}
|
|
121
|
+
if (typeof activeChainId !== "number" || !Number.isFinite(activeChainId)) {
|
|
122
|
+
return void 0;
|
|
123
|
+
}
|
|
124
|
+
if (token.chainId === activeChainId) return void 0;
|
|
125
|
+
return new import_connect_core3.WalletError(
|
|
126
|
+
"chain_mismatch",
|
|
127
|
+
`Token ${token.address} is configured for chain ${token.chainId}, but the wallet is on chain ${activeChainId}. Switch chains before continuing \u2014 the same address holds a different contract on each chain.`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/token-decimals.ts
|
|
132
|
+
function tokenKey(token) {
|
|
133
|
+
return `${token.chainId ?? "?"}:${token.address.toLowerCase()}`;
|
|
134
|
+
}
|
|
135
|
+
function createDecimalsCache(token, known) {
|
|
136
|
+
return { key: tokenKey(token), value: known };
|
|
137
|
+
}
|
|
138
|
+
function readDecimals(cache, token, known) {
|
|
139
|
+
const key = tokenKey(token);
|
|
140
|
+
if (cache.key !== key) {
|
|
141
|
+
cache.key = key;
|
|
142
|
+
cache.value = known;
|
|
143
|
+
}
|
|
144
|
+
return cache.value;
|
|
145
|
+
}
|
|
146
|
+
function writeDecimals(cache, token, value) {
|
|
147
|
+
cache.key = tokenKey(token);
|
|
148
|
+
cache.value = value;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/provider-errors.ts
|
|
152
|
+
var import_connect_core4 = require("@naculus/connect-core");
|
|
153
|
+
var USER_REJECTED = 4001;
|
|
154
|
+
var UNRECOGNIZED_CHAIN = 4902;
|
|
155
|
+
function providerCode(error) {
|
|
156
|
+
if (!error || typeof error !== "object") return void 0;
|
|
157
|
+
const code = error.code;
|
|
158
|
+
if (typeof code === "number") return code;
|
|
159
|
+
if (typeof code === "string" && /^-?\d+$/.test(code)) return Number(code);
|
|
160
|
+
const nested = error.data?.originalError;
|
|
161
|
+
return nested ? providerCode(nested) : void 0;
|
|
162
|
+
}
|
|
163
|
+
function toChainSwitchError(error, fallback = "chain_unsupported") {
|
|
164
|
+
if (error instanceof import_connect_core4.WalletError) return error;
|
|
165
|
+
const message = error instanceof Error ? error.message : "Unknown error during chain switch";
|
|
166
|
+
switch (providerCode(error)) {
|
|
167
|
+
case USER_REJECTED:
|
|
168
|
+
return new import_connect_core4.WalletError("chain_switch_rejected", message, error);
|
|
169
|
+
case UNRECOGNIZED_CHAIN:
|
|
170
|
+
return new import_connect_core4.WalletError(
|
|
171
|
+
"chain_unsupported",
|
|
172
|
+
`${message} (the wallet does not have this chain configured)`,
|
|
173
|
+
error
|
|
174
|
+
);
|
|
175
|
+
default:
|
|
176
|
+
return new import_connect_core4.WalletError(fallback, message, error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/revert-reason.ts
|
|
181
|
+
var ERROR_STRING_SELECTOR = "08c379a0";
|
|
182
|
+
var PANIC_SELECTOR = "4e487b71";
|
|
183
|
+
var PANIC_REASONS = {
|
|
184
|
+
1: "assertion failed",
|
|
185
|
+
17: "arithmetic overflow or underflow",
|
|
186
|
+
18: "division or modulo by zero",
|
|
187
|
+
33: "invalid enum value",
|
|
188
|
+
49: "pop() on an empty array",
|
|
189
|
+
50: "array index out of bounds"
|
|
190
|
+
};
|
|
191
|
+
function hexToUtf8(hex) {
|
|
192
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
193
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
194
|
+
bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
195
|
+
}
|
|
196
|
+
return new TextDecoder().decode(bytes);
|
|
197
|
+
}
|
|
198
|
+
function decodeRevertReason(data) {
|
|
199
|
+
if (typeof data !== "string" || data.length === 0) return void 0;
|
|
200
|
+
const clean = data.startsWith("0x") ? data.slice(2) : data;
|
|
201
|
+
if (!/^[0-9a-fA-F]*$/.test(clean)) return void 0;
|
|
202
|
+
if (clean.startsWith(ERROR_STRING_SELECTOR)) {
|
|
203
|
+
if (clean.length < 136) return void 0;
|
|
204
|
+
const declared = Number.parseInt(clean.slice(72, 136), 16);
|
|
205
|
+
if (!Number.isSafeInteger(declared) || declared <= 0) return void 0;
|
|
206
|
+
const available = (clean.length - 136) / 2;
|
|
207
|
+
if (declared > available) return void 0;
|
|
208
|
+
return hexToUtf8(clean.slice(136, 136 + declared * 2));
|
|
209
|
+
}
|
|
210
|
+
if (clean.startsWith(PANIC_SELECTOR)) {
|
|
211
|
+
if (clean.length < 8 + 64) return "Panic";
|
|
212
|
+
const code = Number.parseInt(clean.slice(8, 72), 16);
|
|
213
|
+
if (!Number.isSafeInteger(code)) return "Panic";
|
|
214
|
+
const known = PANIC_REASONS[code];
|
|
215
|
+
const hex = `0x${code.toString(16).padStart(2, "0")}`;
|
|
216
|
+
return known ? `Panic ${hex}: ${known}` : `Panic ${hex}`;
|
|
217
|
+
}
|
|
218
|
+
return void 0;
|
|
219
|
+
}
|
|
220
|
+
function resolveRevertReason(data, fallbackMessage) {
|
|
221
|
+
return decodeRevertReason(data) ?? (fallbackMessage.includes("revert") ? fallbackMessage : "Transaction reverted");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/name-resolver.ts
|
|
225
|
+
var import_connect_core5 = require("@naculus/connect-core");
|
|
226
|
+
var sharedResolver = null;
|
|
227
|
+
function getResolver(config) {
|
|
228
|
+
if (config) return new import_connect_core5.NameResolver(config);
|
|
229
|
+
if (!sharedResolver) sharedResolver = new import_connect_core5.NameResolver();
|
|
230
|
+
return sharedResolver;
|
|
231
|
+
}
|
|
232
|
+
function __resetResolverForTests() {
|
|
233
|
+
sharedResolver = null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/web3-store.ts
|
|
237
|
+
var import_connect_core6 = require("@naculus/connect-core");
|
|
238
|
+
function withTimeout(promise, ms, label = "Operation") {
|
|
239
|
+
let timeoutId;
|
|
240
|
+
const timeout = new Promise((_, reject) => {
|
|
241
|
+
timeoutId = setTimeout(
|
|
242
|
+
() => reject(new Error(`${label} timed out after ${ms}ms`)),
|
|
243
|
+
ms
|
|
244
|
+
);
|
|
245
|
+
});
|
|
246
|
+
return Promise.race([promise, timeout]).finally(() => {
|
|
247
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
async function withRetry(fn, options) {
|
|
251
|
+
let lastError;
|
|
252
|
+
for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
|
|
253
|
+
try {
|
|
254
|
+
return await fn();
|
|
255
|
+
} catch (error) {
|
|
256
|
+
lastError = error;
|
|
257
|
+
if (attempt < options.maxRetries) {
|
|
258
|
+
const delay = options.baseDelay * 2 ** attempt;
|
|
259
|
+
import_connect_core6.logger.warn(
|
|
260
|
+
"appkit/core",
|
|
261
|
+
`Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`
|
|
262
|
+
);
|
|
263
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
throw lastError;
|
|
268
|
+
}
|
|
269
|
+
function normalizeEip155ChainId(value) {
|
|
270
|
+
if (typeof value !== "string") return void 0;
|
|
271
|
+
try {
|
|
272
|
+
if (value.startsWith("eip155:")) {
|
|
273
|
+
const reference = value.slice("eip155:".length);
|
|
274
|
+
if (!/^\d+$/.test(reference)) return void 0;
|
|
275
|
+
return `eip155:${BigInt(reference).toString(10)}`;
|
|
276
|
+
}
|
|
277
|
+
if (/^0x[0-9a-f]+$/i.test(value) || /^\d+$/.test(value)) {
|
|
278
|
+
return `eip155:${BigInt(value).toString(10)}`;
|
|
279
|
+
}
|
|
280
|
+
} catch {
|
|
281
|
+
}
|
|
282
|
+
return void 0;
|
|
283
|
+
}
|
|
284
|
+
function toEip155Accounts(accounts, chainId) {
|
|
285
|
+
const reference = chainId.split(":")[1];
|
|
286
|
+
if (!reference) return [];
|
|
287
|
+
return accounts.filter(
|
|
288
|
+
(account) => typeof account === "string" && account.length > 0
|
|
289
|
+
).map(
|
|
290
|
+
(account) => account.includes(":") ? account.split(":").pop() : account
|
|
291
|
+
).map((account) => `eip155:${reference}:${account}`);
|
|
292
|
+
}
|
|
293
|
+
function eip155ChainIdToNumber(chainId) {
|
|
294
|
+
const match = /^eip155:([1-9][0-9]*)$/.exec(chainId);
|
|
295
|
+
if (!match) return void 0;
|
|
296
|
+
const numeric = Number(match[1]);
|
|
297
|
+
return Number.isSafeInteger(numeric) ? numeric : void 0;
|
|
298
|
+
}
|
|
299
|
+
var initialWeb3State = {
|
|
300
|
+
status: "disconnected",
|
|
301
|
+
session: null,
|
|
302
|
+
accounts: [],
|
|
303
|
+
chainId: null,
|
|
304
|
+
error: null
|
|
305
|
+
};
|
|
306
|
+
function web3Reducer(state, action) {
|
|
307
|
+
switch (action.type) {
|
|
308
|
+
case "SET_STATUS":
|
|
309
|
+
return { ...state, status: action.payload };
|
|
310
|
+
case "SET_SESSION":
|
|
311
|
+
return { ...state, session: action.payload };
|
|
312
|
+
case "SET_ACCOUNTS":
|
|
313
|
+
return { ...state, accounts: action.payload };
|
|
314
|
+
case "SET_CHAIN":
|
|
315
|
+
return { ...state, chainId: action.payload };
|
|
316
|
+
case "SET_ERROR":
|
|
317
|
+
return { ...state, error: action.payload };
|
|
318
|
+
case "RESET":
|
|
319
|
+
return initialWeb3State;
|
|
320
|
+
default:
|
|
321
|
+
return state;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
325
|
+
0 && (module.exports = {
|
|
326
|
+
__resetResolverForTests,
|
|
327
|
+
chainNamespace,
|
|
328
|
+
chainNumber,
|
|
329
|
+
chainsForNamespace,
|
|
330
|
+
createDecimalsCache,
|
|
331
|
+
decodeRevertReason,
|
|
332
|
+
describeChain,
|
|
333
|
+
eip155ChainIdToNumber,
|
|
334
|
+
getResolver,
|
|
335
|
+
initialWeb3State,
|
|
336
|
+
isEvmChainId,
|
|
337
|
+
normalizeEip155ChainId,
|
|
338
|
+
readDecimals,
|
|
339
|
+
resolveChain,
|
|
340
|
+
resolveEvmChainId,
|
|
341
|
+
resolveRevertReason,
|
|
342
|
+
toChainSwitchError,
|
|
343
|
+
toEip155Accounts,
|
|
344
|
+
toViemChain,
|
|
345
|
+
tokenChainMismatch,
|
|
346
|
+
tokenKey,
|
|
347
|
+
web3Reducer,
|
|
348
|
+
withRetry,
|
|
349
|
+
withTimeout,
|
|
350
|
+
writeDecimals
|
|
351
|
+
});
|
|
352
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/chain-selection.ts","../src/viem-chain.ts","../src/aa-chain.ts","../src/token-chain.ts","../src/token-decimals.ts","../src/provider-errors.ts","../src/revert-reason.ts","../src/name-resolver.ts","../src/web3-store.ts"],"sourcesContent":["/**\n * `@naculus/connect-appkit-core` — the half of appkit that is not about React.\n *\n * appkit's shape is \"write the Stencil components once, generate the React and\n * Vue wrappers\", and that works for anything visual. It never covered the\n * logic: the React package carried ~8.5k hand-written lines against Vue's\n * ~280, and only two files in it contain JSX. The rest was logic wearing React\n * clothes, reachable from exactly one framework.\n *\n * Everything exported here imports no framework. A React hook and a Vue\n * composable over it are each about ten lines, and they share every decision\n * that took thought rather than each making it again.\n */\n\nexport * from \"./types\";\n\n// ── Chains ────────────────────────────────────────────────────────\nexport {\n chainNamespace,\n chainNumber,\n chainsForNamespace,\n describeChain,\n resolveChain,\n} from \"./chain-selection\";\n\nexport { toViemChain } from \"./viem-chain\";\nexport type { ViemChainShape } from \"./viem-chain\";\n\n// ── Account abstraction ───────────────────────────────────────────\nexport * from \"./aa-chain\";\n\n// ── Tokens ────────────────────────────────────────────────────────\nexport * from \"./token-chain\";\nexport * from \"./token-decimals\";\n\n// ── Errors ────────────────────────────────────────────────────────\nexport * from \"./provider-errors\";\nexport * from \"./revert-reason\";\n\n// ── Names ─────────────────────────────────────────────────────────\nexport * from \"./name-resolver\";\n\n// ── Connection state machine ──────────────────────────────────────\nexport * from \"./web3-store\";\n","/**\n * Which chains a session can actually switch to, and what the current one is.\n *\n * Framework-neutral, and deliberately built on `parseChainId` from\n * `@naculus/connect-core` rather than on another `startsWith(\"eip155:\")`.\n */\n\nimport { eip155Reference, namespaceOf } from \"@naculus/connect-core\";\nimport type { ChainInfo, WalletChain } from \"./types\";\n\n/**\n * The EIP-155 chain number, or null when this is not an EVM chain.\n *\n * Callers that need a number — a viem client, an ERC-20 read — must handle\n * the null rather than defaulting, because there is no number that means\n * \"Solana\" and any stand-in would address a real EVM chain.\n */\nexport function chainNumber(chain: WalletChain): number | null {\n return eip155Reference(chain.caip2);\n}\n\n/** The namespace a chain belongs to, read from its CAIP-2 id. */\nexport function chainNamespace(chain: WalletChain): string | null {\n return namespaceOf(chain.caip2);\n}\n\n/**\n * The configured chain for a CAIP-2 id, or null.\n *\n * A string comparison now that `WalletChain` is keyed by CAIP-2. It used to\n * pull an integer out of the id and compare that, which no non-EVM chain\n * could ever match.\n */\nexport function resolveChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain | null {\n if (!chainId) return null;\n return chains.find((c) => c.caip2 === chainId) ?? null;\n}\n\n/**\n * The chains worth offering for the session's namespace.\n *\n * This used to return every configured chain regardless of what was\n * connected, so a Solana wallet was offered Ethereum and Polygon in the\n * switcher. Clicking one asked a wallet that has no concept of EIP-155 to\n * switch to chain 137 — an action the interface presented as available and\n * that could never work.\n *\n * With no connected chain, everything is offered: nothing has been ruled out\n * yet, and hiding the list would leave a user unable to pick.\n */\nexport function chainsForNamespace(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain[] {\n if (!chainId) return chains;\n const namespace = namespaceOf(chainId);\n if (!namespace) return chains;\n return chains.filter((c) => chainNamespace(c) === namespace);\n}\n\n/**\n * A description of the connected chain for display.\n *\n * Returns something for every namespace. It used to return null for anything\n * that was not EIP-155, so a connected Solana wallet had no chain to show at\n * all and the interface fell back to \"Unknown Chain\".\n */\nexport function describeChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): ChainInfo | null {\n if (!chainId) return null;\n const namespace = namespaceOf(chainId);\n if (!namespace) return null;\n\n const known = resolveChain(chains, chainId);\n if (known) {\n return { namespace, chainId, name: known.name, selected: true };\n }\n\n // No configured entry. Name it by its CAIP-2 reference rather than\n // inventing one: \"Chain 5\" for a Solana cluster would be a fabrication, and\n // the reference is at least something a user can look up.\n const reference = chainId.slice(namespace.length + 1);\n return {\n namespace,\n chainId,\n name: namespace === \"eip155\" ? `Chain ${reference}` : reference,\n selected: true,\n };\n}\n","/**\n * The viem `Chain` shape for a configured EVM chain.\n *\n * Three hooks each built this inline — `useBalance`, `useTokenBalance` and\n * `useViemClient` — with identical bodies and the same `?? \"ETH\"` in each.\n * Three copies of a fallback is three places for it to be wrong.\n *\n * Returns a plain object rather than importing viem, so this package stays\n * free of a dependency only the React bindings need. The shape satisfies\n * viem's `Chain` structurally.\n */\n\nimport { CHAINS } from \"@naculus/connect-core\";\nimport type { WalletChain } from \"./types\";\n\nexport interface ViemChainShape {\n id: number;\n name: string;\n nativeCurrency: { name: string; symbol: string; decimals: number };\n rpcUrls: {\n default: { http: string[] };\n public: { http: string[] };\n };\n}\n\n/**\n * Build the chain descriptor a viem client needs, or null when this chain is\n * not one viem can talk to.\n *\n * Null for a non-EVM chain rather than a stand-in number: viem speaks to EVM\n * nodes, and any number chosen to fill the gap addresses a real chain that is\n * not the one connected.\n *\n * The native symbol comes from the chain's own `token`, then from the shared\n * chain registry. For an unlisted chain it stays empty rather than claiming\n * the asset is ETH. viem requires a string here; the user-facing symbol comes\n * from `useBalance().symbol`, which stays null when it is unknown.\n */\nexport function toViemChain(\n chain: WalletChain,\n chainNumber: number | null,\n): ViemChainShape | null {\n if (chainNumber === null || !chain.rpcUrl) return null;\n\n const symbol =\n chain.token ?? CHAINS[chainNumber]?.nativeCurrency?.symbol ?? \"\";\n\n return {\n id: chainNumber,\n name: chain.name,\n // Every EIP-155 native currency is 18 decimals by protocol, so this is a\n // constant rather than an assumption. ERC-20 decimals are per-token and\n // are never guessed anywhere in this codebase.\n nativeCurrency: { name: symbol, symbol, decimals: 18 },\n rpcUrls: {\n default: { http: [chain.rpcUrl] },\n public: { http: [chain.rpcUrl] },\n },\n };\n}\n","/**\n * Which EVM chain does an account-abstraction operation belong to?\n *\n * The smart-account hooks each resolved this as\n * `options.chainId ?? connectedChainId ?? \"eip155:1\"`, and each then guarded\n * with `if (connectedChainId && connectedChainId !== target)`. The guard is\n * skipped precisely when the mainnet default is used, so the one branch that\n * assumes a chain is the one branch that never checks it.\n *\n * That branch is reachable: a caller passing its own `signer` needs no\n * session, so `connectedChainId` is legitimately absent. It would then build\n * and sign a UserOperation for chain 1 — with chain 1's EntryPoint — while its\n * configured RPC and bundler point somewhere else. The chain ID is part of the\n * UserOperation hash, so the user approves a commitment to a chain they were\n * never shown.\n *\n * Resolving to undefined instead lets each caller refuse in whatever way suits\n * it. Framework-agnostic on purpose: it must not import React.\n */\n\n/** CAIP-2 for an EVM chain. The reference is a decimal chain ID with no leading zero. */\nconst EVM_CHAIN_ID = /^eip155:[1-9][0-9]*$/;\n\nexport function isEvmChainId(value: string | null | undefined): boolean {\n return typeof value === \"string\" && EVM_CHAIN_ID.test(value);\n}\n\n/**\n * The chain to operate on, or undefined when it cannot be known.\n *\n * An explicitly requested chain wins over the connected one; a malformed value\n * from either source resolves to undefined rather than being replaced by a\n * guess, because the caller asked for something specific and got it wrong.\n */\nexport function resolveEvmChainId(\n requested: string | null | undefined,\n connected: string | null | undefined,\n): string | undefined {\n const candidate = requested ?? connected ?? undefined;\n return isEvmChainId(candidate) ? candidate : undefined;\n}\n","/**\n * Does this token belong to the chain the wallet is pointed at?\n *\n * `TokenConfig.chainId` existed but was only ever read as a display label and\n * a cache key. Nothing compared it to the connected chain, so a hook handed a\n * mainnet token config while the wallet sat on Polygon would read — or\n * approve — whatever contract happens to occupy that address on Polygon.\n * Usually that address holds nothing and the call reverts, which is merely\n * confusing. When it holds a different token, `allowance()` returns a\n * plausible number for the wrong asset, and `approve()` grants a spender\n * rights over something the user never looked at.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/**\n * A mismatch, or undefined when the token is on the active chain — or when\n * there is not enough information to tell.\n *\n * Silence on \"cannot tell\" is deliberate. A token config without a chainId, or\n * a session with no resolved chain, is a gap in what the caller supplied; a\n * guess in either direction would be worse than letting the call proceed and\n * fail on its own terms.\n */\nexport function tokenChainMismatch(\n token: Pick<TokenConfig, \"address\" | \"chainId\">,\n activeChainId: number | undefined,\n): WalletError | undefined {\n if (typeof token?.chainId !== \"number\" || !Number.isFinite(token.chainId)) {\n return undefined;\n }\n if (typeof activeChainId !== \"number\" || !Number.isFinite(activeChainId)) {\n return undefined;\n }\n if (token.chainId === activeChainId) return undefined;\n\n return new WalletError(\n \"chain_mismatch\",\n `Token ${token.address} is configured for chain ${token.chainId}, but the ` +\n `wallet is on chain ${activeChainId}. Switch chains before continuing — ` +\n `the same address holds a different contract on each chain.`,\n );\n}\n","/**\n * Decimals cache keyed by the token it belongs to.\n *\n * The ERC-20 hooks cached decimals in a bare `useRef` seeded from the token\n * prop. `useRef` only takes its initial value on mount, and nothing reset it,\n * so a component that lets the user switch tokens kept the first token's\n * precision: picking USDC (6) and then DAI (18) converted \"100\" with 6\n * decimals and transferred 0.0000000001 DAI. The transaction succeeded, so\n * nothing surfaced the mistake.\n *\n * Keying the cache by the token makes a stale hit impossible without needing\n * an effect to fire first.\n */\n\nexport interface TokenIdentity {\n chainId?: number;\n address: string;\n}\n\nexport interface DecimalsCache {\n key: string;\n value: number | undefined;\n}\n\nexport function tokenKey(token: TokenIdentity): string {\n return `${token.chainId ?? \"?\"}:${token.address.toLowerCase()}`;\n}\n\nexport function createDecimalsCache(\n token: TokenIdentity,\n known?: number,\n): DecimalsCache {\n return { key: tokenKey(token), value: known };\n}\n\n/**\n * Cached decimals for `token`, or undefined when the cache holds another\n * token's value. Resets the cache as a side effect so the next write lands\n * against the right key.\n */\nexport function readDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n known?: number,\n): number | undefined {\n const key = tokenKey(token);\n if (cache.key !== key) {\n cache.key = key;\n cache.value = known;\n }\n return cache.value;\n}\n\nexport function writeDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n value: number,\n): void {\n cache.key = tokenKey(token);\n cache.value = value;\n}\n","/**\n * Normalize an EIP-1193 provider error into a WalletError.\n *\n * Hooks were collapsing every non-WalletError into one code — `useSwitchChain`\n * labelled a user pressing Cancel as `chain_unsupported`, so the UI told them\n * the chain was unavailable when they had simply declined. The codes below are\n * the ones wallets actually send, and they mean different things to a caller:\n * one is retryable by asking again, the other is not retryable at all until\n * the chain is added.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/** EIP-1193: the user rejected the request. */\nconst USER_REJECTED = 4001;\n/** EIP-3326: the wallet does not recognize the chain and must add it first. */\nconst UNRECOGNIZED_CHAIN = 4902;\n\nfunction providerCode(error: unknown): number | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"number\") return code;\n // Some wallets stringify it, and some nest the original under `data`.\n if (typeof code === \"string\" && /^-?\\d+$/.test(code)) return Number(code);\n const nested = (error as { data?: { originalError?: unknown } }).data\n ?.originalError;\n return nested ? providerCode(nested) : undefined;\n}\n\n/**\n * Map a chain-switch failure onto the code that describes it.\n *\n * `fallback` is used when the wallet gave nothing to go on, so the caller\n * still decides what an unexplained failure means in its own context.\n */\nexport function toChainSwitchError(\n error: unknown,\n fallback: WalletErrorCode = \"chain_unsupported\",\n): WalletError {\n if (error instanceof WalletError) return error;\n\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error during chain switch\";\n\n switch (providerCode(error)) {\n case USER_REJECTED:\n return new WalletError(\"chain_switch_rejected\", message, error);\n case UNRECOGNIZED_CHAIN:\n return new WalletError(\n \"chain_unsupported\",\n `${message} (the wallet does not have this chain configured)`,\n error,\n );\n default:\n return new WalletError(fallback, message, error);\n }\n}\n","/**\n * Decode an EVM revert payload into something a user can act on.\n *\n * This text is what a wallet shows when a simulation says a transaction would\n * fail, so it is worth getting right and worth sharing: the logic is pure and\n * every binding needs the same answer.\n *\n * Two things are handled that the inlined version did not. The ABI length\n * word is attacker-controlled, so a payload can declare a longer string than\n * it carries; decoding that produced a run of NUL bytes rather than an honest\n * \"could not decode\". And a Panic was reported as \"Built-in failure\" with the\n * code discarded, which is the one piece of information that distinguishes an\n * overflow from a division by zero.\n */\n\n/** keccak256(\"Error(string)\")[0:4] */\nconst ERROR_STRING_SELECTOR = \"08c379a0\";\n/** keccak256(\"Panic(uint256)\")[0:4] */\nconst PANIC_SELECTOR = \"4e487b71\";\n\n/**\n * Panic codes defined by Solidity. Unlisted codes still surface their raw\n * value rather than being flattened into a generic message.\n */\nconst PANIC_REASONS: Record<number, string> = {\n 0x01: \"assertion failed\",\n 0x11: \"arithmetic overflow or underflow\",\n 0x12: \"division or modulo by zero\",\n 0x21: \"invalid enum value\",\n 0x31: \"pop() on an empty array\",\n 0x32: \"array index out of bounds\",\n};\n\nfunction hexToUtf8(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * @param data Raw revert data from the node, with or without the 0x prefix.\n * @returns The decoded reason, or undefined when the payload is not a shape\n * this understands — callers should fall back to the RPC error text rather\n * than presenting a guess.\n */\nexport function decodeRevertReason(data: unknown): string | undefined {\n if (typeof data !== \"string\" || data.length === 0) return undefined;\n const clean = data.startsWith(\"0x\") ? data.slice(2) : data;\n if (!/^[0-9a-fA-F]*$/.test(clean)) return undefined;\n\n if (clean.startsWith(ERROR_STRING_SELECTOR)) {\n // selector(8) + offset(64) + length(64) + payload\n if (clean.length < 136) return undefined;\n const declared = Number.parseInt(clean.slice(72, 136), 16);\n if (!Number.isSafeInteger(declared) || declared <= 0) return undefined;\n const available = (clean.length - 136) / 2;\n // Refuse a payload that promises more than it carries instead of padding\n // the difference with NULs and calling it a revert reason.\n if (declared > available) return undefined;\n return hexToUtf8(clean.slice(136, 136 + declared * 2));\n }\n\n if (clean.startsWith(PANIC_SELECTOR)) {\n if (clean.length < 8 + 64) return \"Panic\";\n const code = Number.parseInt(clean.slice(8, 72), 16);\n if (!Number.isSafeInteger(code)) return \"Panic\";\n const known = PANIC_REASONS[code];\n const hex = `0x${code.toString(16).padStart(2, \"0\")}`;\n return known ? `Panic ${hex}: ${known}` : `Panic ${hex}`;\n }\n\n return undefined;\n}\n\n/** Decoded reason if available, otherwise the node's own message. */\nexport function resolveRevertReason(\n data: unknown,\n fallbackMessage: string,\n): string {\n return (\n decodeRevertReason(data) ??\n (fallbackMessage.includes(\"revert\")\n ? fallbackMessage\n : \"Transaction reverted\")\n );\n}\n","/**\n * Shared NameResolver instance for the name-resolution hooks.\n *\n * useResolveName and useLookupAddress each carried an identical getResolver\n * with its own module-level singleton, so the two directions of the same\n * lookup ran against separate resolvers and separate caches. One definition,\n * one instance.\n */\nimport { NameResolver } from \"@naculus/connect-core\";\nimport type { NameResolverConfig } from \"@naculus/connect-core\";\n\nlet sharedResolver: NameResolver | null = null;\n\n/**\n * @param config When supplied, returns a dedicated resolver rather than the\n * shared one — a caller asking for specific settings must not be handed an\n * instance configured by someone else.\n */\nexport function getResolver(config?: NameResolverConfig): NameResolver {\n if (config) return new NameResolver(config);\n if (!sharedResolver) sharedResolver = new NameResolver();\n return sharedResolver;\n}\n\n/** Test seam: drop the shared instance. */\nexport function __resetResolverForTests(): void {\n sharedResolver = null;\n}\n","/**\n * Framework-agnostic core of the connect provider.\n *\n * appkit's stated shape is \"write the Stencil components once, generate the\n * React and Vue wrappers\". In practice `react/` carries ~8.5k hand-written\n * lines against `vue/`'s ~280, and only two files in `react/src` contain JSX —\n * the rest is logic wearing React clothes. Web Components also cannot serve\n * React Native or Flutter, so the presentation layer was never going to be the\n * thing worth sharing.\n *\n * This module is the first piece moved out: the state machine and the pure\n * helpers around it, with no React import. Everything here is consumable from\n * Vue, Svelte, or a native binding as-is, and `web3-store.test.ts` asserts the\n * absence of a framework import so the boundary cannot rot back.\n */\nimport { logger } from \"@naculus/connect-core\";\nimport type { ConnectionStatus, Web3State } from \"./types\";\n\n// ── Async helpers ──────────────────────────────────────────────────────\n\nexport function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n label = \"Operation\",\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<T>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(`${label} timed out after ${ms}ms`)),\n ms,\n );\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n });\n}\n\nexport interface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n label?: string;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= options.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (attempt < options.maxRetries) {\n const delay = options.baseDelay * 2 ** attempt;\n logger.warn(\n \"appkit/core\",\n `Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n throw lastError;\n}\n\n// ── CAIP normalisation ─────────────────────────────────────────────────\n\n/** Convert EIP-1193 chainChanged values into the CAIP-2 form used by sessions. */\nexport function normalizeEip155ChainId(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n try {\n if (value.startsWith(\"eip155:\")) {\n const reference = value.slice(\"eip155:\".length);\n if (!/^\\d+$/.test(reference)) return undefined;\n return `eip155:${BigInt(reference).toString(10)}`;\n }\n if (/^0x[0-9a-f]+$/i.test(value) || /^\\d+$/.test(value)) {\n return `eip155:${BigInt(value).toString(10)}`;\n }\n } catch {\n // Ignore malformed wallet events rather than corrupting session state.\n }\n return undefined;\n}\n\nexport function toEip155Accounts(\n accounts: unknown[],\n chainId: string,\n): string[] {\n const reference = chainId.split(\":\")[1];\n if (!reference) return [];\n return accounts\n .filter(\n (account): account is string =>\n typeof account === \"string\" && account.length > 0,\n )\n .map((account) =>\n account.includes(\":\") ? (account.split(\":\").pop() as string) : account,\n )\n .map((account) => `eip155:${reference}:${account}`);\n}\n\n/**\n * Numeric EIP-155 chain id, or undefined for any other namespace.\n *\n * The previous implementation took the last CAIP segment and ran parseInt over\n * it, which stops at the first non-digit: `solana:5eykt4Us…` became 5 — an\n * EVM chain id — so asking for Solana mainnet's token list returned Goerli's,\n * and `xrpl:0` became chain 0. Anchor the whole reference instead.\n */\nexport function eip155ChainIdToNumber(chainId: string): number | undefined {\n const match = /^eip155:([1-9][0-9]*)$/.exec(chainId);\n if (!match) return undefined;\n const numeric = Number(match[1]);\n return Number.isSafeInteger(numeric) ? numeric : undefined;\n}\n\n// ── State machine ──────────────────────────────────────────────────────\n\nexport type Web3Action =\n | { type: \"SET_STATUS\"; payload: ConnectionStatus }\n | { type: \"SET_SESSION\"; payload: Web3State[\"session\"] }\n | { type: \"SET_ACCOUNTS\"; payload: string[] }\n | { type: \"SET_CHAIN\"; payload: string | null }\n | { type: \"SET_ERROR\"; payload: Error | null }\n | { type: \"RESET\" };\n\nexport const initialWeb3State: Web3State = {\n status: \"disconnected\",\n session: null,\n accounts: [],\n chainId: null,\n error: null,\n};\n\nexport function web3Reducer(state: Web3State, action: Web3Action): Web3State {\n switch (action.type) {\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_SESSION\":\n return { ...state, session: action.payload };\n case \"SET_ACCOUNTS\":\n return { ...state, accounts: action.payload };\n case \"SET_CHAIN\":\n return { ...state, chainId: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"RESET\":\n return initialWeb3State;\n default:\n return state;\n }\n}\n"],"mappings":"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","names":["import_connect_core","chainNumber","import_connect_core","import_connect_core","import_connect_core","import_connect_core"]}
|