shogun-core 1.2.7 → 1.2.8
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 +0 -1
- package/dist/browser/shogun-core.js +1 -1
- package/dist/browser/shogun-core.js.LICENSE.txt +2 -0
- package/dist/browser/shogun-core.light.js +1 -1
- package/dist/browser/shogun-core.vendors.light.js +1 -1
- package/dist/core.js +31 -71
- package/dist/gundb/{instance.js → gunInstance.js} +135 -115
- package/dist/gundb/index.js +3 -20
- package/dist/plugins/index.js +23 -1
- package/dist/plugins/nostr/index.js +1 -0
- package/dist/plugins/nostr/nostrChain.js +128 -0
- package/dist/plugins/nostr/nostrConnector.js +42 -7
- package/dist/plugins/nostr/nostrConnectorPlugin.js +157 -1
- package/dist/plugins/nostr/nostrSigner.js +343 -0
- package/dist/plugins/oauth/index.js +13 -0
- package/dist/plugins/oauth/oauthChain.js +161 -0
- package/dist/plugins/oauth/oauthConnector.js +542 -0
- package/dist/plugins/oauth/oauthPlugin.js +302 -0
- package/dist/plugins/oauth/types.js +2 -0
- package/dist/plugins/web3/index.js +1 -0
- package/dist/plugins/web3/web3Chain.js +77 -2
- package/dist/plugins/web3/web3Connector.js +159 -37
- package/dist/plugins/web3/web3ConnectorPlugin.js +157 -1
- package/dist/plugins/web3/web3Signer.js +268 -0
- package/dist/plugins/webauthn/webauthnChain.js +78 -0
- package/dist/plugins/webauthn/webauthnPlugin.js +154 -1
- package/dist/plugins/webauthn/webauthnSigner.js +318 -0
- package/dist/storage/storage.js +0 -8
- package/dist/types/core.d.ts +10 -34
- package/dist/types/gundb/gun-es/gun-es.d.ts +1 -0
- package/dist/types/gundb/{instance.d.ts → gunInstance.d.ts} +2 -2
- package/dist/types/gundb/index.d.ts +1 -4
- package/dist/types/plugins/index.d.ts +4 -0
- package/dist/types/plugins/nostr/index.d.ts +1 -0
- package/dist/types/plugins/nostr/nostrConnector.d.ts +3 -2
- package/dist/types/plugins/nostr/nostrConnectorPlugin.d.ts +82 -0
- package/dist/types/plugins/nostr/nostrSigner.d.ts +104 -0
- package/dist/types/plugins/oauth/index.d.ts +4 -0
- package/dist/types/plugins/oauth/oauthChain.d.ts +2 -0
- package/dist/types/plugins/oauth/oauthConnector.d.ts +100 -0
- package/dist/types/plugins/oauth/oauthPlugin.d.ts +89 -0
- package/dist/types/plugins/oauth/types.d.ts +106 -0
- package/dist/types/plugins/web3/index.d.ts +1 -0
- package/dist/types/plugins/web3/types.d.ts +1 -0
- package/dist/types/plugins/web3/web3Connector.d.ts +8 -2
- package/dist/types/plugins/web3/web3ConnectorPlugin.d.ts +82 -0
- package/dist/types/plugins/web3/web3Signer.d.ts +93 -0
- package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +81 -0
- package/dist/types/plugins/webauthn/webauthnSigner.d.ts +90 -0
- package/dist/types/shogun.js +1 -28
- package/dist/types/types/events.d.ts +2 -2
- package/dist/types/types/shogun.d.ts +13 -49
- package/package.json +2 -1
- package/dist/browser.js +0 -107
- package/dist/contracts/base.js +0 -152
- package/dist/contracts/entryPoint.js +0 -407
- package/dist/contracts/index.js +0 -47
- package/dist/contracts/registry.js +0 -259
- package/dist/contracts/relay.js +0 -494
- package/dist/contracts/utils.js +0 -582
- package/dist/types/browser.d.ts +0 -27
- package/dist/types/contracts/base.d.ts +0 -82
- package/dist/types/contracts/entryPoint.d.ts +0 -138
- package/dist/types/contracts/index.d.ts +0 -17
- package/dist/types/contracts/registry.d.ts +0 -97
- package/dist/types/contracts/relay.d.ts +0 -165
- package/dist/types/contracts/utils.d.ts +0 -173
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Web3ConnectorPlugin = void 0;
|
|
4
4
|
const base_1 = require("../base");
|
|
5
5
|
const web3Connector_1 = require("./web3Connector");
|
|
6
|
+
const web3Signer_1 = require("./web3Signer");
|
|
6
7
|
const logger_1 = require("../../utils/logger");
|
|
7
8
|
const ethers_1 = require("ethers");
|
|
8
9
|
const errorHandler_1 = require("../../utils/errorHandler");
|
|
@@ -14,6 +15,7 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
14
15
|
version = "1.0.0";
|
|
15
16
|
description = "Provides Ethereum wallet connection and authentication for ShogunCore";
|
|
16
17
|
Web3 = null;
|
|
18
|
+
signer = null;
|
|
17
19
|
/**
|
|
18
20
|
* @inheritdoc
|
|
19
21
|
*/
|
|
@@ -21,7 +23,8 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
21
23
|
super.initialize(core);
|
|
22
24
|
// Inizializziamo il modulo Web3
|
|
23
25
|
this.Web3 = new web3Connector_1.Web3Connector();
|
|
24
|
-
|
|
26
|
+
this.signer = new web3Signer_1.Web3Signer(this.Web3);
|
|
27
|
+
(0, logger_1.log)("Web3 plugin initialized with signer support");
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
30
|
* @inheritdoc
|
|
@@ -31,6 +34,7 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
31
34
|
this.Web3.cleanup();
|
|
32
35
|
}
|
|
33
36
|
this.Web3 = null;
|
|
37
|
+
this.signer = null;
|
|
34
38
|
super.destroy();
|
|
35
39
|
(0, logger_1.log)("Web3 plugin destroyed");
|
|
36
40
|
}
|
|
@@ -45,6 +49,17 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
45
49
|
}
|
|
46
50
|
return this.Web3;
|
|
47
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Assicura che il signer sia inizializzato
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
assertSigner() {
|
|
57
|
+
this.assertInitialized();
|
|
58
|
+
if (!this.signer) {
|
|
59
|
+
throw new Error("Web3 signer not initialized");
|
|
60
|
+
}
|
|
61
|
+
return this.signer;
|
|
62
|
+
}
|
|
48
63
|
/**
|
|
49
64
|
* @inheritdoc
|
|
50
65
|
*/
|
|
@@ -100,6 +115,147 @@ class Web3ConnectorPlugin extends base_1.BasePlugin {
|
|
|
100
115
|
async verifySignature(message, signature) {
|
|
101
116
|
return this.assertMetaMask().verifySignature(message, signature);
|
|
102
117
|
}
|
|
118
|
+
// === WEB3 SIGNER METHODS ===
|
|
119
|
+
/**
|
|
120
|
+
* Creates a new Web3 signing credential
|
|
121
|
+
* CONSISTENT with normal Web3 approach
|
|
122
|
+
*/
|
|
123
|
+
async createSigningCredential(address) {
|
|
124
|
+
try {
|
|
125
|
+
(0, logger_1.log)(`Creating Web3 signing credential for address: ${address}`);
|
|
126
|
+
return await this.assertSigner().createSigningCredential(address);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
(0, logger_1.logError)(`Error creating Web3 signing credential: ${error.message}`);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Creates an authenticator function for Web3 signing
|
|
135
|
+
*/
|
|
136
|
+
createAuthenticator(address) {
|
|
137
|
+
try {
|
|
138
|
+
(0, logger_1.log)(`Creating Web3 authenticator for address: ${address}`);
|
|
139
|
+
return this.assertSigner().createAuthenticator(address);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
(0, logger_1.logError)(`Error creating Web3 authenticator: ${error.message}`);
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Creates a derived key pair from Web3 credential
|
|
148
|
+
*/
|
|
149
|
+
async createDerivedKeyPair(address, extra) {
|
|
150
|
+
try {
|
|
151
|
+
(0, logger_1.log)(`Creating derived key pair for address: ${address}`);
|
|
152
|
+
return await this.assertSigner().createDerivedKeyPair(address, extra);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
(0, logger_1.logError)(`Error creating derived key pair: ${error.message}`);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Signs data with derived keys after Web3 verification
|
|
161
|
+
*/
|
|
162
|
+
async signWithDerivedKeys(data, address, extra) {
|
|
163
|
+
try {
|
|
164
|
+
(0, logger_1.log)(`Signing data with derived keys for address: ${address}`);
|
|
165
|
+
return await this.assertSigner().signWithDerivedKeys(data, address, extra);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
(0, logger_1.logError)(`Error signing with derived keys: ${error.message}`);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get signing credential by address
|
|
174
|
+
*/
|
|
175
|
+
getSigningCredential(address) {
|
|
176
|
+
return this.assertSigner().getCredential(address);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* List all signing credentials
|
|
180
|
+
*/
|
|
181
|
+
listSigningCredentials() {
|
|
182
|
+
return this.assertSigner().listCredentials();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Remove a signing credential
|
|
186
|
+
*/
|
|
187
|
+
removeSigningCredential(address) {
|
|
188
|
+
return this.assertSigner().removeCredential(address);
|
|
189
|
+
}
|
|
190
|
+
// === CONSISTENCY METHODS ===
|
|
191
|
+
/**
|
|
192
|
+
* Creates a Gun user from Web3 signing credential
|
|
193
|
+
* This ensures the SAME user is created as with normal approach
|
|
194
|
+
*/
|
|
195
|
+
async createGunUserFromSigningCredential(address) {
|
|
196
|
+
try {
|
|
197
|
+
const core = this.assertInitialized();
|
|
198
|
+
(0, logger_1.log)(`Creating Gun user from Web3 signing credential: ${address}`);
|
|
199
|
+
return await this.assertSigner().createGunUser(address, core.gun);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
(0, logger_1.logError)(`Error creating Gun user from Web3 signing credential: ${error.message}`);
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get the Gun user public key for a signing credential
|
|
208
|
+
*/
|
|
209
|
+
getGunUserPubFromSigningCredential(address) {
|
|
210
|
+
return this.assertSigner().getGunUserPub(address);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get the password (for consistency checking)
|
|
214
|
+
*/
|
|
215
|
+
getPassword(address) {
|
|
216
|
+
return this.assertSigner().getPassword(address);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Verify consistency between oneshot and normal approaches
|
|
220
|
+
* This ensures both approaches create the same Gun user
|
|
221
|
+
*/
|
|
222
|
+
async verifyConsistency(address, expectedUserPub) {
|
|
223
|
+
try {
|
|
224
|
+
(0, logger_1.log)(`Verifying Web3 consistency for address: ${address}`);
|
|
225
|
+
return await this.assertSigner().verifyConsistency(address, expectedUserPub);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
(0, logger_1.logError)(`Error verifying Web3 consistency: ${error.message}`);
|
|
229
|
+
return { consistent: false };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Complete oneshot workflow that creates the SAME Gun user as normal approach
|
|
234
|
+
* This is the recommended method for oneshot signing with full consistency
|
|
235
|
+
*/
|
|
236
|
+
async setupConsistentOneshotSigning(address) {
|
|
237
|
+
try {
|
|
238
|
+
(0, logger_1.log)(`Setting up consistent Web3 oneshot signing for: ${address}`);
|
|
239
|
+
// 1. Create signing credential (with consistent password generation)
|
|
240
|
+
const credential = await this.createSigningCredential(address);
|
|
241
|
+
// 2. Create authenticator
|
|
242
|
+
const authenticator = this.createAuthenticator(address);
|
|
243
|
+
// 3. Create Gun user (same as normal approach)
|
|
244
|
+
const gunUser = await this.createGunUserFromSigningCredential(address);
|
|
245
|
+
return {
|
|
246
|
+
credential,
|
|
247
|
+
authenticator,
|
|
248
|
+
gunUser,
|
|
249
|
+
username: credential.username,
|
|
250
|
+
password: credential.password,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
(0, logger_1.logError)(`Error setting up consistent Web3 oneshot signing: ${error.message}`);
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// === EXISTING METHODS ===
|
|
103
259
|
/**
|
|
104
260
|
* Login con Web3
|
|
105
261
|
* @param address - Indirizzo Ethereum
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Web3Signer = void 0;
|
|
7
|
+
const web3Connector_1 = require("./web3Connector");
|
|
8
|
+
const ethers_1 = require("ethers");
|
|
9
|
+
const logger_1 = require("../../utils/logger");
|
|
10
|
+
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
11
|
+
/**
|
|
12
|
+
* Web3 Signer - Provides oneshot signing functionality
|
|
13
|
+
* Similar to webauthn.js but for Web3/MetaMask
|
|
14
|
+
* CONSISTENT with normal Web3 approach
|
|
15
|
+
*/
|
|
16
|
+
class Web3Signer {
|
|
17
|
+
web3Connector;
|
|
18
|
+
credentials = new Map();
|
|
19
|
+
MESSAGE_TO_SIGN = "I Love Shogun!"; // Same as normal approach
|
|
20
|
+
constructor(web3Connector) {
|
|
21
|
+
this.web3Connector = web3Connector || new web3Connector_1.Web3Connector();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new Web3 signing credential
|
|
25
|
+
* CONSISTENT with normal Web3 approach
|
|
26
|
+
*/
|
|
27
|
+
async createSigningCredential(address) {
|
|
28
|
+
try {
|
|
29
|
+
(0, logger_1.logDebug)(`Creating Web3 signing credential for address: ${address}`);
|
|
30
|
+
// Validate address
|
|
31
|
+
const validAddress = ethers_1.ethers.getAddress(address.toLowerCase());
|
|
32
|
+
// Request signature using the same approach as normal Web3
|
|
33
|
+
const signature = await this.requestSignature(validAddress);
|
|
34
|
+
// Generate credentials using the SAME logic as normal approach
|
|
35
|
+
const username = `${validAddress.toLowerCase()}`;
|
|
36
|
+
const password = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(`${signature}:${validAddress.toLowerCase()}`));
|
|
37
|
+
const signingCredential = {
|
|
38
|
+
address: validAddress,
|
|
39
|
+
signature,
|
|
40
|
+
message: this.MESSAGE_TO_SIGN,
|
|
41
|
+
username,
|
|
42
|
+
password, // This ensures consistency with normal approach
|
|
43
|
+
};
|
|
44
|
+
// Store credential for later use
|
|
45
|
+
this.credentials.set(validAddress.toLowerCase(), signingCredential);
|
|
46
|
+
(0, logger_1.logDebug)("Created Web3 signing credential:", signingCredential);
|
|
47
|
+
return signingCredential;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
(0, logger_1.logError)("Error creating Web3 signing credential:", error);
|
|
51
|
+
throw new Error(`Failed to create Web3 signing credential: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Request signature from MetaMask
|
|
56
|
+
* Uses the same approach as normal Web3Connector
|
|
57
|
+
*/
|
|
58
|
+
async requestSignature(address) {
|
|
59
|
+
try {
|
|
60
|
+
const signer = await this.web3Connector.getSigner();
|
|
61
|
+
const signerAddress = await signer.getAddress();
|
|
62
|
+
if (signerAddress.toLowerCase() !== address.toLowerCase()) {
|
|
63
|
+
throw new Error(`Signer address (${signerAddress}) does not match expected address (${address})`);
|
|
64
|
+
}
|
|
65
|
+
(0, logger_1.logDebug)(`Requesting signature for message: ${this.MESSAGE_TO_SIGN}`);
|
|
66
|
+
const signature = await signer.signMessage(this.MESSAGE_TO_SIGN);
|
|
67
|
+
(0, logger_1.logDebug)("Signature obtained successfully");
|
|
68
|
+
return signature;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
(0, logger_1.logError)("Failed to request signature:", error);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates an authenticator function compatible with SEA.sign
|
|
77
|
+
* This is the key function that makes it work like webauthn.js but for Web3
|
|
78
|
+
*/
|
|
79
|
+
createAuthenticator(address) {
|
|
80
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
81
|
+
if (!credential) {
|
|
82
|
+
throw new Error(`Credential for address ${address} not found`);
|
|
83
|
+
}
|
|
84
|
+
return async (data) => {
|
|
85
|
+
try {
|
|
86
|
+
// Verify the user by requesting a new signature for the data
|
|
87
|
+
const signer = await this.web3Connector.getSigner();
|
|
88
|
+
const signerAddress = await signer.getAddress();
|
|
89
|
+
if (signerAddress.toLowerCase() !== address.toLowerCase()) {
|
|
90
|
+
throw new Error("Address mismatch during authentication");
|
|
91
|
+
}
|
|
92
|
+
// Sign the data
|
|
93
|
+
const dataToSign = JSON.stringify(data);
|
|
94
|
+
const signature = await signer.signMessage(dataToSign);
|
|
95
|
+
(0, logger_1.logDebug)("Web3 authentication successful:", { data, signature });
|
|
96
|
+
return signature;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
(0, logger_1.logError)("Web3 authentication error:", error);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates a derived key pair from Web3 credential
|
|
106
|
+
* CONSISTENT with normal approach: uses password as seed
|
|
107
|
+
*/
|
|
108
|
+
async createDerivedKeyPair(address, extra) {
|
|
109
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
110
|
+
if (!credential) {
|
|
111
|
+
throw new Error(`Credential for address ${address} not found`);
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
// CONSISTENCY: Use the same approach as normal Web3
|
|
115
|
+
// Use password as seed (same as normal approach)
|
|
116
|
+
const derivedKeys = await (0, derive_1.default)(credential.password, // This is the key consistency point!
|
|
117
|
+
extra, { includeP256: true });
|
|
118
|
+
return {
|
|
119
|
+
pub: derivedKeys.pub,
|
|
120
|
+
priv: derivedKeys.priv,
|
|
121
|
+
epub: derivedKeys.epub,
|
|
122
|
+
epriv: derivedKeys.epriv,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
(0, logger_1.logError)("Error deriving keys from Web3 credential:", error);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Creates a Gun user from Web3 credential
|
|
132
|
+
* This ensures the SAME user is created as with normal approach
|
|
133
|
+
*/
|
|
134
|
+
async createGunUser(address, gunInstance) {
|
|
135
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
136
|
+
if (!credential) {
|
|
137
|
+
throw new Error(`Credential for address ${address} not found`);
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
// Use the SAME approach as normal Web3
|
|
141
|
+
return new Promise((resolve) => {
|
|
142
|
+
gunInstance
|
|
143
|
+
.user()
|
|
144
|
+
.create(credential.username, credential.password, (ack) => {
|
|
145
|
+
if (ack.err) {
|
|
146
|
+
// Try to login if user already exists
|
|
147
|
+
gunInstance
|
|
148
|
+
.user()
|
|
149
|
+
.auth(credential.username, credential.password, (authAck) => {
|
|
150
|
+
if (authAck.err) {
|
|
151
|
+
resolve({ success: false, error: authAck.err });
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const userPub = authAck.pub;
|
|
155
|
+
// Update credential with Gun user pub
|
|
156
|
+
credential.gunUserPub = userPub;
|
|
157
|
+
this.credentials.set(address.toLowerCase(), credential);
|
|
158
|
+
resolve({ success: true, userPub });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// User created, now login
|
|
164
|
+
gunInstance
|
|
165
|
+
.user()
|
|
166
|
+
.auth(credential.username, credential.password, (authAck) => {
|
|
167
|
+
if (authAck.err) {
|
|
168
|
+
resolve({ success: false, error: authAck.err });
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
const userPub = authAck.pub;
|
|
172
|
+
// Update credential with Gun user pub
|
|
173
|
+
credential.gunUserPub = userPub;
|
|
174
|
+
this.credentials.set(address.toLowerCase(), credential);
|
|
175
|
+
resolve({ success: true, userPub });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
(0, logger_1.logError)("Error creating Gun user:", error);
|
|
184
|
+
return { success: false, error: error.message };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Signs data using Web3 + derived keys
|
|
189
|
+
* This provides a hybrid approach: Web3 for user verification + derived keys for actual signing
|
|
190
|
+
* CONSISTENT with normal approach
|
|
191
|
+
*/
|
|
192
|
+
async signWithDerivedKeys(data, address, extra) {
|
|
193
|
+
try {
|
|
194
|
+
// First, verify user with Web3
|
|
195
|
+
const authenticator = this.createAuthenticator(address);
|
|
196
|
+
await authenticator(data); // This verifies the user
|
|
197
|
+
// Then use derived keys for actual signing (CONSISTENT approach)
|
|
198
|
+
const keyPair = await this.createDerivedKeyPair(address, extra);
|
|
199
|
+
// Create signature using the same approach as SEA
|
|
200
|
+
const message = JSON.stringify(data);
|
|
201
|
+
const messageHash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(message));
|
|
202
|
+
// Use ethers for signing (compatible with SEA)
|
|
203
|
+
const wallet = new ethers_1.ethers.Wallet(keyPair.priv);
|
|
204
|
+
const signature = await wallet.signMessage(message);
|
|
205
|
+
// Format like SEA signature
|
|
206
|
+
const seaSignature = {
|
|
207
|
+
m: message,
|
|
208
|
+
s: signature,
|
|
209
|
+
};
|
|
210
|
+
return "SEA" + JSON.stringify(seaSignature);
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
(0, logger_1.logError)("Error signing with derived keys:", error);
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get the Gun user public key for a credential
|
|
219
|
+
* This allows checking if the same user would be created
|
|
220
|
+
*/
|
|
221
|
+
getGunUserPub(address) {
|
|
222
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
223
|
+
return credential?.gunUserPub;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get the password (for consistency checking)
|
|
227
|
+
*/
|
|
228
|
+
getPassword(address) {
|
|
229
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
230
|
+
return credential?.password;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if this credential would create the same Gun user as normal approach
|
|
234
|
+
*/
|
|
235
|
+
async verifyConsistency(address, expectedUserPub) {
|
|
236
|
+
const credential = this.credentials.get(address.toLowerCase());
|
|
237
|
+
if (!credential) {
|
|
238
|
+
return { consistent: false };
|
|
239
|
+
}
|
|
240
|
+
// The derived keys should be the same as normal approach
|
|
241
|
+
const derivedKeys = await this.createDerivedKeyPair(address);
|
|
242
|
+
return {
|
|
243
|
+
consistent: expectedUserPub ? derivedKeys.pub === expectedUserPub : true,
|
|
244
|
+
actualUserPub: derivedKeys.pub,
|
|
245
|
+
expectedUserPub,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get credential by address
|
|
250
|
+
*/
|
|
251
|
+
getCredential(address) {
|
|
252
|
+
return this.credentials.get(address.toLowerCase());
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* List all stored credentials
|
|
256
|
+
*/
|
|
257
|
+
listCredentials() {
|
|
258
|
+
return Array.from(this.credentials.values());
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Remove a credential
|
|
262
|
+
*/
|
|
263
|
+
removeCredential(address) {
|
|
264
|
+
return this.credentials.delete(address.toLowerCase());
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.Web3Signer = Web3Signer;
|
|
268
|
+
exports.default = Web3Signer;
|
|
@@ -5,8 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const gun_1 = __importDefault(require("gun"));
|
|
7
7
|
const webauthn_1 = require("./webauthn");
|
|
8
|
+
const webauthnSigner_1 = require("./webauthnSigner");
|
|
8
9
|
const webauthnChain = () => {
|
|
9
10
|
const webauthn = new webauthn_1.Webauthn();
|
|
11
|
+
const signer = new webauthnSigner_1.WebAuthnSigner(webauthn);
|
|
10
12
|
gun_1.default.chain.webauthn = {};
|
|
11
13
|
gun_1.default.chain.webauthn.isSupported = function () {
|
|
12
14
|
return webauthn.isSupported();
|
|
@@ -32,5 +34,81 @@ const webauthnChain = () => {
|
|
|
32
34
|
gun_1.default.chain.webauthn.validateUsername = function (username) {
|
|
33
35
|
return webauthn.validateUsername(username);
|
|
34
36
|
};
|
|
37
|
+
gun_1.default.chain.webauthn.createSigningCredential = async function (username) {
|
|
38
|
+
return await signer.createSigningCredential(username);
|
|
39
|
+
};
|
|
40
|
+
gun_1.default.chain.webauthn.createAuthenticator = function (credentialId) {
|
|
41
|
+
return signer.createAuthenticator(credentialId);
|
|
42
|
+
};
|
|
43
|
+
gun_1.default.chain.webauthn.createDerivedKeyPair = async function (credentialId, username, extra) {
|
|
44
|
+
return await signer.createDerivedKeyPair(credentialId, username, extra);
|
|
45
|
+
};
|
|
46
|
+
gun_1.default.chain.webauthn.signWithDerivedKeys = async function (data, credentialId, username, extra) {
|
|
47
|
+
return await signer.signWithDerivedKeys(data, credentialId, username, extra);
|
|
48
|
+
};
|
|
49
|
+
gun_1.default.chain.webauthn.getSigningCredential = function (credentialId) {
|
|
50
|
+
return signer.getCredential(credentialId);
|
|
51
|
+
};
|
|
52
|
+
gun_1.default.chain.webauthn.listSigningCredentials = function () {
|
|
53
|
+
return signer.listCredentials();
|
|
54
|
+
};
|
|
55
|
+
gun_1.default.chain.webauthn.removeSigningCredential = function (credentialId) {
|
|
56
|
+
return signer.removeCredential(credentialId);
|
|
57
|
+
};
|
|
58
|
+
gun_1.default.chain.webauthn.setupOneshotSigning = async function (username) {
|
|
59
|
+
const credential = await signer.createSigningCredential(username);
|
|
60
|
+
const authenticator = signer.createAuthenticator(credential.id);
|
|
61
|
+
return {
|
|
62
|
+
credential,
|
|
63
|
+
authenticator,
|
|
64
|
+
pub: credential.pub,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
gun_1.default.chain.webauthn.quickSign = async function (data, credentialId, username, extra) {
|
|
68
|
+
return await signer.signWithDerivedKeys(data, credentialId, username, extra);
|
|
69
|
+
};
|
|
70
|
+
// === CONSISTENCY METHODS ===
|
|
71
|
+
/**
|
|
72
|
+
* Creates a Gun user from WebAuthn signing credential
|
|
73
|
+
* Ensures SAME user as normal approach
|
|
74
|
+
*/
|
|
75
|
+
gun_1.default.chain.webauthn.createGunUserFromSigningCredential =
|
|
76
|
+
async function (credentialId, username) {
|
|
77
|
+
return await signer.createGunUser(credentialId, username, this);
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Get the Gun user public key for a signing credential
|
|
81
|
+
*/
|
|
82
|
+
gun_1.default.chain.webauthn.getGunUserPubFromSigningCredential = function (credentialId) {
|
|
83
|
+
return signer.getGunUserPub(credentialId);
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Get the hashed credential ID (for consistency checking)
|
|
87
|
+
*/
|
|
88
|
+
gun_1.default.chain.webauthn.getHashedCredentialId = function (credentialId) {
|
|
89
|
+
return signer.getHashedCredentialId(credentialId);
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Verify consistency between oneshot and normal approaches
|
|
93
|
+
*/
|
|
94
|
+
gun_1.default.chain.webauthn.verifyConsistency = async function (credentialId, username, expectedUserPub) {
|
|
95
|
+
return await signer.verifyConsistency(credentialId, username, expectedUserPub);
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Complete consistent oneshot signing workflow
|
|
99
|
+
* Creates the SAME Gun user as normal approach
|
|
100
|
+
*/
|
|
101
|
+
gun_1.default.chain.webauthn.setupConsistentOneshotSigning = async function (username) {
|
|
102
|
+
const credential = await signer.createSigningCredential(username);
|
|
103
|
+
const authenticator = signer.createAuthenticator(credential.id);
|
|
104
|
+
const gunUser = await signer.createGunUser(credential.id, username, this);
|
|
105
|
+
return {
|
|
106
|
+
credential,
|
|
107
|
+
authenticator,
|
|
108
|
+
gunUser,
|
|
109
|
+
pub: credential.pub,
|
|
110
|
+
hashedCredentialId: credential.hashedCredentialId,
|
|
111
|
+
};
|
|
112
|
+
};
|
|
35
113
|
};
|
|
36
114
|
exports.default = webauthnChain;
|