@dnzn/dxkit-wallet 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/dist/index.cjs +285 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.global.js +279 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +257 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Denizen. // dnzn.wei
|
|
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,285 @@
|
|
|
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 index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createEIP1193Provider: () => createEIP1193Provider,
|
|
24
|
+
createEthereumWallet: () => createEthereumWallet,
|
|
25
|
+
createLocalWalletProvider: () => createLocalWalletProvider,
|
|
26
|
+
createWallet: () => createWallet
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var import_dxkit_settings = require("@dnzn/dxkit-settings");
|
|
30
|
+
function createEIP1193Provider() {
|
|
31
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
32
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
33
|
+
let accountsListener = null;
|
|
34
|
+
let chainListener = null;
|
|
35
|
+
function getEthereumProvider() {
|
|
36
|
+
return window.ethereum;
|
|
37
|
+
}
|
|
38
|
+
function updateState(updates) {
|
|
39
|
+
state = { ...state, ...updates };
|
|
40
|
+
for (const handler of handlers) handler(state);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
id: "eip1193",
|
|
44
|
+
name: "Browser Wallet",
|
|
45
|
+
available() {
|
|
46
|
+
return !!window.ethereum;
|
|
47
|
+
},
|
|
48
|
+
async connect() {
|
|
49
|
+
const provider = getEthereumProvider();
|
|
50
|
+
if (!provider) {
|
|
51
|
+
throw new Error("No wallet detected. Install MetaMask or another EIP-1193 wallet.");
|
|
52
|
+
}
|
|
53
|
+
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
54
|
+
const chainIdHex = await provider.request({ method: "eth_chainId" });
|
|
55
|
+
const chainId = parseInt(chainIdHex, 16);
|
|
56
|
+
updateState({ connected: true, address: accounts[0], chainId, provider });
|
|
57
|
+
accountsListener = (accts) => {
|
|
58
|
+
if (accts.length === 0) {
|
|
59
|
+
updateState({ connected: false, address: null, provider: null });
|
|
60
|
+
} else {
|
|
61
|
+
updateState({ connected: true, address: accts[0] });
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
chainListener = (hex) => {
|
|
65
|
+
updateState({ chainId: parseInt(hex, 16) });
|
|
66
|
+
};
|
|
67
|
+
provider.on?.("accountsChanged", accountsListener);
|
|
68
|
+
provider.on?.("chainChanged", chainListener);
|
|
69
|
+
return state;
|
|
70
|
+
},
|
|
71
|
+
async disconnect() {
|
|
72
|
+
const provider = getEthereumProvider();
|
|
73
|
+
if (accountsListener) provider?.removeListener?.("accountsChanged", accountsListener);
|
|
74
|
+
if (chainListener) provider?.removeListener?.("chainChanged", chainListener);
|
|
75
|
+
accountsListener = null;
|
|
76
|
+
chainListener = null;
|
|
77
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
78
|
+
},
|
|
79
|
+
async sign(message) {
|
|
80
|
+
const provider = getEthereumProvider();
|
|
81
|
+
if (!provider || !state.address) throw new Error("Wallet not connected");
|
|
82
|
+
return provider.request({ method: "personal_sign", params: [message, state.address] });
|
|
83
|
+
},
|
|
84
|
+
onStateChange(handler) {
|
|
85
|
+
handlers.add(handler);
|
|
86
|
+
return () => handlers.delete(handler);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function createLocalWalletProvider(options) {
|
|
91
|
+
const address = options?.address ?? "0x0000000000000000000000000000000001";
|
|
92
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
93
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
94
|
+
function updateState(updates) {
|
|
95
|
+
state = { ...state, ...updates };
|
|
96
|
+
for (const handler of handlers) handler(state);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
id: "local",
|
|
100
|
+
name: "Local (Dev)",
|
|
101
|
+
available() {
|
|
102
|
+
return true;
|
|
103
|
+
},
|
|
104
|
+
async connect() {
|
|
105
|
+
updateState({ connected: true, address, chainId: 0, provider: null });
|
|
106
|
+
return state;
|
|
107
|
+
},
|
|
108
|
+
async disconnect() {
|
|
109
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
110
|
+
},
|
|
111
|
+
async sign(message) {
|
|
112
|
+
if (!state.connected) throw new Error("Wallet not connected");
|
|
113
|
+
const bytes = new TextEncoder().encode(message);
|
|
114
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
115
|
+
return `0x${hex}`;
|
|
116
|
+
},
|
|
117
|
+
onStateChange(handler) {
|
|
118
|
+
handlers.add(handler);
|
|
119
|
+
return () => handlers.delete(handler);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
var STORAGE_KEY = "dxkit:wallet";
|
|
124
|
+
function createWallet(options) {
|
|
125
|
+
const providers = options.providers;
|
|
126
|
+
let activeProvider = null;
|
|
127
|
+
let activeUnsub = null;
|
|
128
|
+
let dx = null;
|
|
129
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
130
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
131
|
+
function persistProvider(providerId) {
|
|
132
|
+
try {
|
|
133
|
+
if (providerId) {
|
|
134
|
+
localStorage.setItem(STORAGE_KEY, providerId);
|
|
135
|
+
} else {
|
|
136
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function getPersistedProvider() {
|
|
142
|
+
try {
|
|
143
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function updateState(newState) {
|
|
149
|
+
const wasConnected = state.connected;
|
|
150
|
+
state = { ...newState };
|
|
151
|
+
for (const handler of handlers) handler(state);
|
|
152
|
+
if (!dx) return;
|
|
153
|
+
if (newState.connected && !wasConnected) {
|
|
154
|
+
dx.events.emit("dx:plugin:wallet:connected", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
155
|
+
} else if (!newState.connected && wasConnected) {
|
|
156
|
+
dx.events.emit("dx:plugin:wallet:disconnected", {});
|
|
157
|
+
} else if (newState.connected && wasConnected) {
|
|
158
|
+
dx.events.emit("dx:plugin:wallet:changed", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function getSetting(key, fallback) {
|
|
162
|
+
try {
|
|
163
|
+
const settings = dx?.settings;
|
|
164
|
+
if (settings) return settings.get("wallet", key) ?? fallback;
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
return fallback;
|
|
168
|
+
}
|
|
169
|
+
const plugin = {
|
|
170
|
+
name: "wallet",
|
|
171
|
+
settings: [
|
|
172
|
+
{
|
|
173
|
+
key: "revokeOnDisconnect",
|
|
174
|
+
label: "Revoke on Disconnect",
|
|
175
|
+
type: "boolean",
|
|
176
|
+
default: true,
|
|
177
|
+
description: "Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval."
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
async init(context) {
|
|
181
|
+
dx = context;
|
|
182
|
+
context.eventRegistry.registerEvent("wallet", [
|
|
183
|
+
{ name: "dx:plugin:wallet:connected" },
|
|
184
|
+
{ name: "dx:plugin:wallet:disconnected" },
|
|
185
|
+
{ name: "dx:plugin:wallet:changed" }
|
|
186
|
+
]);
|
|
187
|
+
const savedId = getPersistedProvider();
|
|
188
|
+
if (savedId) {
|
|
189
|
+
const provider = providers.find((p) => p.id === savedId);
|
|
190
|
+
if (provider?.available()) {
|
|
191
|
+
try {
|
|
192
|
+
await plugin.connect(savedId);
|
|
193
|
+
} catch {
|
|
194
|
+
persistProvider(null);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
async destroy() {
|
|
200
|
+
if (activeUnsub) activeUnsub();
|
|
201
|
+
activeUnsub = null;
|
|
202
|
+
if (activeProvider) {
|
|
203
|
+
await activeProvider.disconnect();
|
|
204
|
+
}
|
|
205
|
+
activeProvider = null;
|
|
206
|
+
handlers.clear();
|
|
207
|
+
dx = null;
|
|
208
|
+
},
|
|
209
|
+
async connect(providerId) {
|
|
210
|
+
if (activeProvider) {
|
|
211
|
+
if (activeUnsub) activeUnsub();
|
|
212
|
+
activeUnsub = null;
|
|
213
|
+
await activeProvider.disconnect();
|
|
214
|
+
}
|
|
215
|
+
let provider;
|
|
216
|
+
if (providerId) {
|
|
217
|
+
provider = providers.find((p) => p.id === providerId);
|
|
218
|
+
if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);
|
|
219
|
+
if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);
|
|
220
|
+
} else {
|
|
221
|
+
provider = providers.find((p) => p.available());
|
|
222
|
+
if (!provider) throw new Error("No wallet provider available");
|
|
223
|
+
}
|
|
224
|
+
activeProvider = provider;
|
|
225
|
+
activeUnsub = provider.onStateChange((providerState) => {
|
|
226
|
+
updateState(providerState);
|
|
227
|
+
});
|
|
228
|
+
await provider.connect();
|
|
229
|
+
persistProvider(provider.id);
|
|
230
|
+
return state;
|
|
231
|
+
},
|
|
232
|
+
async disconnect() {
|
|
233
|
+
const shouldRevoke = getSetting("revokeOnDisconnect", true);
|
|
234
|
+
if (shouldRevoke && activeProvider?.id === "eip1193") {
|
|
235
|
+
try {
|
|
236
|
+
const eth = window.ethereum;
|
|
237
|
+
if (eth) {
|
|
238
|
+
await eth.request({
|
|
239
|
+
method: "wallet_revokePermissions",
|
|
240
|
+
params: [{ eth_accounts: {} }]
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (activeUnsub) activeUnsub();
|
|
247
|
+
activeUnsub = null;
|
|
248
|
+
if (activeProvider) {
|
|
249
|
+
await activeProvider.disconnect();
|
|
250
|
+
}
|
|
251
|
+
activeProvider = null;
|
|
252
|
+
persistProvider(null);
|
|
253
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
254
|
+
},
|
|
255
|
+
getState() {
|
|
256
|
+
return { ...state };
|
|
257
|
+
},
|
|
258
|
+
async sign(message) {
|
|
259
|
+
if (!activeProvider || !state.connected) throw new Error("Wallet not connected");
|
|
260
|
+
return activeProvider.sign(message);
|
|
261
|
+
},
|
|
262
|
+
onStateChange(handler) {
|
|
263
|
+
handlers.add(handler);
|
|
264
|
+
return () => handlers.delete(handler);
|
|
265
|
+
},
|
|
266
|
+
getProviders() {
|
|
267
|
+
return [...providers];
|
|
268
|
+
},
|
|
269
|
+
getActiveProvider() {
|
|
270
|
+
return activeProvider;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
return plugin;
|
|
274
|
+
}
|
|
275
|
+
function createEthereumWallet() {
|
|
276
|
+
return createWallet({ providers: [createEIP1193Provider()] });
|
|
277
|
+
}
|
|
278
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
279
|
+
0 && (module.exports = {
|
|
280
|
+
createEIP1193Provider,
|
|
281
|
+
createEthereumWallet,
|
|
282
|
+
createLocalWalletProvider,
|
|
283
|
+
createWallet
|
|
284
|
+
});
|
|
285
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Context, SettingDefinition, Wallet, WalletProvider, WalletState } from '@dnzn/dxkit';\nimport '@dnzn/dxkit-settings';\n\ndeclare module '@dnzn/dxkit' {\n interface EventMap {\n 'dx:plugin:wallet:connected': { address: string; chainId: number };\n 'dx:plugin:wallet:disconnected': Record<string, never>;\n 'dx:plugin:wallet:changed': { address: string; chainId: number };\n }\n}\n\n// ---------------------------------------------------------------------------\n// EIP-1193 Provider — works with MetaMask, Brave, Coinbase, any injected wallet\n// ---------------------------------------------------------------------------\n\n/** Creates a wallet provider using the browser's injected EIP-1193 provider (window.ethereum). */\nexport function createEIP1193Provider(): WalletProvider {\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n let accountsListener: ((accounts: string[]) => void) | null = null;\n let chainListener: ((chainIdHex: string) => void) | null = null;\n\n function getEthereumProvider(): any {\n return (window as any).ethereum;\n }\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'eip1193',\n name: 'Browser Wallet',\n\n available(): boolean {\n return !!(window as any).ethereum;\n },\n\n async connect(): Promise<WalletState> {\n const provider = getEthereumProvider();\n if (!provider) {\n throw new Error('No wallet detected. Install MetaMask or another EIP-1193 wallet.');\n }\n\n const accounts: string[] = await provider.request({ method: 'eth_requestAccounts' });\n const chainIdHex: string = await provider.request({ method: 'eth_chainId' });\n const chainId = parseInt(chainIdHex, 16);\n\n updateState({ connected: true, address: accounts[0], chainId, provider });\n\n // MetaMask/injected wallets fire these when user switches account or chain externally\n accountsListener = (accts: string[]) => {\n if (accts.length === 0) {\n updateState({ connected: false, address: null, provider: null });\n } else {\n updateState({ connected: true, address: accts[0] });\n }\n };\n chainListener = (hex: string) => {\n updateState({ chainId: parseInt(hex, 16) });\n };\n provider.on?.('accountsChanged', accountsListener);\n provider.on?.('chainChanged', chainListener);\n\n return state;\n },\n\n async disconnect(): Promise<void> {\n const provider = getEthereumProvider();\n if (accountsListener) provider?.removeListener?.('accountsChanged', accountsListener);\n if (chainListener) provider?.removeListener?.('chainChanged', chainListener);\n accountsListener = null;\n chainListener = null;\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n const provider = getEthereumProvider();\n if (!provider || !state.address) throw new Error('Wallet not connected');\n return provider.request({ method: 'personal_sign', params: [message, state.address] });\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Local Wallet Provider — dev/ephemeral, instant connect, no external deps\n// ---------------------------------------------------------------------------\n\nexport interface LocalWalletProviderOptions {\n /** Override the deterministic address. Default: '0x0000000000000000000000000000000001' */\n address?: string;\n}\n\n/** Creates a local dev wallet provider. Instant connect, deterministic address. */\nexport function createLocalWalletProvider(options?: LocalWalletProviderOptions): WalletProvider {\n const address = options?.address ?? '0x0000000000000000000000000000000001';\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'local',\n name: 'Local (Dev)',\n\n available(): boolean {\n return true;\n },\n\n async connect(): Promise<WalletState> {\n updateState({ connected: true, address, chainId: 0, provider: null });\n return state;\n },\n\n async disconnect(): Promise<void> {\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n if (!state.connected) throw new Error('Wallet not connected');\n // Deterministic signature for dev: hex-encode the message\n const bytes = new TextEncoder().encode(message);\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `0x${hex}`;\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wallet Coordinator — the Context plugin that manages providers\n// ---------------------------------------------------------------------------\n\nexport interface WalletOptions {\n /** Available wallet providers. First available is used by default. */\n providers: WalletProvider[];\n}\n\nconst STORAGE_KEY = 'dxkit:wallet';\n\n/** Creates the wallet Context plugin — a coordinator that delegates to pluggable providers. */\nexport function createWallet(options: WalletOptions): Wallet {\n const providers = options.providers;\n let activeProvider: WalletProvider | null = null;\n let activeUnsub: (() => void) | null = null;\n let dx: Context | null = null;\n\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function persistProvider(providerId: string | null): void {\n try {\n if (providerId) {\n localStorage.setItem(STORAGE_KEY, providerId);\n } else {\n localStorage.removeItem(STORAGE_KEY);\n }\n } catch {\n /* localStorage unavailable */\n }\n }\n\n function getPersistedProvider(): string | null {\n try {\n return localStorage.getItem(STORAGE_KEY);\n } catch {\n return null;\n }\n }\n\n function updateState(newState: WalletState): void {\n const wasConnected = state.connected;\n state = { ...newState };\n for (const handler of handlers) handler(state);\n\n if (!dx) return;\n if (newState.connected && !wasConnected) {\n dx.events.emit('dx:plugin:wallet:connected', { address: newState.address!, chainId: newState.chainId ?? 0 });\n } else if (!newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:disconnected', {});\n } else if (newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:changed', { address: newState.address!, chainId: newState.chainId ?? 0 });\n }\n }\n\n function getSetting(key: string, fallback: any): any {\n try {\n const settings = (dx as any)?.settings;\n if (settings) return settings.get('wallet', key) ?? fallback;\n } catch {\n /* settings plugin not available */\n }\n return fallback;\n }\n\n const plugin: Wallet = {\n name: 'wallet',\n\n settings: [\n {\n key: 'revokeOnDisconnect',\n label: 'Revoke on Disconnect',\n type: 'boolean',\n default: true,\n description:\n 'Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval.',\n },\n ] satisfies SettingDefinition[],\n\n async init(context: Context): Promise<void> {\n dx = context;\n\n context.eventRegistry.registerEvent('wallet', [\n { name: 'dx:plugin:wallet:connected' },\n { name: 'dx:plugin:wallet:disconnected' },\n { name: 'dx:plugin:wallet:changed' },\n ]);\n\n // Restore previous wallet connection\n const savedId = getPersistedProvider();\n if (savedId) {\n const provider = providers.find((p) => p.id === savedId);\n if (provider?.available()) {\n try {\n await plugin.connect(savedId);\n } catch {\n // Provider no longer available — clear persisted state\n persistProvider(null);\n }\n }\n }\n },\n\n async destroy(): Promise<void> {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n handlers.clear();\n dx = null;\n },\n\n async connect(providerId?: string): Promise<WalletState> {\n // Unsub before disconnect to avoid double-firing state change handlers\n if (activeProvider) {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n await activeProvider.disconnect();\n }\n\n // Select provider\n let provider: WalletProvider | undefined;\n if (providerId) {\n provider = providers.find((p) => p.id === providerId);\n if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);\n if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);\n } else {\n provider = providers.find((p) => p.available());\n if (!provider) throw new Error('No wallet provider available');\n }\n\n activeProvider = provider;\n\n // Subscribe before connect — provider.connect() triggers this, so no explicit updateState needed\n activeUnsub = provider.onStateChange((providerState: WalletState) => {\n updateState(providerState);\n });\n\n await provider.connect();\n persistProvider(provider.id);\n return state;\n },\n\n async disconnect(): Promise<void> {\n // EIP-1193 only: revoke permissions so reconnect requires explicit approval\n const shouldRevoke = getSetting('revokeOnDisconnect', true);\n if (shouldRevoke && activeProvider?.id === 'eip1193') {\n try {\n const eth = (window as any).ethereum;\n if (eth) {\n await eth.request({\n method: 'wallet_revokePermissions',\n params: [{ eth_accounts: {} }],\n });\n }\n } catch {\n /* Not all wallets support wallet_revokePermissions */\n }\n }\n\n // Unsub before disconnect to avoid double-firing state changes\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n persistProvider(null);\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n getState(): WalletState {\n return { ...state };\n },\n\n async sign(message: string): Promise<string> {\n if (!activeProvider || !state.connected) throw new Error('Wallet not connected');\n return activeProvider.sign(message);\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n\n getProviders(): WalletProvider[] {\n return [...providers];\n },\n\n getActiveProvider(): WalletProvider | null {\n return activeProvider;\n },\n };\n\n return plugin;\n}\n\n// ---------------------------------------------------------------------------\n// Backward compat — deprecated, use createWallet({ providers: [...] })\n// ---------------------------------------------------------------------------\n\n/**\n * @deprecated Use `createWallet({ providers: [createEIP1193Provider()] })` instead.\n */\nexport function createEthereumWallet(): Wallet {\n return createWallet({ providers: [createEIP1193Provider()] });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { WalletProvider, Wallet } from '@dnzn/dxkit';
|
|
2
|
+
|
|
3
|
+
declare module '@dnzn/dxkit' {
|
|
4
|
+
interface EventMap {
|
|
5
|
+
'dx:plugin:wallet:connected': {
|
|
6
|
+
address: string;
|
|
7
|
+
chainId: number;
|
|
8
|
+
};
|
|
9
|
+
'dx:plugin:wallet:disconnected': Record<string, never>;
|
|
10
|
+
'dx:plugin:wallet:changed': {
|
|
11
|
+
address: string;
|
|
12
|
+
chainId: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Creates a wallet provider using the browser's injected EIP-1193 provider (window.ethereum). */
|
|
17
|
+
declare function createEIP1193Provider(): WalletProvider;
|
|
18
|
+
interface LocalWalletProviderOptions {
|
|
19
|
+
/** Override the deterministic address. Default: '0x0000000000000000000000000000000001' */
|
|
20
|
+
address?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Creates a local dev wallet provider. Instant connect, deterministic address. */
|
|
23
|
+
declare function createLocalWalletProvider(options?: LocalWalletProviderOptions): WalletProvider;
|
|
24
|
+
interface WalletOptions {
|
|
25
|
+
/** Available wallet providers. First available is used by default. */
|
|
26
|
+
providers: WalletProvider[];
|
|
27
|
+
}
|
|
28
|
+
/** Creates the wallet Context plugin — a coordinator that delegates to pluggable providers. */
|
|
29
|
+
declare function createWallet(options: WalletOptions): Wallet;
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `createWallet({ providers: [createEIP1193Provider()] })` instead.
|
|
32
|
+
*/
|
|
33
|
+
declare function createEthereumWallet(): Wallet;
|
|
34
|
+
|
|
35
|
+
export { type LocalWalletProviderOptions, type WalletOptions, createEIP1193Provider, createEthereumWallet, createLocalWalletProvider, createWallet };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { WalletProvider, Wallet } from '@dnzn/dxkit';
|
|
2
|
+
|
|
3
|
+
declare module '@dnzn/dxkit' {
|
|
4
|
+
interface EventMap {
|
|
5
|
+
'dx:plugin:wallet:connected': {
|
|
6
|
+
address: string;
|
|
7
|
+
chainId: number;
|
|
8
|
+
};
|
|
9
|
+
'dx:plugin:wallet:disconnected': Record<string, never>;
|
|
10
|
+
'dx:plugin:wallet:changed': {
|
|
11
|
+
address: string;
|
|
12
|
+
chainId: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Creates a wallet provider using the browser's injected EIP-1193 provider (window.ethereum). */
|
|
17
|
+
declare function createEIP1193Provider(): WalletProvider;
|
|
18
|
+
interface LocalWalletProviderOptions {
|
|
19
|
+
/** Override the deterministic address. Default: '0x0000000000000000000000000000000001' */
|
|
20
|
+
address?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Creates a local dev wallet provider. Instant connect, deterministic address. */
|
|
23
|
+
declare function createLocalWalletProvider(options?: LocalWalletProviderOptions): WalletProvider;
|
|
24
|
+
interface WalletOptions {
|
|
25
|
+
/** Available wallet providers. First available is used by default. */
|
|
26
|
+
providers: WalletProvider[];
|
|
27
|
+
}
|
|
28
|
+
/** Creates the wallet Context plugin — a coordinator that delegates to pluggable providers. */
|
|
29
|
+
declare function createWallet(options: WalletOptions): Wallet;
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `createWallet({ providers: [createEIP1193Provider()] })` instead.
|
|
32
|
+
*/
|
|
33
|
+
declare function createEthereumWallet(): Wallet;
|
|
34
|
+
|
|
35
|
+
export { type LocalWalletProviderOptions, type WalletOptions, createEIP1193Provider, createEthereumWallet, createLocalWalletProvider, createWallet };
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var DxWallet = (() => {
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
createEIP1193Provider: () => createEIP1193Provider,
|
|
25
|
+
createEthereumWallet: () => createEthereumWallet,
|
|
26
|
+
createLocalWalletProvider: () => createLocalWalletProvider,
|
|
27
|
+
createWallet: () => createWallet
|
|
28
|
+
});
|
|
29
|
+
function createEIP1193Provider() {
|
|
30
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
31
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
32
|
+
let accountsListener = null;
|
|
33
|
+
let chainListener = null;
|
|
34
|
+
function getEthereumProvider() {
|
|
35
|
+
return window.ethereum;
|
|
36
|
+
}
|
|
37
|
+
function updateState(updates) {
|
|
38
|
+
state = { ...state, ...updates };
|
|
39
|
+
for (const handler of handlers) handler(state);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
id: "eip1193",
|
|
43
|
+
name: "Browser Wallet",
|
|
44
|
+
available() {
|
|
45
|
+
return !!window.ethereum;
|
|
46
|
+
},
|
|
47
|
+
async connect() {
|
|
48
|
+
const provider = getEthereumProvider();
|
|
49
|
+
if (!provider) {
|
|
50
|
+
throw new Error("No wallet detected. Install MetaMask or another EIP-1193 wallet.");
|
|
51
|
+
}
|
|
52
|
+
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
53
|
+
const chainIdHex = await provider.request({ method: "eth_chainId" });
|
|
54
|
+
const chainId = parseInt(chainIdHex, 16);
|
|
55
|
+
updateState({ connected: true, address: accounts[0], chainId, provider });
|
|
56
|
+
accountsListener = (accts) => {
|
|
57
|
+
if (accts.length === 0) {
|
|
58
|
+
updateState({ connected: false, address: null, provider: null });
|
|
59
|
+
} else {
|
|
60
|
+
updateState({ connected: true, address: accts[0] });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
chainListener = (hex) => {
|
|
64
|
+
updateState({ chainId: parseInt(hex, 16) });
|
|
65
|
+
};
|
|
66
|
+
provider.on?.("accountsChanged", accountsListener);
|
|
67
|
+
provider.on?.("chainChanged", chainListener);
|
|
68
|
+
return state;
|
|
69
|
+
},
|
|
70
|
+
async disconnect() {
|
|
71
|
+
const provider = getEthereumProvider();
|
|
72
|
+
if (accountsListener) provider?.removeListener?.("accountsChanged", accountsListener);
|
|
73
|
+
if (chainListener) provider?.removeListener?.("chainChanged", chainListener);
|
|
74
|
+
accountsListener = null;
|
|
75
|
+
chainListener = null;
|
|
76
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
77
|
+
},
|
|
78
|
+
async sign(message) {
|
|
79
|
+
const provider = getEthereumProvider();
|
|
80
|
+
if (!provider || !state.address) throw new Error("Wallet not connected");
|
|
81
|
+
return provider.request({ method: "personal_sign", params: [message, state.address] });
|
|
82
|
+
},
|
|
83
|
+
onStateChange(handler) {
|
|
84
|
+
handlers.add(handler);
|
|
85
|
+
return () => handlers.delete(handler);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function createLocalWalletProvider(options) {
|
|
90
|
+
const address = options?.address ?? "0x0000000000000000000000000000000001";
|
|
91
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
92
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
93
|
+
function updateState(updates) {
|
|
94
|
+
state = { ...state, ...updates };
|
|
95
|
+
for (const handler of handlers) handler(state);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
id: "local",
|
|
99
|
+
name: "Local (Dev)",
|
|
100
|
+
available() {
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
async connect() {
|
|
104
|
+
updateState({ connected: true, address, chainId: 0, provider: null });
|
|
105
|
+
return state;
|
|
106
|
+
},
|
|
107
|
+
async disconnect() {
|
|
108
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
109
|
+
},
|
|
110
|
+
async sign(message) {
|
|
111
|
+
if (!state.connected) throw new Error("Wallet not connected");
|
|
112
|
+
const bytes = new TextEncoder().encode(message);
|
|
113
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
114
|
+
return `0x${hex}`;
|
|
115
|
+
},
|
|
116
|
+
onStateChange(handler) {
|
|
117
|
+
handlers.add(handler);
|
|
118
|
+
return () => handlers.delete(handler);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
var STORAGE_KEY = "dxkit:wallet";
|
|
123
|
+
function createWallet(options) {
|
|
124
|
+
const providers = options.providers;
|
|
125
|
+
let activeProvider = null;
|
|
126
|
+
let activeUnsub = null;
|
|
127
|
+
let dx = null;
|
|
128
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
129
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
130
|
+
function persistProvider(providerId) {
|
|
131
|
+
try {
|
|
132
|
+
if (providerId) {
|
|
133
|
+
localStorage.setItem(STORAGE_KEY, providerId);
|
|
134
|
+
} else {
|
|
135
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function getPersistedProvider() {
|
|
141
|
+
try {
|
|
142
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
143
|
+
} catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function updateState(newState) {
|
|
148
|
+
const wasConnected = state.connected;
|
|
149
|
+
state = { ...newState };
|
|
150
|
+
for (const handler of handlers) handler(state);
|
|
151
|
+
if (!dx) return;
|
|
152
|
+
if (newState.connected && !wasConnected) {
|
|
153
|
+
dx.events.emit("dx:plugin:wallet:connected", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
154
|
+
} else if (!newState.connected && wasConnected) {
|
|
155
|
+
dx.events.emit("dx:plugin:wallet:disconnected", {});
|
|
156
|
+
} else if (newState.connected && wasConnected) {
|
|
157
|
+
dx.events.emit("dx:plugin:wallet:changed", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function getSetting(key, fallback) {
|
|
161
|
+
try {
|
|
162
|
+
const settings = dx?.settings;
|
|
163
|
+
if (settings) return settings.get("wallet", key) ?? fallback;
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
166
|
+
return fallback;
|
|
167
|
+
}
|
|
168
|
+
const plugin = {
|
|
169
|
+
name: "wallet",
|
|
170
|
+
settings: [
|
|
171
|
+
{
|
|
172
|
+
key: "revokeOnDisconnect",
|
|
173
|
+
label: "Revoke on Disconnect",
|
|
174
|
+
type: "boolean",
|
|
175
|
+
default: true,
|
|
176
|
+
description: "Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval."
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
async init(context) {
|
|
180
|
+
dx = context;
|
|
181
|
+
context.eventRegistry.registerEvent("wallet", [
|
|
182
|
+
{ name: "dx:plugin:wallet:connected" },
|
|
183
|
+
{ name: "dx:plugin:wallet:disconnected" },
|
|
184
|
+
{ name: "dx:plugin:wallet:changed" }
|
|
185
|
+
]);
|
|
186
|
+
const savedId = getPersistedProvider();
|
|
187
|
+
if (savedId) {
|
|
188
|
+
const provider = providers.find((p) => p.id === savedId);
|
|
189
|
+
if (provider?.available()) {
|
|
190
|
+
try {
|
|
191
|
+
await plugin.connect(savedId);
|
|
192
|
+
} catch {
|
|
193
|
+
persistProvider(null);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
async destroy() {
|
|
199
|
+
if (activeUnsub) activeUnsub();
|
|
200
|
+
activeUnsub = null;
|
|
201
|
+
if (activeProvider) {
|
|
202
|
+
await activeProvider.disconnect();
|
|
203
|
+
}
|
|
204
|
+
activeProvider = null;
|
|
205
|
+
handlers.clear();
|
|
206
|
+
dx = null;
|
|
207
|
+
},
|
|
208
|
+
async connect(providerId) {
|
|
209
|
+
if (activeProvider) {
|
|
210
|
+
if (activeUnsub) activeUnsub();
|
|
211
|
+
activeUnsub = null;
|
|
212
|
+
await activeProvider.disconnect();
|
|
213
|
+
}
|
|
214
|
+
let provider;
|
|
215
|
+
if (providerId) {
|
|
216
|
+
provider = providers.find((p) => p.id === providerId);
|
|
217
|
+
if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);
|
|
218
|
+
if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);
|
|
219
|
+
} else {
|
|
220
|
+
provider = providers.find((p) => p.available());
|
|
221
|
+
if (!provider) throw new Error("No wallet provider available");
|
|
222
|
+
}
|
|
223
|
+
activeProvider = provider;
|
|
224
|
+
activeUnsub = provider.onStateChange((providerState) => {
|
|
225
|
+
updateState(providerState);
|
|
226
|
+
});
|
|
227
|
+
await provider.connect();
|
|
228
|
+
persistProvider(provider.id);
|
|
229
|
+
return state;
|
|
230
|
+
},
|
|
231
|
+
async disconnect() {
|
|
232
|
+
const shouldRevoke = getSetting("revokeOnDisconnect", true);
|
|
233
|
+
if (shouldRevoke && activeProvider?.id === "eip1193") {
|
|
234
|
+
try {
|
|
235
|
+
const eth = window.ethereum;
|
|
236
|
+
if (eth) {
|
|
237
|
+
await eth.request({
|
|
238
|
+
method: "wallet_revokePermissions",
|
|
239
|
+
params: [{ eth_accounts: {} }]
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (activeUnsub) activeUnsub();
|
|
246
|
+
activeUnsub = null;
|
|
247
|
+
if (activeProvider) {
|
|
248
|
+
await activeProvider.disconnect();
|
|
249
|
+
}
|
|
250
|
+
activeProvider = null;
|
|
251
|
+
persistProvider(null);
|
|
252
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
253
|
+
},
|
|
254
|
+
getState() {
|
|
255
|
+
return { ...state };
|
|
256
|
+
},
|
|
257
|
+
async sign(message) {
|
|
258
|
+
if (!activeProvider || !state.connected) throw new Error("Wallet not connected");
|
|
259
|
+
return activeProvider.sign(message);
|
|
260
|
+
},
|
|
261
|
+
onStateChange(handler) {
|
|
262
|
+
handlers.add(handler);
|
|
263
|
+
return () => handlers.delete(handler);
|
|
264
|
+
},
|
|
265
|
+
getProviders() {
|
|
266
|
+
return [...providers];
|
|
267
|
+
},
|
|
268
|
+
getActiveProvider() {
|
|
269
|
+
return activeProvider;
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
return plugin;
|
|
273
|
+
}
|
|
274
|
+
function createEthereumWallet() {
|
|
275
|
+
return createWallet({ providers: [createEIP1193Provider()] });
|
|
276
|
+
}
|
|
277
|
+
return __toCommonJS(index_exports);
|
|
278
|
+
})();
|
|
279
|
+
//# sourceMappingURL=index.global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Context, SettingDefinition, Wallet, WalletProvider, WalletState } from '@dnzn/dxkit';\nimport '@dnzn/dxkit-settings';\n\ndeclare module '@dnzn/dxkit' {\n interface EventMap {\n 'dx:plugin:wallet:connected': { address: string; chainId: number };\n 'dx:plugin:wallet:disconnected': Record<string, never>;\n 'dx:plugin:wallet:changed': { address: string; chainId: number };\n }\n}\n\n// ---------------------------------------------------------------------------\n// EIP-1193 Provider — works with MetaMask, Brave, Coinbase, any injected wallet\n// ---------------------------------------------------------------------------\n\n/** Creates a wallet provider using the browser's injected EIP-1193 provider (window.ethereum). */\nexport function createEIP1193Provider(): WalletProvider {\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n let accountsListener: ((accounts: string[]) => void) | null = null;\n let chainListener: ((chainIdHex: string) => void) | null = null;\n\n function getEthereumProvider(): any {\n return (window as any).ethereum;\n }\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'eip1193',\n name: 'Browser Wallet',\n\n available(): boolean {\n return !!(window as any).ethereum;\n },\n\n async connect(): Promise<WalletState> {\n const provider = getEthereumProvider();\n if (!provider) {\n throw new Error('No wallet detected. Install MetaMask or another EIP-1193 wallet.');\n }\n\n const accounts: string[] = await provider.request({ method: 'eth_requestAccounts' });\n const chainIdHex: string = await provider.request({ method: 'eth_chainId' });\n const chainId = parseInt(chainIdHex, 16);\n\n updateState({ connected: true, address: accounts[0], chainId, provider });\n\n // MetaMask/injected wallets fire these when user switches account or chain externally\n accountsListener = (accts: string[]) => {\n if (accts.length === 0) {\n updateState({ connected: false, address: null, provider: null });\n } else {\n updateState({ connected: true, address: accts[0] });\n }\n };\n chainListener = (hex: string) => {\n updateState({ chainId: parseInt(hex, 16) });\n };\n provider.on?.('accountsChanged', accountsListener);\n provider.on?.('chainChanged', chainListener);\n\n return state;\n },\n\n async disconnect(): Promise<void> {\n const provider = getEthereumProvider();\n if (accountsListener) provider?.removeListener?.('accountsChanged', accountsListener);\n if (chainListener) provider?.removeListener?.('chainChanged', chainListener);\n accountsListener = null;\n chainListener = null;\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n const provider = getEthereumProvider();\n if (!provider || !state.address) throw new Error('Wallet not connected');\n return provider.request({ method: 'personal_sign', params: [message, state.address] });\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Local Wallet Provider — dev/ephemeral, instant connect, no external deps\n// ---------------------------------------------------------------------------\n\nexport interface LocalWalletProviderOptions {\n /** Override the deterministic address. Default: '0x0000000000000000000000000000000001' */\n address?: string;\n}\n\n/** Creates a local dev wallet provider. Instant connect, deterministic address. */\nexport function createLocalWalletProvider(options?: LocalWalletProviderOptions): WalletProvider {\n const address = options?.address ?? '0x0000000000000000000000000000000001';\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'local',\n name: 'Local (Dev)',\n\n available(): boolean {\n return true;\n },\n\n async connect(): Promise<WalletState> {\n updateState({ connected: true, address, chainId: 0, provider: null });\n return state;\n },\n\n async disconnect(): Promise<void> {\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n if (!state.connected) throw new Error('Wallet not connected');\n // Deterministic signature for dev: hex-encode the message\n const bytes = new TextEncoder().encode(message);\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `0x${hex}`;\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wallet Coordinator — the Context plugin that manages providers\n// ---------------------------------------------------------------------------\n\nexport interface WalletOptions {\n /** Available wallet providers. First available is used by default. */\n providers: WalletProvider[];\n}\n\nconst STORAGE_KEY = 'dxkit:wallet';\n\n/** Creates the wallet Context plugin — a coordinator that delegates to pluggable providers. */\nexport function createWallet(options: WalletOptions): Wallet {\n const providers = options.providers;\n let activeProvider: WalletProvider | null = null;\n let activeUnsub: (() => void) | null = null;\n let dx: Context | null = null;\n\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function persistProvider(providerId: string | null): void {\n try {\n if (providerId) {\n localStorage.setItem(STORAGE_KEY, providerId);\n } else {\n localStorage.removeItem(STORAGE_KEY);\n }\n } catch {\n /* localStorage unavailable */\n }\n }\n\n function getPersistedProvider(): string | null {\n try {\n return localStorage.getItem(STORAGE_KEY);\n } catch {\n return null;\n }\n }\n\n function updateState(newState: WalletState): void {\n const wasConnected = state.connected;\n state = { ...newState };\n for (const handler of handlers) handler(state);\n\n if (!dx) return;\n if (newState.connected && !wasConnected) {\n dx.events.emit('dx:plugin:wallet:connected', { address: newState.address!, chainId: newState.chainId ?? 0 });\n } else if (!newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:disconnected', {});\n } else if (newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:changed', { address: newState.address!, chainId: newState.chainId ?? 0 });\n }\n }\n\n function getSetting(key: string, fallback: any): any {\n try {\n const settings = (dx as any)?.settings;\n if (settings) return settings.get('wallet', key) ?? fallback;\n } catch {\n /* settings plugin not available */\n }\n return fallback;\n }\n\n const plugin: Wallet = {\n name: 'wallet',\n\n settings: [\n {\n key: 'revokeOnDisconnect',\n label: 'Revoke on Disconnect',\n type: 'boolean',\n default: true,\n description:\n 'Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval.',\n },\n ] satisfies SettingDefinition[],\n\n async init(context: Context): Promise<void> {\n dx = context;\n\n context.eventRegistry.registerEvent('wallet', [\n { name: 'dx:plugin:wallet:connected' },\n { name: 'dx:plugin:wallet:disconnected' },\n { name: 'dx:plugin:wallet:changed' },\n ]);\n\n // Restore previous wallet connection\n const savedId = getPersistedProvider();\n if (savedId) {\n const provider = providers.find((p) => p.id === savedId);\n if (provider?.available()) {\n try {\n await plugin.connect(savedId);\n } catch {\n // Provider no longer available — clear persisted state\n persistProvider(null);\n }\n }\n }\n },\n\n async destroy(): Promise<void> {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n handlers.clear();\n dx = null;\n },\n\n async connect(providerId?: string): Promise<WalletState> {\n // Unsub before disconnect to avoid double-firing state change handlers\n if (activeProvider) {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n await activeProvider.disconnect();\n }\n\n // Select provider\n let provider: WalletProvider | undefined;\n if (providerId) {\n provider = providers.find((p) => p.id === providerId);\n if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);\n if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);\n } else {\n provider = providers.find((p) => p.available());\n if (!provider) throw new Error('No wallet provider available');\n }\n\n activeProvider = provider;\n\n // Subscribe before connect — provider.connect() triggers this, so no explicit updateState needed\n activeUnsub = provider.onStateChange((providerState: WalletState) => {\n updateState(providerState);\n });\n\n await provider.connect();\n persistProvider(provider.id);\n return state;\n },\n\n async disconnect(): Promise<void> {\n // EIP-1193 only: revoke permissions so reconnect requires explicit approval\n const shouldRevoke = getSetting('revokeOnDisconnect', true);\n if (shouldRevoke && activeProvider?.id === 'eip1193') {\n try {\n const eth = (window as any).ethereum;\n if (eth) {\n await eth.request({\n method: 'wallet_revokePermissions',\n params: [{ eth_accounts: {} }],\n });\n }\n } catch {\n /* Not all wallets support wallet_revokePermissions */\n }\n }\n\n // Unsub before disconnect to avoid double-firing state changes\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n persistProvider(null);\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n getState(): WalletState {\n return { ...state };\n },\n\n async sign(message: string): Promise<string> {\n if (!activeProvider || !state.connected) throw new Error('Wallet not connected');\n return activeProvider.sign(message);\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n\n getProviders(): WalletProvider[] {\n return [...providers];\n },\n\n getActiveProvider(): WalletProvider | null {\n return activeProvider;\n },\n };\n\n return plugin;\n}\n\n// ---------------------------------------------------------------------------\n// Backward compat — deprecated, use createWallet({ providers: [...] })\n// ---------------------------------------------------------------------------\n\n/**\n * @deprecated Use `createWallet({ providers: [createEIP1193Provider()] })` instead.\n */\nexport function createEthereumWallet(): Wallet {\n return createWallet({ providers: [createEIP1193Provider()] });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import "@dnzn/dxkit-settings";
|
|
3
|
+
function createEIP1193Provider() {
|
|
4
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
5
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
6
|
+
let accountsListener = null;
|
|
7
|
+
let chainListener = null;
|
|
8
|
+
function getEthereumProvider() {
|
|
9
|
+
return window.ethereum;
|
|
10
|
+
}
|
|
11
|
+
function updateState(updates) {
|
|
12
|
+
state = { ...state, ...updates };
|
|
13
|
+
for (const handler of handlers) handler(state);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
id: "eip1193",
|
|
17
|
+
name: "Browser Wallet",
|
|
18
|
+
available() {
|
|
19
|
+
return !!window.ethereum;
|
|
20
|
+
},
|
|
21
|
+
async connect() {
|
|
22
|
+
const provider = getEthereumProvider();
|
|
23
|
+
if (!provider) {
|
|
24
|
+
throw new Error("No wallet detected. Install MetaMask or another EIP-1193 wallet.");
|
|
25
|
+
}
|
|
26
|
+
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
27
|
+
const chainIdHex = await provider.request({ method: "eth_chainId" });
|
|
28
|
+
const chainId = parseInt(chainIdHex, 16);
|
|
29
|
+
updateState({ connected: true, address: accounts[0], chainId, provider });
|
|
30
|
+
accountsListener = (accts) => {
|
|
31
|
+
if (accts.length === 0) {
|
|
32
|
+
updateState({ connected: false, address: null, provider: null });
|
|
33
|
+
} else {
|
|
34
|
+
updateState({ connected: true, address: accts[0] });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
chainListener = (hex) => {
|
|
38
|
+
updateState({ chainId: parseInt(hex, 16) });
|
|
39
|
+
};
|
|
40
|
+
provider.on?.("accountsChanged", accountsListener);
|
|
41
|
+
provider.on?.("chainChanged", chainListener);
|
|
42
|
+
return state;
|
|
43
|
+
},
|
|
44
|
+
async disconnect() {
|
|
45
|
+
const provider = getEthereumProvider();
|
|
46
|
+
if (accountsListener) provider?.removeListener?.("accountsChanged", accountsListener);
|
|
47
|
+
if (chainListener) provider?.removeListener?.("chainChanged", chainListener);
|
|
48
|
+
accountsListener = null;
|
|
49
|
+
chainListener = null;
|
|
50
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
51
|
+
},
|
|
52
|
+
async sign(message) {
|
|
53
|
+
const provider = getEthereumProvider();
|
|
54
|
+
if (!provider || !state.address) throw new Error("Wallet not connected");
|
|
55
|
+
return provider.request({ method: "personal_sign", params: [message, state.address] });
|
|
56
|
+
},
|
|
57
|
+
onStateChange(handler) {
|
|
58
|
+
handlers.add(handler);
|
|
59
|
+
return () => handlers.delete(handler);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function createLocalWalletProvider(options) {
|
|
64
|
+
const address = options?.address ?? "0x0000000000000000000000000000000001";
|
|
65
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
66
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
67
|
+
function updateState(updates) {
|
|
68
|
+
state = { ...state, ...updates };
|
|
69
|
+
for (const handler of handlers) handler(state);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
id: "local",
|
|
73
|
+
name: "Local (Dev)",
|
|
74
|
+
available() {
|
|
75
|
+
return true;
|
|
76
|
+
},
|
|
77
|
+
async connect() {
|
|
78
|
+
updateState({ connected: true, address, chainId: 0, provider: null });
|
|
79
|
+
return state;
|
|
80
|
+
},
|
|
81
|
+
async disconnect() {
|
|
82
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
83
|
+
},
|
|
84
|
+
async sign(message) {
|
|
85
|
+
if (!state.connected) throw new Error("Wallet not connected");
|
|
86
|
+
const bytes = new TextEncoder().encode(message);
|
|
87
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
88
|
+
return `0x${hex}`;
|
|
89
|
+
},
|
|
90
|
+
onStateChange(handler) {
|
|
91
|
+
handlers.add(handler);
|
|
92
|
+
return () => handlers.delete(handler);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
var STORAGE_KEY = "dxkit:wallet";
|
|
97
|
+
function createWallet(options) {
|
|
98
|
+
const providers = options.providers;
|
|
99
|
+
let activeProvider = null;
|
|
100
|
+
let activeUnsub = null;
|
|
101
|
+
let dx = null;
|
|
102
|
+
let state = { connected: false, address: null, chainId: null, provider: null };
|
|
103
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
104
|
+
function persistProvider(providerId) {
|
|
105
|
+
try {
|
|
106
|
+
if (providerId) {
|
|
107
|
+
localStorage.setItem(STORAGE_KEY, providerId);
|
|
108
|
+
} else {
|
|
109
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
110
|
+
}
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function getPersistedProvider() {
|
|
115
|
+
try {
|
|
116
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function updateState(newState) {
|
|
122
|
+
const wasConnected = state.connected;
|
|
123
|
+
state = { ...newState };
|
|
124
|
+
for (const handler of handlers) handler(state);
|
|
125
|
+
if (!dx) return;
|
|
126
|
+
if (newState.connected && !wasConnected) {
|
|
127
|
+
dx.events.emit("dx:plugin:wallet:connected", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
128
|
+
} else if (!newState.connected && wasConnected) {
|
|
129
|
+
dx.events.emit("dx:plugin:wallet:disconnected", {});
|
|
130
|
+
} else if (newState.connected && wasConnected) {
|
|
131
|
+
dx.events.emit("dx:plugin:wallet:changed", { address: newState.address, chainId: newState.chainId ?? 0 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function getSetting(key, fallback) {
|
|
135
|
+
try {
|
|
136
|
+
const settings = dx?.settings;
|
|
137
|
+
if (settings) return settings.get("wallet", key) ?? fallback;
|
|
138
|
+
} catch {
|
|
139
|
+
}
|
|
140
|
+
return fallback;
|
|
141
|
+
}
|
|
142
|
+
const plugin = {
|
|
143
|
+
name: "wallet",
|
|
144
|
+
settings: [
|
|
145
|
+
{
|
|
146
|
+
key: "revokeOnDisconnect",
|
|
147
|
+
label: "Revoke on Disconnect",
|
|
148
|
+
type: "boolean",
|
|
149
|
+
default: true,
|
|
150
|
+
description: "Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval."
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
async init(context) {
|
|
154
|
+
dx = context;
|
|
155
|
+
context.eventRegistry.registerEvent("wallet", [
|
|
156
|
+
{ name: "dx:plugin:wallet:connected" },
|
|
157
|
+
{ name: "dx:plugin:wallet:disconnected" },
|
|
158
|
+
{ name: "dx:plugin:wallet:changed" }
|
|
159
|
+
]);
|
|
160
|
+
const savedId = getPersistedProvider();
|
|
161
|
+
if (savedId) {
|
|
162
|
+
const provider = providers.find((p) => p.id === savedId);
|
|
163
|
+
if (provider?.available()) {
|
|
164
|
+
try {
|
|
165
|
+
await plugin.connect(savedId);
|
|
166
|
+
} catch {
|
|
167
|
+
persistProvider(null);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
async destroy() {
|
|
173
|
+
if (activeUnsub) activeUnsub();
|
|
174
|
+
activeUnsub = null;
|
|
175
|
+
if (activeProvider) {
|
|
176
|
+
await activeProvider.disconnect();
|
|
177
|
+
}
|
|
178
|
+
activeProvider = null;
|
|
179
|
+
handlers.clear();
|
|
180
|
+
dx = null;
|
|
181
|
+
},
|
|
182
|
+
async connect(providerId) {
|
|
183
|
+
if (activeProvider) {
|
|
184
|
+
if (activeUnsub) activeUnsub();
|
|
185
|
+
activeUnsub = null;
|
|
186
|
+
await activeProvider.disconnect();
|
|
187
|
+
}
|
|
188
|
+
let provider;
|
|
189
|
+
if (providerId) {
|
|
190
|
+
provider = providers.find((p) => p.id === providerId);
|
|
191
|
+
if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);
|
|
192
|
+
if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);
|
|
193
|
+
} else {
|
|
194
|
+
provider = providers.find((p) => p.available());
|
|
195
|
+
if (!provider) throw new Error("No wallet provider available");
|
|
196
|
+
}
|
|
197
|
+
activeProvider = provider;
|
|
198
|
+
activeUnsub = provider.onStateChange((providerState) => {
|
|
199
|
+
updateState(providerState);
|
|
200
|
+
});
|
|
201
|
+
await provider.connect();
|
|
202
|
+
persistProvider(provider.id);
|
|
203
|
+
return state;
|
|
204
|
+
},
|
|
205
|
+
async disconnect() {
|
|
206
|
+
const shouldRevoke = getSetting("revokeOnDisconnect", true);
|
|
207
|
+
if (shouldRevoke && activeProvider?.id === "eip1193") {
|
|
208
|
+
try {
|
|
209
|
+
const eth = window.ethereum;
|
|
210
|
+
if (eth) {
|
|
211
|
+
await eth.request({
|
|
212
|
+
method: "wallet_revokePermissions",
|
|
213
|
+
params: [{ eth_accounts: {} }]
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (activeUnsub) activeUnsub();
|
|
220
|
+
activeUnsub = null;
|
|
221
|
+
if (activeProvider) {
|
|
222
|
+
await activeProvider.disconnect();
|
|
223
|
+
}
|
|
224
|
+
activeProvider = null;
|
|
225
|
+
persistProvider(null);
|
|
226
|
+
updateState({ connected: false, address: null, chainId: null, provider: null });
|
|
227
|
+
},
|
|
228
|
+
getState() {
|
|
229
|
+
return { ...state };
|
|
230
|
+
},
|
|
231
|
+
async sign(message) {
|
|
232
|
+
if (!activeProvider || !state.connected) throw new Error("Wallet not connected");
|
|
233
|
+
return activeProvider.sign(message);
|
|
234
|
+
},
|
|
235
|
+
onStateChange(handler) {
|
|
236
|
+
handlers.add(handler);
|
|
237
|
+
return () => handlers.delete(handler);
|
|
238
|
+
},
|
|
239
|
+
getProviders() {
|
|
240
|
+
return [...providers];
|
|
241
|
+
},
|
|
242
|
+
getActiveProvider() {
|
|
243
|
+
return activeProvider;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
return plugin;
|
|
247
|
+
}
|
|
248
|
+
function createEthereumWallet() {
|
|
249
|
+
return createWallet({ providers: [createEIP1193Provider()] });
|
|
250
|
+
}
|
|
251
|
+
export {
|
|
252
|
+
createEIP1193Provider,
|
|
253
|
+
createEthereumWallet,
|
|
254
|
+
createLocalWalletProvider,
|
|
255
|
+
createWallet
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Context, SettingDefinition, Wallet, WalletProvider, WalletState } from '@dnzn/dxkit';\nimport '@dnzn/dxkit-settings';\n\ndeclare module '@dnzn/dxkit' {\n interface EventMap {\n 'dx:plugin:wallet:connected': { address: string; chainId: number };\n 'dx:plugin:wallet:disconnected': Record<string, never>;\n 'dx:plugin:wallet:changed': { address: string; chainId: number };\n }\n}\n\n// ---------------------------------------------------------------------------\n// EIP-1193 Provider — works with MetaMask, Brave, Coinbase, any injected wallet\n// ---------------------------------------------------------------------------\n\n/** Creates a wallet provider using the browser's injected EIP-1193 provider (window.ethereum). */\nexport function createEIP1193Provider(): WalletProvider {\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n let accountsListener: ((accounts: string[]) => void) | null = null;\n let chainListener: ((chainIdHex: string) => void) | null = null;\n\n function getEthereumProvider(): any {\n return (window as any).ethereum;\n }\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'eip1193',\n name: 'Browser Wallet',\n\n available(): boolean {\n return !!(window as any).ethereum;\n },\n\n async connect(): Promise<WalletState> {\n const provider = getEthereumProvider();\n if (!provider) {\n throw new Error('No wallet detected. Install MetaMask or another EIP-1193 wallet.');\n }\n\n const accounts: string[] = await provider.request({ method: 'eth_requestAccounts' });\n const chainIdHex: string = await provider.request({ method: 'eth_chainId' });\n const chainId = parseInt(chainIdHex, 16);\n\n updateState({ connected: true, address: accounts[0], chainId, provider });\n\n // MetaMask/injected wallets fire these when user switches account or chain externally\n accountsListener = (accts: string[]) => {\n if (accts.length === 0) {\n updateState({ connected: false, address: null, provider: null });\n } else {\n updateState({ connected: true, address: accts[0] });\n }\n };\n chainListener = (hex: string) => {\n updateState({ chainId: parseInt(hex, 16) });\n };\n provider.on?.('accountsChanged', accountsListener);\n provider.on?.('chainChanged', chainListener);\n\n return state;\n },\n\n async disconnect(): Promise<void> {\n const provider = getEthereumProvider();\n if (accountsListener) provider?.removeListener?.('accountsChanged', accountsListener);\n if (chainListener) provider?.removeListener?.('chainChanged', chainListener);\n accountsListener = null;\n chainListener = null;\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n const provider = getEthereumProvider();\n if (!provider || !state.address) throw new Error('Wallet not connected');\n return provider.request({ method: 'personal_sign', params: [message, state.address] });\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Local Wallet Provider — dev/ephemeral, instant connect, no external deps\n// ---------------------------------------------------------------------------\n\nexport interface LocalWalletProviderOptions {\n /** Override the deterministic address. Default: '0x0000000000000000000000000000000001' */\n address?: string;\n}\n\n/** Creates a local dev wallet provider. Instant connect, deterministic address. */\nexport function createLocalWalletProvider(options?: LocalWalletProviderOptions): WalletProvider {\n const address = options?.address ?? '0x0000000000000000000000000000000001';\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function updateState(updates: Partial<WalletState>): void {\n state = { ...state, ...updates };\n for (const handler of handlers) handler(state);\n }\n\n return {\n id: 'local',\n name: 'Local (Dev)',\n\n available(): boolean {\n return true;\n },\n\n async connect(): Promise<WalletState> {\n updateState({ connected: true, address, chainId: 0, provider: null });\n return state;\n },\n\n async disconnect(): Promise<void> {\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n async sign(message: string): Promise<string> {\n if (!state.connected) throw new Error('Wallet not connected');\n // Deterministic signature for dev: hex-encode the message\n const bytes = new TextEncoder().encode(message);\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return `0x${hex}`;\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wallet Coordinator — the Context plugin that manages providers\n// ---------------------------------------------------------------------------\n\nexport interface WalletOptions {\n /** Available wallet providers. First available is used by default. */\n providers: WalletProvider[];\n}\n\nconst STORAGE_KEY = 'dxkit:wallet';\n\n/** Creates the wallet Context plugin — a coordinator that delegates to pluggable providers. */\nexport function createWallet(options: WalletOptions): Wallet {\n const providers = options.providers;\n let activeProvider: WalletProvider | null = null;\n let activeUnsub: (() => void) | null = null;\n let dx: Context | null = null;\n\n let state: WalletState = { connected: false, address: null, chainId: null, provider: null };\n const handlers = new Set<(state: WalletState) => void>();\n\n function persistProvider(providerId: string | null): void {\n try {\n if (providerId) {\n localStorage.setItem(STORAGE_KEY, providerId);\n } else {\n localStorage.removeItem(STORAGE_KEY);\n }\n } catch {\n /* localStorage unavailable */\n }\n }\n\n function getPersistedProvider(): string | null {\n try {\n return localStorage.getItem(STORAGE_KEY);\n } catch {\n return null;\n }\n }\n\n function updateState(newState: WalletState): void {\n const wasConnected = state.connected;\n state = { ...newState };\n for (const handler of handlers) handler(state);\n\n if (!dx) return;\n if (newState.connected && !wasConnected) {\n dx.events.emit('dx:plugin:wallet:connected', { address: newState.address!, chainId: newState.chainId ?? 0 });\n } else if (!newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:disconnected', {});\n } else if (newState.connected && wasConnected) {\n dx.events.emit('dx:plugin:wallet:changed', { address: newState.address!, chainId: newState.chainId ?? 0 });\n }\n }\n\n function getSetting(key: string, fallback: any): any {\n try {\n const settings = (dx as any)?.settings;\n if (settings) return settings.get('wallet', key) ?? fallback;\n } catch {\n /* settings plugin not available */\n }\n return fallback;\n }\n\n const plugin: Wallet = {\n name: 'wallet',\n\n settings: [\n {\n key: 'revokeOnDisconnect',\n label: 'Revoke on Disconnect',\n type: 'boolean',\n default: true,\n description:\n 'Revoke wallet permissions when disconnecting. When enabled, reconnecting requires explicit wallet approval.',\n },\n ] satisfies SettingDefinition[],\n\n async init(context: Context): Promise<void> {\n dx = context;\n\n context.eventRegistry.registerEvent('wallet', [\n { name: 'dx:plugin:wallet:connected' },\n { name: 'dx:plugin:wallet:disconnected' },\n { name: 'dx:plugin:wallet:changed' },\n ]);\n\n // Restore previous wallet connection\n const savedId = getPersistedProvider();\n if (savedId) {\n const provider = providers.find((p) => p.id === savedId);\n if (provider?.available()) {\n try {\n await plugin.connect(savedId);\n } catch {\n // Provider no longer available — clear persisted state\n persistProvider(null);\n }\n }\n }\n },\n\n async destroy(): Promise<void> {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n handlers.clear();\n dx = null;\n },\n\n async connect(providerId?: string): Promise<WalletState> {\n // Unsub before disconnect to avoid double-firing state change handlers\n if (activeProvider) {\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n await activeProvider.disconnect();\n }\n\n // Select provider\n let provider: WalletProvider | undefined;\n if (providerId) {\n provider = providers.find((p) => p.id === providerId);\n if (!provider) throw new Error(`Wallet provider '${providerId}' not found`);\n if (!provider.available()) throw new Error(`Wallet provider '${providerId}' is not available`);\n } else {\n provider = providers.find((p) => p.available());\n if (!provider) throw new Error('No wallet provider available');\n }\n\n activeProvider = provider;\n\n // Subscribe before connect — provider.connect() triggers this, so no explicit updateState needed\n activeUnsub = provider.onStateChange((providerState: WalletState) => {\n updateState(providerState);\n });\n\n await provider.connect();\n persistProvider(provider.id);\n return state;\n },\n\n async disconnect(): Promise<void> {\n // EIP-1193 only: revoke permissions so reconnect requires explicit approval\n const shouldRevoke = getSetting('revokeOnDisconnect', true);\n if (shouldRevoke && activeProvider?.id === 'eip1193') {\n try {\n const eth = (window as any).ethereum;\n if (eth) {\n await eth.request({\n method: 'wallet_revokePermissions',\n params: [{ eth_accounts: {} }],\n });\n }\n } catch {\n /* Not all wallets support wallet_revokePermissions */\n }\n }\n\n // Unsub before disconnect to avoid double-firing state changes\n if (activeUnsub) activeUnsub();\n activeUnsub = null;\n if (activeProvider) {\n await activeProvider.disconnect();\n }\n activeProvider = null;\n persistProvider(null);\n updateState({ connected: false, address: null, chainId: null, provider: null });\n },\n\n getState(): WalletState {\n return { ...state };\n },\n\n async sign(message: string): Promise<string> {\n if (!activeProvider || !state.connected) throw new Error('Wallet not connected');\n return activeProvider.sign(message);\n },\n\n onStateChange(handler: (state: WalletState) => void): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n\n getProviders(): WalletProvider[] {\n return [...providers];\n },\n\n getActiveProvider(): WalletProvider | null {\n return activeProvider;\n },\n };\n\n return plugin;\n}\n\n// ---------------------------------------------------------------------------\n// Backward compat — deprecated, use createWallet({ providers: [...] })\n// ---------------------------------------------------------------------------\n\n/**\n * @deprecated Use `createWallet({ providers: [createEIP1193Provider()] })` instead.\n */\nexport function createEthereumWallet(): Wallet {\n return createWallet({ providers: [createEIP1193Provider()] });\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dnzn/dxkit-wallet",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DxKit wallet plugin — injected wallet (window.ethereum)",
|
|
5
|
+
"author": "Denizen. <null@dnzn.dev>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/DxNZN/DxKit",
|
|
10
|
+
"directory": "plugins/wallet"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://dnzn.dev",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "dist/index.cjs",
|
|
15
|
+
"module": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@dnzn/dxkit-settings": "0.1.0",
|
|
29
|
+
"@dnzn/dxkit": "0.1.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"clean": "rm -rf dist"
|
|
34
|
+
}
|
|
35
|
+
}
|