@dignetwork/dig-sdk 0.0.1-alpha.56 → 0.0.1-alpha.58
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/dist/DataIntegrityTree/DataIntegrityTree.d.ts +3 -0
- package/dist/DataIntegrityTree/DataIntegrityTree.d.ts.map +1 -1
- package/dist/DataIntegrityTree/DataIntegrityTree.js +5 -2
- package/dist/DigNetwork/PropagationServer.d.ts +16 -4
- package/dist/DigNetwork/PropagationServer.d.ts.map +1 -1
- package/dist/DigNetwork/PropagationServer.js +124 -46
- package/dist/blockchain/DataStore.d.ts +10 -1
- package/dist/blockchain/DataStore.d.ts.map +1 -1
- package/dist/blockchain/DataStore.js +36 -11
- package/dist/blockchain/Wallet.d.ts +1 -1
- package/dist/blockchain/Wallet.d.ts.map +1 -1
- package/dist/blockchain/Wallet.js +1 -1
- package/package.json +1 -1
|
@@ -78,6 +78,9 @@ declare class DataIntegrityTree {
|
|
|
78
78
|
* @returns The serialized Merkle tree.
|
|
79
79
|
*/
|
|
80
80
|
serialize(rootHash?: string | null): object;
|
|
81
|
+
static getRootOfForeignTree(treeData: {
|
|
82
|
+
leaves: string[];
|
|
83
|
+
}): string;
|
|
81
84
|
/**
|
|
82
85
|
* Deserialize a JSON object to a Merkle tree.
|
|
83
86
|
* @param rootHash - The root hash of the tree.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAuClC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,cAAM,iBAAiB;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAa;gBAEb,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,wBAA6B;WAiDrD,IAAI,CAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,wBAAwB,GAChC,iBAAiB;IAOpB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAUvB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;OAIG;YACW,WAAW;IAazB;;;;;OAKG;IACG,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqFjE;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAW5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,EAAE;IAalD;;;OAGG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,SAAS,CAAC,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM;IAqBjD,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,MAAM;IAQnE;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU;IAwB7C,OAAO,CAAC,wBAAwB;IAuBhC;;OAEG;IACH,MAAM,IAAI,MAAM,GAAG,SAAS;IAoC5B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO;IA+B/D;;;;;OAKG;IACH,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,UAAU,GAAE,MAAM,GAAG,IAAW,EAChC,MAAM,GAAE,MAAM,GAAG,IAAW,GAC3B,QAAQ;IA4DX;;OAEG;IACH,eAAe,IAAI,IAAI;IAKvB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUhE;;;;;;OAMG;IACH,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAM,GAAG,IAAW,GAC7B,MAAM;IAsCT;;;;;OAKG;IACH,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IA4B5D;;;;;OAKG;IACH,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB;QAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;IA+B/D;;;;;OAKG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyD5E;;;;;;;;;OASG;WACU,mCAAmC,CAC9C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;CAwFpB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -313,6 +313,11 @@ class DataIntegrityTree {
|
|
|
313
313
|
files: Object.fromEntries(this.files),
|
|
314
314
|
};
|
|
315
315
|
}
|
|
316
|
+
static getRootOfForeignTree(treeData) {
|
|
317
|
+
const leaves = treeData.leaves.map((leaf) => Buffer.from(leaf, "hex"));
|
|
318
|
+
const tree = new merkletreejs_1.MerkleTree(leaves, crypto_js_1.SHA256, { sortPairs: true });
|
|
319
|
+
return tree.getRoot().toString("hex");
|
|
320
|
+
}
|
|
316
321
|
/**
|
|
317
322
|
* Deserialize a JSON object to a Merkle tree.
|
|
318
323
|
* @param rootHash - The root hash of the tree.
|
|
@@ -603,7 +608,6 @@ class DataIntegrityTree {
|
|
|
603
608
|
decompressStream.on("end", () => {
|
|
604
609
|
const uncompressedSha256 = hash.digest("hex");
|
|
605
610
|
const isValid = uncompressedSha256 === sha256;
|
|
606
|
-
console.log(`SHA-256 of uncompressed file: ${uncompressedSha256}`);
|
|
607
611
|
if (!isValid) {
|
|
608
612
|
return resolve(false);
|
|
609
613
|
}
|
|
@@ -661,7 +665,6 @@ class DataIntegrityTree {
|
|
|
661
665
|
});
|
|
662
666
|
decompressStream.on("end", () => {
|
|
663
667
|
const uncompressedSha256 = hash.digest("hex");
|
|
664
|
-
console.log(`SHA-256 of uncompressed file: ${uncompressedSha256}`);
|
|
665
668
|
if (uncompressedSha256 !== sha256) {
|
|
666
669
|
console.warn(`File hash mismatch. Expected: ${sha256}, got: ${uncompressedSha256}`);
|
|
667
670
|
return resolve(false);
|
|
@@ -31,18 +31,30 @@ export declare class PropagationServer {
|
|
|
31
31
|
rootHashExists: boolean;
|
|
32
32
|
}>;
|
|
33
33
|
/**
|
|
34
|
-
* Start an upload session by sending a POST request
|
|
34
|
+
* Start an upload session by sending a POST request with the rootHash.dat file.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} rootHash - The root hash used to name the .dat file.
|
|
37
|
+
* @param {string} datFilePath - The full path to the rootHash.dat file.
|
|
35
38
|
*/
|
|
36
|
-
startUploadSession(): Promise<void>;
|
|
39
|
+
startUploadSession(rootHash: string): Promise<void>;
|
|
37
40
|
/**
|
|
38
41
|
* Request a nonce for a file by sending a HEAD request to the server.
|
|
42
|
+
* Checks if the file already exists based on the 'x-file-exists' header.
|
|
39
43
|
*/
|
|
40
|
-
getFileNonce(filename: string): Promise<
|
|
44
|
+
getFileNonce(filename: string): Promise<{
|
|
45
|
+
nonce: string;
|
|
46
|
+
fileExists: boolean;
|
|
47
|
+
}>;
|
|
41
48
|
/**
|
|
42
49
|
* Upload a file to the server by sending a PUT request.
|
|
43
50
|
* Logs progress using cli-progress for each file.
|
|
44
51
|
*/
|
|
45
|
-
uploadFile(
|
|
52
|
+
uploadFile(label: string, dataPath: string): Promise<any>;
|
|
53
|
+
/**
|
|
54
|
+
* Commit the upload session by sending a POST request to the server.
|
|
55
|
+
* This finalizes the upload and moves files from the temporary session directory to the permanent location.
|
|
56
|
+
*/
|
|
57
|
+
commitUploadSession(): Promise<any>;
|
|
46
58
|
/**
|
|
47
59
|
* Static function to handle the entire upload process for multiple files based on rootHash.
|
|
48
60
|
* @param {string} storeId - The ID of the DataStore.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,OAAO,CAAC;AAiB1B,qBAAa,iBAAiB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAIpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAqCrB;gBAEU,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAY9C;;OAEG;IACG,gBAAgB;IAKtB;;OAEG;IACH,gBAAgB;IAQhB;;;;;OAKG;IACG,gBAAgB,CACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IAwC7D;;;;;OAKG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAqDzC;;;OAGG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAyBlD;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IA+DhD;;;OAGG;IACG,mBAAmB;IAgCzB;;;;;;OAMG;WACU,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;IAiDnB;;;;;OAKG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4ClD;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM;IAgEnC;;;;;OAKG;WACU,aAAa,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;CA4BpB"}
|
|
@@ -17,6 +17,15 @@ const colorette_1 = require("colorette"); // For colored output
|
|
|
17
17
|
const config_1 = require("../utils/config");
|
|
18
18
|
const hashUtils_1 = require("../utils/hashUtils");
|
|
19
19
|
const nanospinner_1 = require("nanospinner");
|
|
20
|
+
// Helper function to trim long filenames with ellipsis and ensure consistent padding
|
|
21
|
+
function formatFilename(filename, maxLength = 30) {
|
|
22
|
+
if (filename.length > maxLength) {
|
|
23
|
+
// Trim the filename and add ellipsis
|
|
24
|
+
return `...${filename.slice(-(maxLength - 3))}`.padEnd(maxLength, " ");
|
|
25
|
+
}
|
|
26
|
+
// For shorter filenames, just pad to the maxLength
|
|
27
|
+
return filename.padEnd(maxLength, " ");
|
|
28
|
+
}
|
|
20
29
|
class PropagationServer {
|
|
21
30
|
constructor(storeId, ipAddress) {
|
|
22
31
|
this.storeId = storeId;
|
|
@@ -33,7 +42,7 @@ class PropagationServer {
|
|
|
33
42
|
*/
|
|
34
43
|
async initializeWallet() {
|
|
35
44
|
this.wallet = await blockchain_1.Wallet.load("default");
|
|
36
|
-
this.publicKey = await this.wallet.
|
|
45
|
+
this.publicKey = await this.wallet.getPublicSyntheticKey().toString("hex");
|
|
37
46
|
}
|
|
38
47
|
/**
|
|
39
48
|
* Create an Axios HTTPS Agent with self-signed certificate allowance.
|
|
@@ -57,7 +66,7 @@ class PropagationServer {
|
|
|
57
66
|
const config = {
|
|
58
67
|
httpsAgent: this.createHttpsAgent(),
|
|
59
68
|
};
|
|
60
|
-
let url = `https://${this.ipAddress}:${PropagationServer.port}
|
|
69
|
+
let url = `https://${this.ipAddress}:${PropagationServer.port}/${this.storeId}`;
|
|
61
70
|
if (rootHash) {
|
|
62
71
|
url += `?hasRootHash=${rootHash}`;
|
|
63
72
|
}
|
|
@@ -66,45 +75,56 @@ class PropagationServer {
|
|
|
66
75
|
const storeExists = response.headers["x-store-exists"] === "true";
|
|
67
76
|
const rootHashExists = response.headers["x-has-root-hash"] === "true";
|
|
68
77
|
if (storeExists) {
|
|
69
|
-
spinner.success({
|
|
78
|
+
spinner.success({
|
|
79
|
+
text: (0, colorette_1.green)(`Store ${this.storeId} exists on peer!`),
|
|
80
|
+
});
|
|
70
81
|
}
|
|
71
82
|
else {
|
|
72
|
-
spinner.error({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (rootHashExists) {
|
|
76
|
-
console.log((0, colorette_1.green)(`Root hash ${rootHash} exists in the store.`));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
console.log((0, colorette_1.red)(`Root hash ${rootHash} does not exist in the store.`));
|
|
80
|
-
}
|
|
83
|
+
spinner.error({
|
|
84
|
+
text: (0, colorette_1.red)(`Store ${this.storeId} does not exist. Credentials will be required to push.`),
|
|
85
|
+
});
|
|
81
86
|
}
|
|
82
87
|
return { storeExists, rootHashExists };
|
|
83
88
|
}
|
|
84
89
|
catch (error) {
|
|
85
90
|
spinner.error({ text: (0, colorette_1.red)("Error checking if store exists:") });
|
|
86
|
-
console.error((0, colorette_1.red)(error));
|
|
91
|
+
console.error((0, colorette_1.red)(error.message));
|
|
87
92
|
throw error;
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
/**
|
|
91
|
-
* Start an upload session by sending a POST request
|
|
96
|
+
* Start an upload session by sending a POST request with the rootHash.dat file.
|
|
97
|
+
*
|
|
98
|
+
* @param {string} rootHash - The root hash used to name the .dat file.
|
|
99
|
+
* @param {string} datFilePath - The full path to the rootHash.dat file.
|
|
92
100
|
*/
|
|
93
|
-
async startUploadSession() {
|
|
101
|
+
async startUploadSession(rootHash) {
|
|
94
102
|
const spinner = (0, nanospinner_1.createSpinner)(`Starting upload session for store ${this.storeId}...`).start();
|
|
95
103
|
try {
|
|
104
|
+
const formData = new form_data_1.default();
|
|
105
|
+
const datFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, `${rootHash}.dat`);
|
|
106
|
+
// Ensure the rootHash.dat file exists
|
|
107
|
+
if (!fs_1.default.existsSync(datFilePath)) {
|
|
108
|
+
throw new Error(`File not found: ${datFilePath}`);
|
|
109
|
+
}
|
|
110
|
+
formData.append("file", fs_1.default.createReadStream(datFilePath), {
|
|
111
|
+
filename: `${rootHash}.dat`,
|
|
112
|
+
});
|
|
96
113
|
const config = {
|
|
97
114
|
httpsAgent: this.createHttpsAgent(),
|
|
115
|
+
headers: {
|
|
116
|
+
...formData.getHeaders(),
|
|
117
|
+
},
|
|
98
118
|
};
|
|
99
|
-
// Add Basic Auth
|
|
119
|
+
// Add Basic Auth if username and password are present
|
|
100
120
|
if (this.username && this.password) {
|
|
101
121
|
config.auth = {
|
|
102
122
|
username: this.username,
|
|
103
123
|
password: this.password,
|
|
104
124
|
};
|
|
105
125
|
}
|
|
106
|
-
const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}`;
|
|
107
|
-
const response = await axios_1.default.post(url,
|
|
126
|
+
const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}?roothash=${rootHash}`;
|
|
127
|
+
const response = await axios_1.default.post(url, formData, config);
|
|
108
128
|
this.sessionId = response.data.sessionId;
|
|
109
129
|
spinner.success({
|
|
110
130
|
text: (0, colorette_1.green)(`Upload session started for DataStore ${this.storeId} with session ID ${this.sessionId}`),
|
|
@@ -112,12 +132,13 @@ class PropagationServer {
|
|
|
112
132
|
}
|
|
113
133
|
catch (error) {
|
|
114
134
|
spinner.error({ text: (0, colorette_1.red)("Error starting upload session:") });
|
|
115
|
-
console.error((0, colorette_1.red)(error));
|
|
135
|
+
console.error((0, colorette_1.red)(error.message));
|
|
116
136
|
throw error;
|
|
117
137
|
}
|
|
118
138
|
}
|
|
119
139
|
/**
|
|
120
140
|
* Request a nonce for a file by sending a HEAD request to the server.
|
|
141
|
+
* Checks if the file already exists based on the 'x-file-exists' header.
|
|
121
142
|
*/
|
|
122
143
|
async getFileNonce(filename) {
|
|
123
144
|
try {
|
|
@@ -126,12 +147,14 @@ class PropagationServer {
|
|
|
126
147
|
};
|
|
127
148
|
const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${filename}`;
|
|
128
149
|
const response = await axios_1.default.head(url, config);
|
|
150
|
+
// Check for 'x-file-exists' header
|
|
151
|
+
const fileExists = response.headers["x-file-exists"] === "true";
|
|
152
|
+
// If file exists, no need to generate a nonce
|
|
129
153
|
const nonce = response.headers["x-nonce"];
|
|
130
|
-
|
|
131
|
-
return nonce;
|
|
154
|
+
return { nonce, fileExists };
|
|
132
155
|
}
|
|
133
156
|
catch (error) {
|
|
134
|
-
console.error((0, colorette_1.red)(`Error generating nonce for file ${filename}:`), error);
|
|
157
|
+
console.error((0, colorette_1.red)(`Error generating nonce for file ${filename}:`), error.message);
|
|
135
158
|
throw error;
|
|
136
159
|
}
|
|
137
160
|
}
|
|
@@ -139,16 +162,22 @@ class PropagationServer {
|
|
|
139
162
|
* Upload a file to the server by sending a PUT request.
|
|
140
163
|
* Logs progress using cli-progress for each file.
|
|
141
164
|
*/
|
|
142
|
-
async uploadFile(
|
|
143
|
-
const
|
|
144
|
-
const nonce = await this.getFileNonce(
|
|
145
|
-
|
|
165
|
+
async uploadFile(label, dataPath) {
|
|
166
|
+
const filePath = path_1.default.join(config_1.STORE_PATH, this.storeId, dataPath);
|
|
167
|
+
const { nonce, fileExists } = await this.getFileNonce(dataPath);
|
|
168
|
+
if (fileExists) {
|
|
169
|
+
console.log((0, colorette_1.blue)(`File ${label} already exists. Skipping upload.`));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const wallet = await blockchain_1.Wallet.load("default");
|
|
173
|
+
const keyOwnershipSig = await wallet.createKeyOwnershipSignature(nonce);
|
|
174
|
+
const publicKey = await wallet.getPublicSyntheticKey();
|
|
146
175
|
const formData = new form_data_1.default();
|
|
147
176
|
formData.append("file", fs_1.default.createReadStream(filePath));
|
|
148
177
|
const fileSize = fs_1.default.statSync(filePath).size;
|
|
149
178
|
// Create a new progress bar for each file
|
|
150
179
|
const progressBar = PropagationServer.multiBar.create(fileSize, 0, {
|
|
151
|
-
filename: (0, colorette_1.yellow)(
|
|
180
|
+
filename: (0, colorette_1.yellow)(path_1.default.basename(label)),
|
|
152
181
|
percentage: 0,
|
|
153
182
|
});
|
|
154
183
|
let uploadedBytes = 0;
|
|
@@ -156,33 +185,61 @@ class PropagationServer {
|
|
|
156
185
|
headers: {
|
|
157
186
|
"Content-Type": "multipart/form-data",
|
|
158
187
|
"x-nonce": nonce,
|
|
159
|
-
"x-public-key":
|
|
188
|
+
"x-public-key": publicKey.toString("hex"),
|
|
160
189
|
"x-key-ownership-sig": keyOwnershipSig,
|
|
161
190
|
...formData.getHeaders(),
|
|
162
191
|
},
|
|
163
192
|
httpsAgent: this.createHttpsAgent(),
|
|
164
193
|
// Tracking upload progress and updating the progress bar
|
|
165
194
|
onUploadProgress: (progressEvent) => {
|
|
166
|
-
uploadedBytes
|
|
167
|
-
const percentage = Math.round((
|
|
195
|
+
const uploadedBytes = progressEvent.loaded;
|
|
196
|
+
const percentage = Math.round((100 * progressEvent.loaded) / progressEvent.total);
|
|
168
197
|
progressBar.update(uploadedBytes, { percentage });
|
|
169
198
|
},
|
|
170
199
|
};
|
|
171
200
|
try {
|
|
172
|
-
const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${
|
|
201
|
+
const url = `https://${this.ipAddress}:${PropagationServer.port}/upload/${this.storeId}/${this.sessionId}/${dataPath}`;
|
|
173
202
|
const response = await axios_1.default.put(url, formData, config);
|
|
174
|
-
console.log((0, colorette_1.green)(`✔ File ${filename} uploaded successfully.`));
|
|
175
203
|
// Complete the progress bar
|
|
176
204
|
progressBar.update(fileSize, { percentage: 100 });
|
|
177
205
|
progressBar.stop();
|
|
178
206
|
return response.data;
|
|
179
207
|
}
|
|
180
208
|
catch (error) {
|
|
181
|
-
console.error((0, colorette_1.red)(`✖ Error uploading file ${
|
|
209
|
+
console.error((0, colorette_1.red)(`✖ Error uploading file ${label}:`), error.message);
|
|
182
210
|
progressBar.stop(); // Stop the progress bar in case of error
|
|
183
211
|
throw error;
|
|
184
212
|
}
|
|
185
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Commit the upload session by sending a POST request to the server.
|
|
216
|
+
* This finalizes the upload and moves files from the temporary session directory to the permanent location.
|
|
217
|
+
*/
|
|
218
|
+
async commitUploadSession() {
|
|
219
|
+
const spinner = (0, nanospinner_1.createSpinner)(`Committing upload session for store ${this.storeId}...`).start();
|
|
220
|
+
try {
|
|
221
|
+
const config = {
|
|
222
|
+
httpsAgent: this.createHttpsAgent(),
|
|
223
|
+
auth: this.username && this.password
|
|
224
|
+
? {
|
|
225
|
+
username: this.username,
|
|
226
|
+
password: this.password,
|
|
227
|
+
}
|
|
228
|
+
: undefined,
|
|
229
|
+
};
|
|
230
|
+
const url = `https://${this.ipAddress}:${PropagationServer.port}/commit/${this.storeId}/${this.sessionId}`;
|
|
231
|
+
const response = await axios_1.default.post(url, {}, config);
|
|
232
|
+
spinner.success({
|
|
233
|
+
text: (0, colorette_1.green)(`Upload session ${this.sessionId} successfully committed.`),
|
|
234
|
+
});
|
|
235
|
+
return response.data;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
spinner.error({ text: (0, colorette_1.red)("Error committing upload session:") });
|
|
239
|
+
console.error((0, colorette_1.red)(error.message));
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
186
243
|
/**
|
|
187
244
|
* Static function to handle the entire upload process for multiple files based on rootHash.
|
|
188
245
|
* @param {string} storeId - The ID of the DataStore.
|
|
@@ -195,7 +252,7 @@ class PropagationServer {
|
|
|
195
252
|
// Initialize wallet
|
|
196
253
|
await propagationServer.initializeWallet();
|
|
197
254
|
// Check if the store exists
|
|
198
|
-
const storeExists = await propagationServer.checkStoreExists();
|
|
255
|
+
const { storeExists, rootHashExists } = await propagationServer.checkStoreExists(rootHash);
|
|
199
256
|
// If the store does not exist, prompt for credentials
|
|
200
257
|
if (!storeExists) {
|
|
201
258
|
console.log((0, colorette_1.red)(`Store ${storeId} does not exist. Prompting for credentials...`));
|
|
@@ -203,16 +260,20 @@ class PropagationServer {
|
|
|
203
260
|
propagationServer.username = credentials.username;
|
|
204
261
|
propagationServer.password = credentials.password;
|
|
205
262
|
}
|
|
263
|
+
if (rootHashExists) {
|
|
264
|
+
console.log((0, colorette_1.blue)(`Root hash ${rootHash} already exists in the store. Skipping upload.`));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
206
267
|
// Start the upload session
|
|
207
|
-
await propagationServer.startUploadSession();
|
|
268
|
+
await propagationServer.startUploadSession(rootHash);
|
|
208
269
|
const dataStore = blockchain_1.DataStore.from(storeId);
|
|
209
|
-
const
|
|
270
|
+
const files = await dataStore.getFileSetForRootHash(rootHash);
|
|
210
271
|
// Upload each file
|
|
211
|
-
for (const
|
|
212
|
-
await propagationServer.uploadFile(
|
|
272
|
+
for (const file of files) {
|
|
273
|
+
await propagationServer.uploadFile(file.name, file.path);
|
|
213
274
|
}
|
|
214
|
-
//
|
|
215
|
-
|
|
275
|
+
// Commit the session after all files have been uploaded
|
|
276
|
+
await propagationServer.commitUploadSession();
|
|
216
277
|
console.log((0, colorette_1.green)(`✔ All files have been uploaded to DataStore ${storeId}.`));
|
|
217
278
|
}
|
|
218
279
|
/**
|
|
@@ -294,7 +355,8 @@ class PropagationServer {
|
|
|
294
355
|
fileWriteStream.on("finish", () => {
|
|
295
356
|
progressBar.update(totalLength, { percentage: 100 });
|
|
296
357
|
progressBar.stop();
|
|
297
|
-
console.log((0, colorette_1.green)(
|
|
358
|
+
console.log((0, colorette_1.green)(`
|
|
359
|
+
File ${dataPath} downloaded successfully to ${downloadPath}.`));
|
|
298
360
|
resolve();
|
|
299
361
|
});
|
|
300
362
|
fileWriteStream.on("error", (error) => {
|
|
@@ -336,13 +398,29 @@ class PropagationServer {
|
|
|
336
398
|
}
|
|
337
399
|
exports.PropagationServer = PropagationServer;
|
|
338
400
|
PropagationServer.port = 4159; // Static port used for all requests
|
|
339
|
-
//
|
|
401
|
+
// Adjust cliProgress settings to align output properly and handle potential undefined values
|
|
402
|
+
// MultiBar for handling multiple progress bars with green progress and margin between bars
|
|
340
403
|
PropagationServer.multiBar = new cli_progress_1.default.MultiBar({
|
|
341
404
|
clearOnComplete: false,
|
|
342
405
|
hideCursor: true,
|
|
343
|
-
format: (
|
|
344
|
-
|
|
345
|
-
|
|
406
|
+
format: (options, params, payload) => {
|
|
407
|
+
// Bar length and padding settings
|
|
408
|
+
const barCompleteChar = (0, colorette_1.green)(options.barCompleteChar || "="); // Green bar for completed portion
|
|
409
|
+
const barIncompleteChar = options.barIncompleteChar || "-"; // Default incomplete character
|
|
410
|
+
const barSize = options.barsize || 40; // Default size of the bar
|
|
411
|
+
// Calculate the bar progress
|
|
412
|
+
const progressBar = `${barCompleteChar.repeat(Math.round(params.progress * barSize))}${barIncompleteChar.repeat(barSize - Math.round(params.progress * barSize))}`;
|
|
413
|
+
// Calculate the percentage manually
|
|
414
|
+
const percentage = Math.round((params.value / params.total) * 100);
|
|
415
|
+
// Format the filename to a fixed length
|
|
416
|
+
const formattedFilename = formatFilename(payload.filename, 30); // Trim to max 30 chars
|
|
417
|
+
// Padding the filename, percentage, and size
|
|
418
|
+
const percentageStr = `${percentage}%`.padEnd(4); // Ensure percentage is always 7 characters wide
|
|
419
|
+
const size = `${params.value}/${params.total} bytes`.padEnd(20); // Ensure size is always 20 characters wide
|
|
420
|
+
// Return the complete formatted progress bar with padding
|
|
421
|
+
return `${progressBar} | ${formattedFilename.padEnd(35)} | ${percentageStr} | ${size}`;
|
|
422
|
+
},
|
|
346
423
|
stopOnComplete: true,
|
|
347
|
-
|
|
424
|
+
barsize: 40,
|
|
425
|
+
align: "left",
|
|
348
426
|
}, cli_progress_1.default.Presets.shades_classic);
|
|
@@ -48,6 +48,15 @@ export declare class DataStore {
|
|
|
48
48
|
isSynced(): Promise<boolean>;
|
|
49
49
|
hasMetaWritePermissions(publicSyntheticKey?: Buffer): Promise<boolean>;
|
|
50
50
|
updateMetadata(metadata: DataStoreMetadata): Promise<DataStoreDriver>;
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Retrieve the file set for a given root hash and validate file integrity.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} rootHash - The root hash to fetch the file set.
|
|
55
|
+
* @returns {Promise<{ fileName: string, file: string }[]>} - An array of unique file objects.
|
|
56
|
+
*/
|
|
57
|
+
getFileSetForRootHash(rootHash: string): Promise<{
|
|
58
|
+
name: string;
|
|
59
|
+
path: string;
|
|
60
|
+
}[]>;
|
|
52
61
|
}
|
|
53
62
|
//# sourceMappingURL=DataStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataStore.d.ts","sourceRoot":"","sources":["../../src/blockchain/DataStore.ts"],"names":[],"mappings":"AAEA,OAAO,EAOL,SAAS,IAAI,eAAe,EAE5B,iBAAiB,EAIlB,MAAM,8BAA8B,CAAC;AAWtC,OAAO,EAAE,eAAe,EAAW,MAAM,UAAU,CAAC;AAGpD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"DataStore.d.ts","sourceRoot":"","sources":["../../src/blockchain/DataStore.ts"],"names":[],"mappings":"AAEA,OAAO,EAOL,SAAS,IAAI,eAAe,EAE5B,iBAAiB,EAIlB,MAAM,8BAA8B,CAAC;AAWtC,OAAO,EAAE,eAAe,EAAW,MAAM,UAAU,CAAC;AAGpD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAYjD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAoB;gBAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB;IAiB/D,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED,IAAW,IAAI,IAAI,iBAAiB,CAEnC;IAEM,QAAQ,IAAI,MAAM;IAIlB,QAAQ,IAAI,MAAM;IAIlB,SAAS,IAAI,MAAM;WAMN,cAAc,IAAI,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;WAOtD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;WAK1C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;WAYnC,MAAM,CACxB,MAAM,GAAE,qBAA0B,GACjC,OAAO,CAAC,SAAS,CAAC;mBAyCA,IAAI;IA4FzB;;;OAGG;IACU,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5C;;;OAGG;WACiB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxD;;;;OAIG;mBACkB,mBAAmB;WAqB1B,YAAY,IAAI,SAAS,EAAE;IAW5B,aAAa,IAAI,OAAO,CAAC;QACpC,WAAW,EAAE,eAAe,CAAC;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAyGW,iBAAiB,IAAI,OAAO,CAAC;QACxC,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;YA0BY,iBAAiB;IAYlB,cAAc,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAsC5C,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAKzC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAM5B,uBAAuB,CAClC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,OAAO,CAAC;IAkBN,cAAc,CACzB,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,eAAe,CAAC;IA+C3B;;;;;OAKG;IACU,qBAAqB,CAChC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAsD7C"}
|
|
@@ -18,6 +18,9 @@ const DataIntegrityTree_1 = require("../DataIntegrityTree");
|
|
|
18
18
|
const prompts_1 = require("../prompts");
|
|
19
19
|
const FileCache_1 = require("../utils/FileCache");
|
|
20
20
|
const DataStoreSerializer_1 = require("./DataStoreSerializer");
|
|
21
|
+
const node_cache_1 = __importDefault(require("node-cache"));
|
|
22
|
+
// Initialize the cache with a TTL of 180 seconds (3 minutes)
|
|
23
|
+
const rootHistoryCache = new node_cache_1.default({ stdTTL: 180 });
|
|
21
24
|
const stat = (0, util_1.promisify)(fs_1.default.stat);
|
|
22
25
|
const readdir = (0, util_1.promisify)(fs_1.default.readdir);
|
|
23
26
|
class DataStore {
|
|
@@ -284,18 +287,27 @@ class DataStore {
|
|
|
284
287
|
});
|
|
285
288
|
}
|
|
286
289
|
async getRootHistory() {
|
|
290
|
+
// Check if the root history is cached for this storeId
|
|
291
|
+
const cachedHistory = rootHistoryCache.get(this.storeId);
|
|
292
|
+
if (cachedHistory) {
|
|
293
|
+
return cachedHistory;
|
|
294
|
+
}
|
|
295
|
+
// Fetch root history from peer if not cached
|
|
287
296
|
const peer = await FullNodePeer_1.FullNodePeer.connect();
|
|
288
297
|
const { createdAtHeight, createdAtHash } = await this.getCreationHeight();
|
|
289
298
|
const { rootHashes, rootHashesTimestamps } = await peer.syncStoreFromLauncherId(Buffer.from(this.storeId, "hex"), createdAtHeight, createdAtHash, true);
|
|
290
299
|
if (!rootHashes) {
|
|
291
300
|
return [];
|
|
292
301
|
}
|
|
293
|
-
//
|
|
294
|
-
|
|
302
|
+
// Build the root history list
|
|
303
|
+
const rootHistory = rootHashes.map((rootHash, index) => ({
|
|
295
304
|
root_hash: rootHash.toString("hex"),
|
|
296
305
|
timestamp: Number(rootHashesTimestamps?.[index].toString()),
|
|
297
306
|
synced: fs_1.default.existsSync(path_1.default.join(config_1.STORE_PATH, this.storeId, `${rootHash.toString("hex")}.dat`)),
|
|
298
307
|
}));
|
|
308
|
+
// Store the root history in the cache
|
|
309
|
+
rootHistoryCache.set(this.storeId, rootHistory);
|
|
310
|
+
return rootHistory;
|
|
299
311
|
}
|
|
300
312
|
async getMetaData() {
|
|
301
313
|
const { latestStore } = await this.fetchCoinInfo();
|
|
@@ -337,29 +349,42 @@ class DataStore {
|
|
|
337
349
|
}
|
|
338
350
|
return updateStoreResponse.newStore;
|
|
339
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Retrieve the file set for a given root hash and validate file integrity.
|
|
354
|
+
*
|
|
355
|
+
* @param {string} rootHash - The root hash to fetch the file set.
|
|
356
|
+
* @returns {Promise<{ fileName: string, file: string }[]>} - An array of unique file objects.
|
|
357
|
+
*/
|
|
340
358
|
async getFileSetForRootHash(rootHash) {
|
|
341
359
|
const datFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, `${rootHash}.dat`);
|
|
342
360
|
const datFileContent = JSON.parse(fs_1.default.readFileSync(datFilePath, "utf-8"));
|
|
343
361
|
const heightDatFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, "height.json");
|
|
344
|
-
|
|
345
|
-
filesInvolved
|
|
346
|
-
filesInvolved.
|
|
362
|
+
// Use a Set to ensure uniqueness
|
|
363
|
+
const filesInvolved = new Set();
|
|
364
|
+
filesInvolved.add({
|
|
365
|
+
name: "height.json",
|
|
366
|
+
path: "height.json",
|
|
367
|
+
});
|
|
347
368
|
// Iterate over each file and perform an integrity check
|
|
348
369
|
for (const [fileKey, fileData] of Object.entries(datFileContent.files)) {
|
|
349
|
-
const filePath = (0, hashUtils_1.getFilePathFromSha256)(datFileContent.files[fileKey].sha256,
|
|
350
|
-
// Perform the integrity check
|
|
370
|
+
const filePath = (0, hashUtils_1.getFilePathFromSha256)(datFileContent.files[fileKey].sha256, "data");
|
|
371
|
+
// Perform the integrity check
|
|
351
372
|
const integrityCheck = await DataIntegrityTree_1.DataIntegrityTree.validateKeyIntegrityWithForeignTree(fileKey, datFileContent.files[fileKey].sha256, datFileContent, rootHash, path_1.default.join(config_1.STORE_PATH, this.storeId, "data"));
|
|
352
373
|
if (integrityCheck) {
|
|
353
|
-
console.log((0, colorette_1.green)(
|
|
354
|
-
// Add the file to the
|
|
355
|
-
filesInvolved.
|
|
374
|
+
console.log((0, colorette_1.green)(`✔ File ${fileKey} has passed the integrity check.`));
|
|
375
|
+
// Add the file to the Set
|
|
376
|
+
filesInvolved.add({
|
|
377
|
+
name: Buffer.from(fileKey, "hex").toString("utf-8"),
|
|
378
|
+
path: filePath,
|
|
379
|
+
});
|
|
356
380
|
}
|
|
357
381
|
else {
|
|
358
382
|
console.error((0, colorette_1.red)(`File ${fileKey} failed the integrity check.`));
|
|
359
383
|
throw new Error(`Integrity check failed for file: ${fileKey}. Aborting.`);
|
|
360
384
|
}
|
|
361
385
|
}
|
|
362
|
-
return
|
|
386
|
+
// Convert Set to Array and return
|
|
387
|
+
return Array.from(filesInvolved);
|
|
363
388
|
}
|
|
364
389
|
}
|
|
365
390
|
exports.DataStore = DataStore;
|
|
@@ -20,7 +20,7 @@ export declare class Wallet {
|
|
|
20
20
|
private static getWalletFromKeyring;
|
|
21
21
|
private static saveWalletToKeyring;
|
|
22
22
|
createKeyOwnershipSignature(nonce: string): Promise<string>;
|
|
23
|
-
verifyKeyOwnershipSignature(nonce: string, signature: string, publicKey: string): Promise<boolean>;
|
|
23
|
+
static verifyKeyOwnershipSignature(nonce: string, signature: string, publicKey: string): Promise<boolean>;
|
|
24
24
|
selectUnspentCoins(peer: Peer, coinAmount: bigint, feeBigInt: bigint, omitCoins?: Coin[]): Promise<Coin[]>;
|
|
25
25
|
static calculateFeeForCoinSpends(peer: Peer, coinSpends: CoinSpend[] | null): Promise<bigint>;
|
|
26
26
|
static isCoinSpendable(peer: Peer, coinId: Buffer): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Wallet.d.ts","sourceRoot":"","sources":["../../src/blockchain/Wallet.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EASL,IAAI,EACJ,IAAI,EAEJ,SAAS,EAEV,MAAM,8BAA8B,CAAC;AAMtC,eAAO,MAAM,qBAAqB,WAAa,CAAC;AAOhD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO;WAKa,IAAI,CACtB,UAAU,GAAE,MAAkB,EAC9B,iBAAiB,GAAE,OAAc,GAChC,OAAO,CAAC,MAAM,CAAC;IAsBX,WAAW,IAAI,MAAM;WAOR,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAMpD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAShE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BhE,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKrC,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAMxC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKzC,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAMrC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;WAK7B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WASlD,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;mBAU/B,oBAAoB;mBAWpB,mBAAmB;IAM3B,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Wallet.d.ts","sourceRoot":"","sources":["../../src/blockchain/Wallet.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EASL,IAAI,EACJ,IAAI,EAEJ,SAAS,EAEV,MAAM,8BAA8B,CAAC;AAMtC,eAAO,MAAM,qBAAqB,WAAa,CAAC;AAOhD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO;WAKa,IAAI,CACtB,UAAU,GAAE,MAAkB,EAC9B,iBAAiB,GAAE,OAAc,GAChC,OAAO,CAAC,MAAM,CAAC;IAsBX,WAAW,IAAI,MAAM;WAOR,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAMpD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAShE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BhE,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKrC,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAMxC,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKzC,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAMrC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;WAK7B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WASlD,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;mBAU/B,oBAAoB;mBAWpB,mBAAmB;IAM3B,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAOpD,2BAA2B,CAC7C,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IASN,kBAAkB,CAC7B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,IAAI,EAAO,GACrB,OAAO,CAAC,IAAI,EAAE,CAAC;WAwCE,yBAAyB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;WAItF,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAOlF"}
|
|
@@ -174,7 +174,7 @@ class Wallet {
|
|
|
174
174
|
const signature = (0, datalayer_driver_1.signMessage)(buffer_1.Buffer.from(message, "utf-8"), privateSyntheticKey);
|
|
175
175
|
return signature.toString("hex");
|
|
176
176
|
}
|
|
177
|
-
async verifyKeyOwnershipSignature(nonce, signature, publicKey) {
|
|
177
|
+
static async verifyKeyOwnershipSignature(nonce, signature, publicKey) {
|
|
178
178
|
const message = `Signing this message to prove ownership of key.\n\nNonce: ${nonce}`;
|
|
179
179
|
return (0, datalayer_driver_1.verifySignedMessage)(buffer_1.Buffer.from(signature, "hex"), buffer_1.Buffer.from(publicKey, "hex"), buffer_1.Buffer.from(message, "utf-8"));
|
|
180
180
|
}
|