@noosphere/crypto 0.1.0-alpha.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/README.md +202 -0
- package/dist/index.cjs +550 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +231 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.js +512 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
KeystoreManager: () => KeystoreManager,
|
|
34
|
+
WalletManager: () => WalletManager
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/KeystoreManager.ts
|
|
39
|
+
var import_ethers = require("ethers");
|
|
40
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
41
|
+
var import_path = __toESM(require("path"));
|
|
42
|
+
var KeystoreManager = class _KeystoreManager {
|
|
43
|
+
constructor(keystorePath, password) {
|
|
44
|
+
this.keystore = null;
|
|
45
|
+
this.keystorePath = keystorePath;
|
|
46
|
+
this.password = password;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Initialize a new keystore with an EOA
|
|
50
|
+
* @param privateKey - Private key of the EOA (agent's main wallet)
|
|
51
|
+
* @param provider - Ethereum provider
|
|
52
|
+
*/
|
|
53
|
+
static async initialize(keystorePath, password, privateKey, provider) {
|
|
54
|
+
const wallet = new import_ethers.ethers.Wallet(privateKey, provider);
|
|
55
|
+
console.log("Encrypting EOA keystore...");
|
|
56
|
+
const eoaKeystore = await wallet.encrypt(password);
|
|
57
|
+
const keystore = {
|
|
58
|
+
version: "1.0.0",
|
|
59
|
+
eoa: {
|
|
60
|
+
address: wallet.address,
|
|
61
|
+
keystore: eoaKeystore
|
|
62
|
+
},
|
|
63
|
+
paymentWallets: {},
|
|
64
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
65
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
66
|
+
};
|
|
67
|
+
await import_promises.default.mkdir(import_path.default.dirname(keystorePath), { recursive: true });
|
|
68
|
+
await import_promises.default.writeFile(keystorePath, JSON.stringify(keystore, null, 2));
|
|
69
|
+
console.log(`\u2713 Keystore initialized: ${keystorePath}`);
|
|
70
|
+
console.log(` EOA Address: ${wallet.address}`);
|
|
71
|
+
const manager = new _KeystoreManager(keystorePath, password);
|
|
72
|
+
manager.keystore = keystore;
|
|
73
|
+
return manager;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Load existing keystore
|
|
77
|
+
*/
|
|
78
|
+
async load() {
|
|
79
|
+
try {
|
|
80
|
+
const data = await import_promises.default.readFile(this.keystorePath, "utf-8");
|
|
81
|
+
this.keystore = JSON.parse(data);
|
|
82
|
+
console.log(`\u2713 Loaded keystore: ${this.keystorePath}`);
|
|
83
|
+
console.log(` EOA: ${this.keystore.eoa.address}`);
|
|
84
|
+
console.log(` Payment Wallets: ${Object.keys(this.keystore.paymentWallets).length}`);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error.code === "ENOENT") {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Keystore not found: ${this.keystorePath}
|
|
89
|
+
Initialize a new keystore with KeystoreManager.initialize()`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the EOA wallet
|
|
97
|
+
*/
|
|
98
|
+
async getEOA(provider) {
|
|
99
|
+
if (!this.keystore) {
|
|
100
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
101
|
+
}
|
|
102
|
+
console.log("Decrypting EOA...");
|
|
103
|
+
const wallet = await import_ethers.ethers.Wallet.fromEncryptedJson(this.keystore.eoa.keystore, this.password);
|
|
104
|
+
return wallet.connect(provider);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get EOA address without decrypting
|
|
108
|
+
*/
|
|
109
|
+
getEOAAddress() {
|
|
110
|
+
if (!this.keystore) {
|
|
111
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
112
|
+
}
|
|
113
|
+
return this.keystore.eoa.address;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Add a payment wallet to the keystore
|
|
117
|
+
* @param walletAddress - Address of the payment wallet
|
|
118
|
+
* @param privateKey - Private key of the payment wallet
|
|
119
|
+
* @param subscriptionId - Optional subscription ID this wallet is for
|
|
120
|
+
*/
|
|
121
|
+
async addPaymentWallet(walletAddress, privateKey, subscriptionId, metadata) {
|
|
122
|
+
if (!this.keystore) {
|
|
123
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
124
|
+
}
|
|
125
|
+
const encryptedKey = await this.encryptData(privateKey);
|
|
126
|
+
this.keystore.paymentWallets[walletAddress] = {
|
|
127
|
+
address: walletAddress,
|
|
128
|
+
privateKey: encryptedKey,
|
|
129
|
+
subscriptionId,
|
|
130
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
131
|
+
metadata
|
|
132
|
+
};
|
|
133
|
+
this.keystore.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
134
|
+
await this.save();
|
|
135
|
+
console.log(`\u2713 Added payment wallet: ${walletAddress}`);
|
|
136
|
+
if (subscriptionId) {
|
|
137
|
+
console.log(` Subscription ID: ${subscriptionId}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get a payment wallet
|
|
142
|
+
*/
|
|
143
|
+
async getPaymentWallet(walletAddress, provider) {
|
|
144
|
+
if (!this.keystore) {
|
|
145
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
146
|
+
}
|
|
147
|
+
const walletData = this.keystore.paymentWallets[walletAddress];
|
|
148
|
+
if (!walletData) {
|
|
149
|
+
throw new Error(`Payment wallet not found: ${walletAddress}`);
|
|
150
|
+
}
|
|
151
|
+
const privateKey = await this.decryptData(walletData.privateKey);
|
|
152
|
+
const wallet = new import_ethers.ethers.Wallet(privateKey, provider);
|
|
153
|
+
if (wallet.address.toLowerCase() !== walletAddress.toLowerCase()) {
|
|
154
|
+
throw new Error("Decrypted wallet address mismatch");
|
|
155
|
+
}
|
|
156
|
+
return wallet;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* List all payment wallet addresses
|
|
160
|
+
*/
|
|
161
|
+
listPaymentWallets() {
|
|
162
|
+
if (!this.keystore) {
|
|
163
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
164
|
+
}
|
|
165
|
+
return Object.values(this.keystore.paymentWallets).map((w) => ({
|
|
166
|
+
address: w.address,
|
|
167
|
+
subscriptionId: w.subscriptionId,
|
|
168
|
+
createdAt: w.createdAt,
|
|
169
|
+
metadata: w.metadata
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Remove a payment wallet
|
|
174
|
+
*/
|
|
175
|
+
async removePaymentWallet(walletAddress) {
|
|
176
|
+
if (!this.keystore) {
|
|
177
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
178
|
+
}
|
|
179
|
+
if (!this.keystore.paymentWallets[walletAddress]) {
|
|
180
|
+
throw new Error(`Payment wallet not found: ${walletAddress}`);
|
|
181
|
+
}
|
|
182
|
+
delete this.keystore.paymentWallets[walletAddress];
|
|
183
|
+
this.keystore.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
184
|
+
await this.save();
|
|
185
|
+
console.log(`\u2713 Removed payment wallet: ${walletAddress}`);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get keystore info without decrypting
|
|
189
|
+
*/
|
|
190
|
+
getInfo() {
|
|
191
|
+
if (!this.keystore) {
|
|
192
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
version: this.keystore.version,
|
|
196
|
+
eoaAddress: this.keystore.eoa.address,
|
|
197
|
+
paymentWalletCount: Object.keys(this.keystore.paymentWallets).length,
|
|
198
|
+
createdAt: this.keystore.createdAt,
|
|
199
|
+
updatedAt: this.keystore.updatedAt
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if a payment wallet exists
|
|
204
|
+
*/
|
|
205
|
+
hasPaymentWallet(walletAddress) {
|
|
206
|
+
if (!this.keystore) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return walletAddress in this.keystore.paymentWallets;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Update EOA (re-encrypt with new password or new private key)
|
|
213
|
+
*/
|
|
214
|
+
async updateEOA(newPrivateKey, provider) {
|
|
215
|
+
if (!this.keystore) {
|
|
216
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
217
|
+
}
|
|
218
|
+
const wallet = new import_ethers.ethers.Wallet(newPrivateKey, provider);
|
|
219
|
+
console.log("Re-encrypting EOA...");
|
|
220
|
+
const newKeystore = await wallet.encrypt(this.password);
|
|
221
|
+
this.keystore.eoa = {
|
|
222
|
+
address: wallet.address,
|
|
223
|
+
keystore: newKeystore
|
|
224
|
+
};
|
|
225
|
+
this.keystore.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
226
|
+
await this.save();
|
|
227
|
+
console.log(`\u2713 Updated EOA: ${wallet.address}`);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Save keystore to disk
|
|
231
|
+
*/
|
|
232
|
+
async save() {
|
|
233
|
+
if (!this.keystore) {
|
|
234
|
+
throw new Error("No keystore to save");
|
|
235
|
+
}
|
|
236
|
+
await import_promises.default.writeFile(this.keystorePath, JSON.stringify(this.keystore, null, 2));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Encrypt data using password
|
|
240
|
+
* Uses a simple base64 encoding for now - in production, use proper encryption
|
|
241
|
+
*/
|
|
242
|
+
async encryptData(data) {
|
|
243
|
+
const encoded = Buffer.from(data).toString("base64");
|
|
244
|
+
return JSON.stringify({
|
|
245
|
+
version: "1.0",
|
|
246
|
+
_data: encoded
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Decrypt data using password
|
|
251
|
+
*/
|
|
252
|
+
async decryptData(encryptedData) {
|
|
253
|
+
const keystoreObj = JSON.parse(encryptedData);
|
|
254
|
+
if (!keystoreObj._data) {
|
|
255
|
+
throw new Error("Invalid encrypted data format");
|
|
256
|
+
}
|
|
257
|
+
return Buffer.from(keystoreObj._data, "base64").toString();
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Export keystore for backup
|
|
261
|
+
*/
|
|
262
|
+
async exportKeystore() {
|
|
263
|
+
if (!this.keystore) {
|
|
264
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
265
|
+
}
|
|
266
|
+
return JSON.stringify(this.keystore, null, 2);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Import keystore from backup
|
|
270
|
+
*/
|
|
271
|
+
static async importKeystore(keystorePath, password, keystoreJson) {
|
|
272
|
+
const keystore = JSON.parse(keystoreJson);
|
|
273
|
+
if (!keystore.version || !keystore.eoa || !keystore.paymentWallets) {
|
|
274
|
+
throw new Error("Invalid keystore format");
|
|
275
|
+
}
|
|
276
|
+
await import_promises.default.mkdir(import_path.default.dirname(keystorePath), { recursive: true });
|
|
277
|
+
await import_promises.default.writeFile(keystorePath, JSON.stringify(keystore, null, 2));
|
|
278
|
+
const manager = new _KeystoreManager(keystorePath, password);
|
|
279
|
+
manager.keystore = keystore;
|
|
280
|
+
console.log(`\u2713 Imported keystore: ${keystorePath}`);
|
|
281
|
+
console.log(` EOA: ${keystore.eoa.address}`);
|
|
282
|
+
console.log(` Payment Wallets: ${Object.keys(keystore.paymentWallets).length}`);
|
|
283
|
+
return manager;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Change password (re-encrypt all wallets)
|
|
287
|
+
*/
|
|
288
|
+
async changePassword(oldPassword, newPassword, provider) {
|
|
289
|
+
if (oldPassword !== this.password) {
|
|
290
|
+
throw new Error("Old password is incorrect");
|
|
291
|
+
}
|
|
292
|
+
if (!this.keystore) {
|
|
293
|
+
throw new Error("Keystore not loaded. Call load() first.");
|
|
294
|
+
}
|
|
295
|
+
console.log("Changing password...");
|
|
296
|
+
const eoaWallet = await import_ethers.ethers.Wallet.fromEncryptedJson(
|
|
297
|
+
this.keystore.eoa.keystore,
|
|
298
|
+
oldPassword
|
|
299
|
+
);
|
|
300
|
+
const newEoaKeystore = await eoaWallet.encrypt(newPassword);
|
|
301
|
+
this.keystore.eoa.keystore = newEoaKeystore;
|
|
302
|
+
const walletAddresses = Object.keys(this.keystore.paymentWallets);
|
|
303
|
+
for (const address of walletAddresses) {
|
|
304
|
+
const walletData = this.keystore.paymentWallets[address];
|
|
305
|
+
const decryptedKey = await this.decryptData(walletData.privateKey);
|
|
306
|
+
this.password = newPassword;
|
|
307
|
+
const reEncrypted = await this.encryptData(decryptedKey);
|
|
308
|
+
walletData.privateKey = reEncrypted;
|
|
309
|
+
}
|
|
310
|
+
this.password = newPassword;
|
|
311
|
+
this.keystore.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
312
|
+
await this.save();
|
|
313
|
+
console.log("\u2713 Password changed successfully");
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/WalletManager.ts
|
|
318
|
+
var import_ethers2 = require("ethers");
|
|
319
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
320
|
+
var import_path2 = __toESM(require("path"));
|
|
321
|
+
var import_contracts = require("@noosphere/contracts");
|
|
322
|
+
var WalletManager = class _WalletManager {
|
|
323
|
+
constructor(privateKey, provider, keystoreManager) {
|
|
324
|
+
this.wallet = new import_ethers2.ethers.Wallet(privateKey, provider);
|
|
325
|
+
this.provider = provider;
|
|
326
|
+
this.keystoreManager = keystoreManager;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Initialize WalletManager from KeystoreManager
|
|
330
|
+
* This is the recommended way to create a WalletManager for production use
|
|
331
|
+
*/
|
|
332
|
+
static async fromKeystoreManager(keystoreManager, provider) {
|
|
333
|
+
const wallet = await keystoreManager.getEOA(provider);
|
|
334
|
+
const manager = new _WalletManager(wallet.privateKey, provider, keystoreManager);
|
|
335
|
+
console.log("\u2713 WalletManager initialized from keystore");
|
|
336
|
+
return manager;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Get the agent's wallet address
|
|
340
|
+
*/
|
|
341
|
+
getAddress() {
|
|
342
|
+
return this.wallet.address;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get the wallet instance
|
|
346
|
+
*/
|
|
347
|
+
getWallet() {
|
|
348
|
+
return this.wallet;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Generate deterministic payment wallet using HDNode derivation
|
|
352
|
+
* @param subscriptionId - Subscription ID to derive wallet for
|
|
353
|
+
*/
|
|
354
|
+
async getDeterministicPaymentWallet(subscriptionId) {
|
|
355
|
+
const hdNode = import_ethers2.ethers.HDNodeWallet.fromPhrase(
|
|
356
|
+
await this.getMnemonic(),
|
|
357
|
+
void 0,
|
|
358
|
+
`m/44'/60'/0'/0/${subscriptionId.toString()}`
|
|
359
|
+
);
|
|
360
|
+
return hdNode.address;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Get or generate mnemonic for HD wallet derivation
|
|
364
|
+
*/
|
|
365
|
+
async getMnemonic() {
|
|
366
|
+
const mnemonicPath = import_path2.default.join(process.cwd(), ".noosphere", "mnemonic.txt");
|
|
367
|
+
try {
|
|
368
|
+
const mnemonic = await import_promises2.default.readFile(mnemonicPath, "utf-8");
|
|
369
|
+
return mnemonic.trim();
|
|
370
|
+
} catch {
|
|
371
|
+
const wallet = import_ethers2.ethers.Wallet.createRandom();
|
|
372
|
+
const mnemonic = wallet.mnemonic.phrase;
|
|
373
|
+
await import_promises2.default.mkdir(import_path2.default.dirname(mnemonicPath), { recursive: true });
|
|
374
|
+
await import_promises2.default.writeFile(mnemonicPath, mnemonic);
|
|
375
|
+
console.log("Generated new mnemonic and saved to", mnemonicPath);
|
|
376
|
+
console.log("\u26A0\uFE0F IMPORTANT: Back up this mnemonic phrase securely!");
|
|
377
|
+
return mnemonic;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Sign EIP-712 typed data for delegated subscription creation
|
|
382
|
+
*/
|
|
383
|
+
async signTypedData(domain, types, value) {
|
|
384
|
+
return this.wallet.signTypedData(domain, types, value);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Get current ETH balance
|
|
388
|
+
*/
|
|
389
|
+
async getBalance() {
|
|
390
|
+
return this.provider.getBalance(this.wallet.address);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get ERC20 token balance
|
|
394
|
+
*/
|
|
395
|
+
async getTokenBalance(tokenAddress) {
|
|
396
|
+
const erc20Abi = ["function balanceOf(address owner) view returns (uint256)"];
|
|
397
|
+
const contract = new import_ethers2.ethers.Contract(tokenAddress, erc20Abi, this.provider);
|
|
398
|
+
return contract.balanceOf(this.wallet.address);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Load wallet from keystore file
|
|
402
|
+
*/
|
|
403
|
+
static async fromKeystore(keystorePath, password, provider) {
|
|
404
|
+
const keystore = await import_promises2.default.readFile(keystorePath, "utf-8");
|
|
405
|
+
const wallet = await import_ethers2.ethers.Wallet.fromEncryptedJson(keystore, password);
|
|
406
|
+
return new _WalletManager(wallet.privateKey, provider);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Save wallet to encrypted keystore file
|
|
410
|
+
*/
|
|
411
|
+
async toKeystore(password, outputPath) {
|
|
412
|
+
const keystore = await this.wallet.encrypt(password);
|
|
413
|
+
await import_promises2.default.mkdir(import_path2.default.dirname(outputPath), { recursive: true });
|
|
414
|
+
await import_promises2.default.writeFile(outputPath, keystore);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Create a new payment wallet using WalletFactory contract
|
|
418
|
+
* @param walletFactoryAddress - Address of the WalletFactory contract
|
|
419
|
+
* @param initialOwner - Address that will own the new wallet (typically subscription owner)
|
|
420
|
+
* @param subscriptionId - Optional subscription ID to associate with this wallet
|
|
421
|
+
* @returns Transaction receipt and new wallet address
|
|
422
|
+
*/
|
|
423
|
+
async createPaymentWallet(walletFactoryAddress, initialOwner, subscriptionId) {
|
|
424
|
+
const walletFactory = import_contracts.WalletFactoryAbi__factory.connect(walletFactoryAddress, this.wallet);
|
|
425
|
+
console.log(`Creating payment wallet for owner: ${initialOwner}...`);
|
|
426
|
+
const tx = await walletFactory.createWallet(initialOwner);
|
|
427
|
+
const receipt = await tx.wait();
|
|
428
|
+
if (!receipt) {
|
|
429
|
+
throw new Error("Transaction receipt not available");
|
|
430
|
+
}
|
|
431
|
+
const event = receipt.logs.map((log) => {
|
|
432
|
+
try {
|
|
433
|
+
return walletFactory.interface.parseLog({
|
|
434
|
+
topics: [...log.topics],
|
|
435
|
+
data: log.data
|
|
436
|
+
});
|
|
437
|
+
} catch {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
}).find((e) => e && e.name === "WalletCreated");
|
|
441
|
+
if (!event) {
|
|
442
|
+
throw new Error("WalletCreated event not found in transaction receipt");
|
|
443
|
+
}
|
|
444
|
+
const walletAddress = event.args.walletAddress;
|
|
445
|
+
console.log(`\u2713 Payment wallet created: ${walletAddress}`);
|
|
446
|
+
console.log(` Transaction: ${receipt.hash}`);
|
|
447
|
+
console.log(` \u26A0\uFE0F This is a smart contract wallet (not an EOA)`);
|
|
448
|
+
if (this.keystoreManager && subscriptionId) {
|
|
449
|
+
await this.keystoreManager.addPaymentWallet(
|
|
450
|
+
walletAddress,
|
|
451
|
+
"",
|
|
452
|
+
// Smart contract wallet has no private key
|
|
453
|
+
subscriptionId,
|
|
454
|
+
{
|
|
455
|
+
type: "SmartContract",
|
|
456
|
+
factoryAddress: walletFactoryAddress
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
console.log(` \u2713 Wallet metadata saved to keystore`);
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
walletAddress,
|
|
463
|
+
txHash: receipt.hash
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Create a new EOA payment wallet and save to keystore
|
|
468
|
+
* This creates a regular externally-owned account (EOA) wallet
|
|
469
|
+
* @param subscriptionId - Optional subscription ID to associate with this wallet
|
|
470
|
+
* @returns Wallet address and private key (for immediate use, then should be discarded)
|
|
471
|
+
*/
|
|
472
|
+
async createEOAPaymentWallet(subscriptionId) {
|
|
473
|
+
const newWallet = import_ethers2.ethers.Wallet.createRandom();
|
|
474
|
+
console.log(`Creating EOA payment wallet: ${newWallet.address}...`);
|
|
475
|
+
if (this.keystoreManager) {
|
|
476
|
+
await this.keystoreManager.addPaymentWallet(
|
|
477
|
+
newWallet.address,
|
|
478
|
+
newWallet.privateKey,
|
|
479
|
+
subscriptionId,
|
|
480
|
+
{
|
|
481
|
+
type: "EOA",
|
|
482
|
+
createdBy: this.wallet.address
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
console.log(`\u2713 Payment wallet saved to keystore`);
|
|
486
|
+
} else {
|
|
487
|
+
console.warn("\u26A0\uFE0F KeystoreManager not available, wallet not saved");
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
walletAddress: newWallet.address,
|
|
491
|
+
privateKey: newWallet.privateKey
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Get a payment wallet from keystore
|
|
496
|
+
*/
|
|
497
|
+
async getPaymentWallet(walletAddress) {
|
|
498
|
+
if (!this.keystoreManager) {
|
|
499
|
+
throw new Error("KeystoreManager not available");
|
|
500
|
+
}
|
|
501
|
+
return this.keystoreManager.getPaymentWallet(walletAddress, this.provider);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* List all payment wallets in keystore
|
|
505
|
+
*/
|
|
506
|
+
listPaymentWallets() {
|
|
507
|
+
if (!this.keystoreManager) {
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
return this.keystoreManager.listPaymentWallets();
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Check if a wallet address was created by WalletFactory
|
|
514
|
+
* @param walletFactoryAddress - Address of the WalletFactory contract
|
|
515
|
+
* @param walletAddress - Wallet address to validate
|
|
516
|
+
* @returns True if wallet was created by this factory
|
|
517
|
+
*/
|
|
518
|
+
async isValidWallet(walletFactoryAddress, walletAddress) {
|
|
519
|
+
const walletFactory = import_contracts.WalletFactoryAbi__factory.connect(walletFactoryAddress, this.provider);
|
|
520
|
+
return walletFactory.isValidWallet(walletAddress);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Fund a payment wallet with ETH
|
|
524
|
+
* @param walletAddress - Address of the wallet to fund
|
|
525
|
+
* @param amount - Amount in ETH as string (e.g., "0.1")
|
|
526
|
+
*/
|
|
527
|
+
async fundWallet(walletAddress, amount) {
|
|
528
|
+
const tx = await this.wallet.sendTransaction({
|
|
529
|
+
to: walletAddress,
|
|
530
|
+
value: import_ethers2.ethers.parseEther(amount)
|
|
531
|
+
});
|
|
532
|
+
const receipt = await tx.wait();
|
|
533
|
+
console.log(`\u2713 Funded ${walletAddress} with ${amount} ETH`);
|
|
534
|
+
console.log(` Transaction: ${receipt?.hash}`);
|
|
535
|
+
return receipt?.hash || "";
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Get balance of a payment wallet
|
|
539
|
+
* @param walletAddress - Address of the wallet to check
|
|
540
|
+
*/
|
|
541
|
+
async getWalletBalance(walletAddress) {
|
|
542
|
+
return this.provider.getBalance(walletAddress);
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
546
|
+
0 && (module.exports = {
|
|
547
|
+
KeystoreManager,
|
|
548
|
+
WalletManager
|
|
549
|
+
});
|
|
550
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/KeystoreManager.ts","../src/WalletManager.ts"],"sourcesContent":["/**\n * @noosphere/crypto\n *\n * Cryptographic utilities and wallet management for Noosphere SDK\n * Used by agents, users, and verifiers for secure key management\n */\n\nexport { KeystoreManager } from './KeystoreManager';\nexport { WalletManager } from './WalletManager';\nexport * from './types';\n","import { ethers } from 'ethers';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport type { NoosphereKeystore, KeystoreInfo, PaymentWalletInfo } from './types';\n\n/**\n * KeystoreManager manages EOA and payment wallets in a single encrypted keystore file\n * This follows the Hub's keystore structure\n */\nexport class KeystoreManager {\n private keystorePath: string;\n private password: string;\n private keystore: NoosphereKeystore | null = null;\n\n constructor(keystorePath: string, password: string) {\n this.keystorePath = keystorePath;\n this.password = password;\n }\n\n /**\n * Initialize a new keystore with an EOA\n * @param privateKey - Private key of the EOA (agent's main wallet)\n * @param provider - Ethereum provider\n */\n static async initialize(\n keystorePath: string,\n password: string,\n privateKey: string,\n provider: ethers.Provider\n ): Promise<KeystoreManager> {\n const wallet = new ethers.Wallet(privateKey, provider);\n\n // Encrypt EOA keystore\n console.log('Encrypting EOA keystore...');\n const eoaKeystore = await wallet.encrypt(password);\n\n const keystore: NoosphereKeystore = {\n version: '1.0.0',\n eoa: {\n address: wallet.address,\n keystore: eoaKeystore,\n },\n paymentWallets: {},\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n // Save keystore\n await fs.mkdir(path.dirname(keystorePath), { recursive: true });\n await fs.writeFile(keystorePath, JSON.stringify(keystore, null, 2));\n\n console.log(`✓ Keystore initialized: ${keystorePath}`);\n console.log(` EOA Address: ${wallet.address}`);\n\n const manager = new KeystoreManager(keystorePath, password);\n manager.keystore = keystore;\n return manager;\n }\n\n /**\n * Load existing keystore\n */\n async load(): Promise<void> {\n try {\n const data = await fs.readFile(this.keystorePath, 'utf-8');\n this.keystore = JSON.parse(data);\n console.log(`✓ Loaded keystore: ${this.keystorePath}`);\n console.log(` EOA: ${this.keystore!.eoa.address}`);\n console.log(` Payment Wallets: ${Object.keys(this.keystore!.paymentWallets).length}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n throw new Error(\n `Keystore not found: ${this.keystorePath}\\n` +\n 'Initialize a new keystore with KeystoreManager.initialize()'\n );\n }\n throw error;\n }\n }\n\n /**\n * Get the EOA wallet\n */\n async getEOA(provider: ethers.Provider): Promise<ethers.Wallet> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n console.log('Decrypting EOA...');\n const wallet = await ethers.Wallet.fromEncryptedJson(this.keystore.eoa.keystore, this.password);\n\n return wallet.connect(provider) as ethers.Wallet;\n }\n\n /**\n * Get EOA address without decrypting\n */\n getEOAAddress(): string {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n return this.keystore.eoa.address;\n }\n\n /**\n * Add a payment wallet to the keystore\n * @param walletAddress - Address of the payment wallet\n * @param privateKey - Private key of the payment wallet\n * @param subscriptionId - Optional subscription ID this wallet is for\n */\n async addPaymentWallet(\n walletAddress: string,\n privateKey: string,\n subscriptionId?: string,\n metadata?: Record<string, any>\n ): Promise<void> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n // Encrypt private key\n const encryptedKey = await this.encryptData(privateKey);\n\n this.keystore.paymentWallets[walletAddress] = {\n address: walletAddress,\n privateKey: encryptedKey,\n subscriptionId,\n createdAt: new Date().toISOString(),\n metadata,\n };\n\n this.keystore.updatedAt = new Date().toISOString();\n\n await this.save();\n\n console.log(`✓ Added payment wallet: ${walletAddress}`);\n if (subscriptionId) {\n console.log(` Subscription ID: ${subscriptionId}`);\n }\n }\n\n /**\n * Get a payment wallet\n */\n async getPaymentWallet(walletAddress: string, provider: ethers.Provider): Promise<ethers.Wallet> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n const walletData = this.keystore.paymentWallets[walletAddress];\n if (!walletData) {\n throw new Error(`Payment wallet not found: ${walletAddress}`);\n }\n\n // Decrypt private key\n const privateKey = await this.decryptData(walletData.privateKey);\n const wallet = new ethers.Wallet(privateKey, provider);\n\n if (wallet.address.toLowerCase() !== walletAddress.toLowerCase()) {\n throw new Error('Decrypted wallet address mismatch');\n }\n\n return wallet;\n }\n\n /**\n * List all payment wallet addresses\n */\n listPaymentWallets(): PaymentWalletInfo[] {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n return Object.values(this.keystore.paymentWallets).map((w) => ({\n address: w.address,\n subscriptionId: w.subscriptionId,\n createdAt: w.createdAt,\n metadata: w.metadata,\n }));\n }\n\n /**\n * Remove a payment wallet\n */\n async removePaymentWallet(walletAddress: string): Promise<void> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n if (!this.keystore.paymentWallets[walletAddress]) {\n throw new Error(`Payment wallet not found: ${walletAddress}`);\n }\n\n delete this.keystore.paymentWallets[walletAddress];\n this.keystore.updatedAt = new Date().toISOString();\n\n await this.save();\n\n console.log(`✓ Removed payment wallet: ${walletAddress}`);\n }\n\n /**\n * Get keystore info without decrypting\n */\n getInfo(): KeystoreInfo {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n return {\n version: this.keystore.version,\n eoaAddress: this.keystore.eoa.address,\n paymentWalletCount: Object.keys(this.keystore.paymentWallets).length,\n createdAt: this.keystore.createdAt,\n updatedAt: this.keystore.updatedAt,\n };\n }\n\n /**\n * Check if a payment wallet exists\n */\n hasPaymentWallet(walletAddress: string): boolean {\n if (!this.keystore) {\n return false;\n }\n return walletAddress in this.keystore.paymentWallets;\n }\n\n /**\n * Update EOA (re-encrypt with new password or new private key)\n */\n async updateEOA(newPrivateKey: string, provider: ethers.Provider): Promise<void> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n const wallet = new ethers.Wallet(newPrivateKey, provider);\n\n console.log('Re-encrypting EOA...');\n const newKeystore = await wallet.encrypt(this.password);\n\n this.keystore.eoa = {\n address: wallet.address,\n keystore: newKeystore,\n };\n\n this.keystore.updatedAt = new Date().toISOString();\n\n await this.save();\n\n console.log(`✓ Updated EOA: ${wallet.address}`);\n }\n\n /**\n * Save keystore to disk\n */\n private async save(): Promise<void> {\n if (!this.keystore) {\n throw new Error('No keystore to save');\n }\n\n await fs.writeFile(this.keystorePath, JSON.stringify(this.keystore, null, 2));\n }\n\n /**\n * Encrypt data using password\n * Uses a simple base64 encoding for now - in production, use proper encryption\n */\n private async encryptData(data: string): Promise<string> {\n // For simplicity, we'll use base64 encoding\n // In production, this should use proper AES encryption with the password\n const encoded = Buffer.from(data).toString('base64');\n\n // Wrap in a simple structure\n return JSON.stringify({\n version: '1.0',\n _data: encoded,\n });\n }\n\n /**\n * Decrypt data using password\n */\n private async decryptData(encryptedData: string): Promise<string> {\n const keystoreObj = JSON.parse(encryptedData);\n if (!keystoreObj._data) {\n throw new Error('Invalid encrypted data format');\n }\n\n // Simple decryption - in production, use proper encryption\n // For now, we'll use a simpler approach with AES\n return Buffer.from(keystoreObj._data, 'base64').toString();\n }\n\n /**\n * Export keystore for backup\n */\n async exportKeystore(): Promise<string> {\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n return JSON.stringify(this.keystore, null, 2);\n }\n\n /**\n * Import keystore from backup\n */\n static async importKeystore(\n keystorePath: string,\n password: string,\n keystoreJson: string\n ): Promise<KeystoreManager> {\n const keystore: NoosphereKeystore = JSON.parse(keystoreJson);\n\n // Validate keystore format\n if (!keystore.version || !keystore.eoa || !keystore.paymentWallets) {\n throw new Error('Invalid keystore format');\n }\n\n // Save imported keystore\n await fs.mkdir(path.dirname(keystorePath), { recursive: true });\n await fs.writeFile(keystorePath, JSON.stringify(keystore, null, 2));\n\n const manager = new KeystoreManager(keystorePath, password);\n manager.keystore = keystore;\n\n console.log(`✓ Imported keystore: ${keystorePath}`);\n console.log(` EOA: ${keystore.eoa.address}`);\n console.log(` Payment Wallets: ${Object.keys(keystore.paymentWallets).length}`);\n\n return manager;\n }\n\n /**\n * Change password (re-encrypt all wallets)\n */\n async changePassword(\n oldPassword: string,\n newPassword: string,\n provider: ethers.Provider\n ): Promise<void> {\n if (oldPassword !== this.password) {\n throw new Error('Old password is incorrect');\n }\n\n if (!this.keystore) {\n throw new Error('Keystore not loaded. Call load() first.');\n }\n\n console.log('Changing password...');\n\n // Decrypt and re-encrypt EOA\n const eoaWallet = await ethers.Wallet.fromEncryptedJson(\n this.keystore.eoa.keystore,\n oldPassword\n );\n const newEoaKeystore = await eoaWallet.encrypt(newPassword);\n\n this.keystore.eoa.keystore = newEoaKeystore;\n\n // Re-encrypt all payment wallets\n const walletAddresses = Object.keys(this.keystore.paymentWallets);\n for (const address of walletAddresses) {\n const walletData = this.keystore.paymentWallets[address];\n const decryptedKey = await this.decryptData(walletData.privateKey);\n\n // Re-encrypt with new password\n this.password = newPassword;\n const reEncrypted = await this.encryptData(decryptedKey);\n walletData.privateKey = reEncrypted;\n }\n\n this.password = newPassword;\n this.keystore.updatedAt = new Date().toISOString();\n\n await this.save();\n\n console.log('✓ Password changed successfully');\n }\n}\n","import { ethers } from 'ethers';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { KeystoreManager } from './KeystoreManager';\nimport { WalletFactoryAbi__factory } from '@noosphere/contracts';\n\nexport class WalletManager {\n private wallet: ethers.Wallet;\n private provider: ethers.Provider;\n private keystoreManager?: KeystoreManager;\n\n constructor(privateKey: string, provider: ethers.Provider, keystoreManager?: KeystoreManager) {\n this.wallet = new ethers.Wallet(privateKey, provider);\n this.provider = provider;\n this.keystoreManager = keystoreManager;\n }\n\n /**\n * Initialize WalletManager from KeystoreManager\n * This is the recommended way to create a WalletManager for production use\n */\n static async fromKeystoreManager(\n keystoreManager: KeystoreManager,\n provider: ethers.Provider\n ): Promise<WalletManager> {\n const wallet = await keystoreManager.getEOA(provider);\n const manager = new WalletManager(wallet.privateKey, provider, keystoreManager);\n console.log('✓ WalletManager initialized from keystore');\n return manager;\n }\n\n /**\n * Get the agent's wallet address\n */\n getAddress(): string {\n return this.wallet.address;\n }\n\n /**\n * Get the wallet instance\n */\n getWallet(): ethers.Wallet {\n return this.wallet;\n }\n\n /**\n * Generate deterministic payment wallet using HDNode derivation\n * @param subscriptionId - Subscription ID to derive wallet for\n */\n async getDeterministicPaymentWallet(subscriptionId: bigint): Promise<string> {\n // Derive child wallet using subscription ID as path\n const hdNode = ethers.HDNodeWallet.fromPhrase(\n await this.getMnemonic(),\n undefined,\n `m/44'/60'/0'/0/${subscriptionId.toString()}`\n );\n\n return hdNode.address;\n }\n\n /**\n * Get or generate mnemonic for HD wallet derivation\n */\n private async getMnemonic(): Promise<string> {\n const mnemonicPath = path.join(process.cwd(), '.noosphere', 'mnemonic.txt');\n\n try {\n // Try to load existing mnemonic\n const mnemonic = await fs.readFile(mnemonicPath, 'utf-8');\n return mnemonic.trim();\n } catch {\n // Generate new mnemonic\n const wallet = ethers.Wallet.createRandom();\n const mnemonic = wallet.mnemonic!.phrase;\n\n // Save to file\n await fs.mkdir(path.dirname(mnemonicPath), { recursive: true });\n await fs.writeFile(mnemonicPath, mnemonic);\n\n console.log('Generated new mnemonic and saved to', mnemonicPath);\n console.log('⚠️ IMPORTANT: Back up this mnemonic phrase securely!');\n\n return mnemonic;\n }\n }\n\n /**\n * Sign EIP-712 typed data for delegated subscription creation\n */\n async signTypedData(\n domain: ethers.TypedDataDomain,\n types: Record<string, ethers.TypedDataField[]>,\n value: Record<string, any>\n ): Promise<string> {\n return this.wallet.signTypedData(domain, types, value);\n }\n\n /**\n * Get current ETH balance\n */\n async getBalance(): Promise<bigint> {\n return this.provider.getBalance(this.wallet.address);\n }\n\n /**\n * Get ERC20 token balance\n */\n async getTokenBalance(tokenAddress: string): Promise<bigint> {\n const erc20Abi = ['function balanceOf(address owner) view returns (uint256)'];\n\n const contract = new ethers.Contract(tokenAddress, erc20Abi, this.provider);\n return contract.balanceOf(this.wallet.address);\n }\n\n /**\n * Load wallet from keystore file\n */\n static async fromKeystore(\n keystorePath: string,\n password: string,\n provider: ethers.Provider\n ): Promise<WalletManager> {\n const keystore = await fs.readFile(keystorePath, 'utf-8');\n const wallet = await ethers.Wallet.fromEncryptedJson(keystore, password);\n return new WalletManager(wallet.privateKey, provider);\n }\n\n /**\n * Save wallet to encrypted keystore file\n */\n async toKeystore(password: string, outputPath: string): Promise<void> {\n const keystore = await this.wallet.encrypt(password);\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.writeFile(outputPath, keystore);\n }\n\n /**\n * Create a new payment wallet using WalletFactory contract\n * @param walletFactoryAddress - Address of the WalletFactory contract\n * @param initialOwner - Address that will own the new wallet (typically subscription owner)\n * @param subscriptionId - Optional subscription ID to associate with this wallet\n * @returns Transaction receipt and new wallet address\n */\n async createPaymentWallet(\n walletFactoryAddress: string,\n initialOwner: string,\n subscriptionId?: string\n ): Promise<{ walletAddress: string; txHash: string }> {\n // Use TypeChain-generated factory from @noosphere/contracts\n const walletFactory = WalletFactoryAbi__factory.connect(walletFactoryAddress, this.wallet);\n\n console.log(`Creating payment wallet for owner: ${initialOwner}...`);\n\n // Call createWallet with type-safe method\n const tx = await walletFactory.createWallet(initialOwner);\n const receipt = await tx.wait();\n\n if (!receipt) {\n throw new Error('Transaction receipt not available');\n }\n\n // Parse WalletCreated event using TypeChain-generated interface\n const event = receipt.logs\n .map((log) => {\n try {\n return walletFactory.interface.parseLog({\n topics: [...log.topics],\n data: log.data,\n });\n } catch {\n return null;\n }\n })\n .find((e) => e && e.name === 'WalletCreated');\n\n if (!event) {\n throw new Error('WalletCreated event not found in transaction receipt');\n }\n\n const walletAddress = event.args.walletAddress;\n\n console.log(`✓ Payment wallet created: ${walletAddress}`);\n console.log(` Transaction: ${receipt.hash}`);\n\n // Note: We don't have the private key for WalletFactory-created wallets\n // These are smart contract wallets, not EOAs\n // They are controlled through the WalletFactory contract\n console.log(` ⚠️ This is a smart contract wallet (not an EOA)`);\n\n // Save to keystore if available\n if (this.keystoreManager && subscriptionId) {\n await this.keystoreManager.addPaymentWallet(\n walletAddress,\n '', // Smart contract wallet has no private key\n subscriptionId,\n {\n type: 'SmartContract',\n factoryAddress: walletFactoryAddress,\n }\n );\n console.log(` ✓ Wallet metadata saved to keystore`);\n }\n\n return {\n walletAddress,\n txHash: receipt.hash,\n };\n }\n\n /**\n * Create a new EOA payment wallet and save to keystore\n * This creates a regular externally-owned account (EOA) wallet\n * @param subscriptionId - Optional subscription ID to associate with this wallet\n * @returns Wallet address and private key (for immediate use, then should be discarded)\n */\n async createEOAPaymentWallet(\n subscriptionId?: string\n ): Promise<{ walletAddress: string; privateKey: string }> {\n // Generate new wallet\n const newWallet = ethers.Wallet.createRandom();\n\n console.log(`Creating EOA payment wallet: ${newWallet.address}...`);\n\n // Save to keystore if available\n if (this.keystoreManager) {\n await this.keystoreManager.addPaymentWallet(\n newWallet.address,\n newWallet.privateKey,\n subscriptionId,\n {\n type: 'EOA',\n createdBy: this.wallet.address,\n }\n );\n console.log(`✓ Payment wallet saved to keystore`);\n } else {\n console.warn('⚠️ KeystoreManager not available, wallet not saved');\n }\n\n return {\n walletAddress: newWallet.address,\n privateKey: newWallet.privateKey,\n };\n }\n\n /**\n * Get a payment wallet from keystore\n */\n async getPaymentWallet(walletAddress: string): Promise<ethers.Wallet> {\n if (!this.keystoreManager) {\n throw new Error('KeystoreManager not available');\n }\n\n return this.keystoreManager.getPaymentWallet(walletAddress, this.provider);\n }\n\n /**\n * List all payment wallets in keystore\n */\n listPaymentWallets(): Array<{ address: string; subscriptionId?: string }> {\n if (!this.keystoreManager) {\n return [];\n }\n\n return this.keystoreManager.listPaymentWallets();\n }\n\n /**\n * Check if a wallet address was created by WalletFactory\n * @param walletFactoryAddress - Address of the WalletFactory contract\n * @param walletAddress - Wallet address to validate\n * @returns True if wallet was created by this factory\n */\n async isValidWallet(walletFactoryAddress: string, walletAddress: string): Promise<boolean> {\n // Use TypeChain-generated factory from @noosphere/contracts\n const walletFactory = WalletFactoryAbi__factory.connect(walletFactoryAddress, this.provider);\n\n return walletFactory.isValidWallet(walletAddress);\n }\n\n /**\n * Fund a payment wallet with ETH\n * @param walletAddress - Address of the wallet to fund\n * @param amount - Amount in ETH as string (e.g., \"0.1\")\n */\n async fundWallet(walletAddress: string, amount: string): Promise<string> {\n const tx = await this.wallet.sendTransaction({\n to: walletAddress,\n value: ethers.parseEther(amount),\n });\n\n const receipt = await tx.wait();\n console.log(`✓ Funded ${walletAddress} with ${amount} ETH`);\n console.log(` Transaction: ${receipt?.hash}`);\n\n return receipt?.hash || '';\n }\n\n /**\n * Get balance of a payment wallet\n * @param walletAddress - Address of the wallet to check\n */\n async getWalletBalance(walletAddress: string): Promise<bigint> {\n return this.provider.getBalance(walletAddress);\n }\n}\n"],"mappings":"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","names":["fs","path","import_ethers","import_promises","import_path","path","fs"]}
|