@dignetwork/dig-sdk 0.0.1-alpha.10

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.
Files changed (104) hide show
  1. package/LICENSE +7 -0
  2. package/dist/DataIntegrityTree/DataIntegrityTree.d.ts +160 -0
  3. package/dist/DataIntegrityTree/DataIntegrityTree.d.ts.map +1 -0
  4. package/dist/DataIntegrityTree/DataIntegrityTree.js +648 -0
  5. package/dist/DataIntegrityTree/DataLayerError.d.ts +6 -0
  6. package/dist/DataIntegrityTree/DataLayerError.d.ts.map +1 -0
  7. package/dist/DataIntegrityTree/DataLayerError.js +17 -0
  8. package/dist/DataIntegrityTree/index.d.ts +2 -0
  9. package/dist/DataIntegrityTree/index.d.ts.map +1 -0
  10. package/dist/DataIntegrityTree/index.js +17 -0
  11. package/dist/DigNetwork/ContentServer.d.ts +28 -0
  12. package/dist/DigNetwork/ContentServer.d.ts.map +1 -0
  13. package/dist/DigNetwork/ContentServer.js +243 -0
  14. package/dist/DigNetwork/DigChallenge.d.ts +82 -0
  15. package/dist/DigNetwork/DigChallenge.d.ts.map +1 -0
  16. package/dist/DigNetwork/DigChallenge.js +144 -0
  17. package/dist/DigNetwork/DigNetwork.d.ts +20 -0
  18. package/dist/DigNetwork/DigNetwork.d.ts.map +1 -0
  19. package/dist/DigNetwork/DigNetwork.js +260 -0
  20. package/dist/DigNetwork/DigPeer.d.ts +19 -0
  21. package/dist/DigNetwork/DigPeer.d.ts.map +1 -0
  22. package/dist/DigNetwork/DigPeer.js +164 -0
  23. package/dist/DigNetwork/IncentiveServer.d.ts +13 -0
  24. package/dist/DigNetwork/IncentiveServer.d.ts.map +1 -0
  25. package/dist/DigNetwork/IncentiveServer.js +76 -0
  26. package/dist/DigNetwork/PropagationServer.d.ts +41 -0
  27. package/dist/DigNetwork/PropagationServer.d.ts.map +1 -0
  28. package/dist/DigNetwork/PropagationServer.js +415 -0
  29. package/dist/DigNetwork/index.d.ts +4 -0
  30. package/dist/DigNetwork/index.d.ts.map +1 -0
  31. package/dist/DigNetwork/index.js +19 -0
  32. package/dist/blockchain/DataStore.d.ts +56 -0
  33. package/dist/blockchain/DataStore.d.ts.map +1 -0
  34. package/dist/blockchain/DataStore.js +433 -0
  35. package/dist/blockchain/DataStoreSerializer.d.ts +52 -0
  36. package/dist/blockchain/DataStoreSerializer.d.ts.map +1 -0
  37. package/dist/blockchain/DataStoreSerializer.js +109 -0
  38. package/dist/blockchain/FullNodePeer.d.ts +24 -0
  39. package/dist/blockchain/FullNodePeer.d.ts.map +1 -0
  40. package/dist/blockchain/FullNodePeer.js +247 -0
  41. package/dist/blockchain/ServerCoin.d.ts +21 -0
  42. package/dist/blockchain/ServerCoin.d.ts.map +1 -0
  43. package/dist/blockchain/ServerCoin.js +261 -0
  44. package/dist/blockchain/Wallet.d.ts +28 -0
  45. package/dist/blockchain/Wallet.d.ts.map +1 -0
  46. package/dist/blockchain/Wallet.js +220 -0
  47. package/dist/blockchain/coins.d.ts +6 -0
  48. package/dist/blockchain/coins.d.ts.map +1 -0
  49. package/dist/blockchain/coins.js +101 -0
  50. package/dist/blockchain/index.d.ts +8 -0
  51. package/dist/blockchain/index.d.ts.map +1 -0
  52. package/dist/blockchain/index.js +36 -0
  53. package/dist/index.d.ts +5 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +20 -0
  56. package/dist/prompts.d.ts +21 -0
  57. package/dist/prompts.d.ts.map +1 -0
  58. package/dist/prompts.js +149 -0
  59. package/dist/types.d.ts +62 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +2 -0
  62. package/dist/utils/FileCache.d.ts +11 -0
  63. package/dist/utils/FileCache.d.ts.map +1 -0
  64. package/dist/utils/FileCache.js +58 -0
  65. package/dist/utils/NconfManager.d.ts +11 -0
  66. package/dist/utils/NconfManager.d.ts.map +1 -0
  67. package/dist/utils/NconfManager.js +55 -0
  68. package/dist/utils/config.d.ts +67 -0
  69. package/dist/utils/config.d.ts.map +1 -0
  70. package/dist/utils/config.js +218 -0
  71. package/dist/utils/connectionUtils.d.ts +10 -0
  72. package/dist/utils/connectionUtils.d.ts.map +1 -0
  73. package/dist/utils/connectionUtils.js +18 -0
  74. package/dist/utils/credentialsUtils.d.ts +8 -0
  75. package/dist/utils/credentialsUtils.d.ts.map +1 -0
  76. package/dist/utils/credentialsUtils.js +122 -0
  77. package/dist/utils/deltaUtils.d.ts +2 -0
  78. package/dist/utils/deltaUtils.d.ts.map +1 -0
  79. package/dist/utils/deltaUtils.js +83 -0
  80. package/dist/utils/directoryUtils.d.ts +15 -0
  81. package/dist/utils/directoryUtils.d.ts.map +1 -0
  82. package/dist/utils/directoryUtils.js +91 -0
  83. package/dist/utils/encryption.d.ts +8 -0
  84. package/dist/utils/encryption.d.ts.map +1 -0
  85. package/dist/utils/encryption.js +55 -0
  86. package/dist/utils/hashUtils.d.ts +8 -0
  87. package/dist/utils/hashUtils.d.ts.map +1 -0
  88. package/dist/utils/hashUtils.js +44 -0
  89. package/dist/utils/index.d.ts +14 -0
  90. package/dist/utils/index.d.ts.map +1 -0
  91. package/dist/utils/index.js +29 -0
  92. package/dist/utils/network.d.ts +2 -0
  93. package/dist/utils/network.d.ts.map +1 -0
  94. package/dist/utils/network.js +38 -0
  95. package/dist/utils/spinnerUtils.d.ts +2 -0
  96. package/dist/utils/spinnerUtils.d.ts.map +1 -0
  97. package/dist/utils/spinnerUtils.js +47 -0
  98. package/dist/utils/ssl.d.ts +5 -0
  99. package/dist/utils/ssl.d.ts.map +1 -0
  100. package/dist/utils/ssl.js +50 -0
  101. package/dist/utils/validationUtils.d.ts +9 -0
  102. package/dist/utils/validationUtils.d.ts.map +1 -0
  103. package/dist/utils/validationUtils.js +55 -0
  104. package/package.json +64 -0
@@ -0,0 +1,433 @@
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.DataStore = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const datalayer_driver_1 = require("datalayer-driver");
10
+ const util_1 = require("util");
11
+ const FullNodePeer_1 = require("./FullNodePeer");
12
+ const Wallet_1 = require("./Wallet");
13
+ const config_1 = require("../utils/config");
14
+ const coins_1 = require("./coins");
15
+ const utils_1 = require("../utils");
16
+ const hashUtils_1 = require("../utils/hashUtils");
17
+ const DataIntegrityTree_1 = require("../DataIntegrityTree");
18
+ const prompts_1 = require("../prompts");
19
+ const FileCache_1 = require("../utils/FileCache");
20
+ const DataStoreSerializer_1 = require("./DataStoreSerializer");
21
+ const stat = (0, util_1.promisify)(fs_1.default.stat);
22
+ const readdir = (0, util_1.promisify)(fs_1.default.readdir);
23
+ class DataStore {
24
+ constructor(storeId, options) {
25
+ this.storeId = storeId;
26
+ let _options;
27
+ if (options) {
28
+ _options = options;
29
+ }
30
+ else {
31
+ _options = {
32
+ storageMode: "local",
33
+ storeDir: config_1.STORE_PATH,
34
+ };
35
+ }
36
+ this.tree = new DataIntegrityTree_1.DataIntegrityTree(storeId, _options);
37
+ }
38
+ get StoreId() {
39
+ return this.storeId;
40
+ }
41
+ get Tree() {
42
+ return this.tree;
43
+ }
44
+ toBuffer() {
45
+ return Buffer.from(this.storeId, "hex");
46
+ }
47
+ toString() {
48
+ return this.storeId;
49
+ }
50
+ serialize() {
51
+ return JSON.stringify({
52
+ storeId: this.storeId,
53
+ });
54
+ }
55
+ static async getActiveStore() {
56
+ const storeId = await (0, config_1.getActiveStoreId)();
57
+ if (storeId) {
58
+ return DataStore.from(storeId.toString("hex"));
59
+ }
60
+ }
61
+ static deserialize(serialized) {
62
+ const parsed = JSON.parse(serialized);
63
+ return new DataStore(parsed.storeId);
64
+ }
65
+ static from(storeId) {
66
+ const existingTreeOptions = {
67
+ storageMode: "local",
68
+ storeDir: config_1.STORE_PATH,
69
+ disableInitialize: true,
70
+ };
71
+ if (storeId instanceof Buffer) {
72
+ return new DataStore(storeId.toString("hex"), existingTreeOptions);
73
+ }
74
+ return new DataStore(storeId, existingTreeOptions);
75
+ }
76
+ static async create(inputs = {}) {
77
+ const finalInputs = await (0, prompts_1.askForStoreDetails)(inputs);
78
+ try {
79
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
80
+ const height = await peer.getPeak();
81
+ if (!height) {
82
+ throw new Error("Failed to get peak height");
83
+ }
84
+ const hash = await peer.getHeaderHash(height);
85
+ const newStoreCoin = await this.mint(finalInputs.label, finalInputs.description, BigInt(0), finalInputs.authorizedWriter);
86
+ console.log("Store submitted to mempool");
87
+ console.log(`Store ID: ${newStoreCoin.launcherId.toString("hex")}`);
88
+ try {
89
+ console.log(`Coin ID: ${(0, datalayer_driver_1.getCoinId)(newStoreCoin.coin).toString("hex")}`);
90
+ await FullNodePeer_1.FullNodePeer.waitForConfirmation(newStoreCoin.coin.parentCoinInfo);
91
+ }
92
+ catch (error) {
93
+ console.error(error.message);
94
+ }
95
+ const dataStore = new DataStore(newStoreCoin.launcherId.toString("hex"));
96
+ await dataStore.setCreationHeight(height, hash);
97
+ return dataStore;
98
+ }
99
+ catch (error) {
100
+ console.error("Failed to mint Data Layer Store:", error);
101
+ throw error;
102
+ }
103
+ }
104
+ static async mint(label, description, sizeInBytes, authorizedWriterPublicSyntheticKey, adminPublicSyntheticKey) {
105
+ try {
106
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
107
+ const wallet = await Wallet_1.Wallet.load("default");
108
+ const publicSyntheticKey = await wallet.getPublicSyntheticKey();
109
+ const ownerSyntheicPuzzleHash = (0, datalayer_driver_1.syntheticKeyToPuzzleHash)(publicSyntheticKey);
110
+ const storeCreationCoins = await (0, coins_1.selectUnspentCoins)(peer, BigInt(1), BigInt(0));
111
+ const delegationLayers = [];
112
+ if (adminPublicSyntheticKey) {
113
+ delegationLayers.push((0, datalayer_driver_1.adminDelegatedPuzzleFromKey)(Buffer.from(adminPublicSyntheticKey, "hex")));
114
+ }
115
+ if (authorizedWriterPublicSyntheticKey) {
116
+ delegationLayers.push((0, datalayer_driver_1.writerDelegatedPuzzleFromKey)(Buffer.from(authorizedWriterPublicSyntheticKey, "hex")));
117
+ }
118
+ delegationLayers.push((0, datalayer_driver_1.oracleDelegatedPuzzle)(ownerSyntheicPuzzleHash, BigInt(100000)));
119
+ const rootHash = Buffer.from("0000000000000000000000000000000000000000000000000000000000000000", "hex");
120
+ const mintStoreParams = [
121
+ publicSyntheticKey,
122
+ storeCreationCoins,
123
+ rootHash,
124
+ label || undefined,
125
+ description || undefined,
126
+ sizeInBytes || BigInt(0),
127
+ ownerSyntheicPuzzleHash,
128
+ delegationLayers,
129
+ ];
130
+ const { coinSpends: preflightCoinSpends } = await (0, datalayer_driver_1.mintStore)(
131
+ // @ts-ignore
132
+ ...mintStoreParams,
133
+ // @ts-ignore
134
+ BigInt(0));
135
+ const fee = await (0, coins_1.calculateFeeForCoinSpends)(peer, preflightCoinSpends);
136
+ const storeCreationResponse = await datalayer_driver_1.mintStore.apply(null, [
137
+ // @ts-ignore
138
+ ...mintStoreParams,
139
+ // @ts-ignore
140
+ fee,
141
+ ]);
142
+ const sig = (0, datalayer_driver_1.signCoinSpends)(storeCreationResponse.coinSpends, [await wallet.getPrivateSyntheticKey()], false);
143
+ const err = await peer.broadcastSpend(storeCreationResponse.coinSpends, [sig]);
144
+ if (err) {
145
+ throw new Error(err);
146
+ }
147
+ await new Promise((resolve) => setTimeout(resolve, 5000));
148
+ return storeCreationResponse.newStore;
149
+ }
150
+ catch (error) {
151
+ console.error("Unable to mint store");
152
+ throw error;
153
+ }
154
+ }
155
+ /**
156
+ * Instance method to calculate the disk space used by the store/storeId folder.
157
+ * @returns {Promise<number>} - The total disk space used by the store in bytes.
158
+ */
159
+ async getDiskSpace() {
160
+ const storePath = path_1.default.join(config_1.STORE_PATH, this.storeId);
161
+ return await DataStore.calculateFolderSize(storePath);
162
+ }
163
+ /**
164
+ * Static method to calculate the total disk space used by all stores in the store folder.
165
+ * @returns {Promise<number>} - The total disk space used by the store folder in bytes.
166
+ */
167
+ static async getTotalDiskSpace() {
168
+ return await DataStore.calculateFolderSize(config_1.STORE_PATH);
169
+ }
170
+ /**
171
+ * Helper method to calculate the size of a folder and its subfolders recursively.
172
+ * @param folderPath - The path of the folder to calculate the size of.
173
+ * @returns {Promise<number>} - The total size of the folder in bytes.
174
+ */
175
+ static async calculateFolderSize(folderPath) {
176
+ let totalSize = BigInt(0);
177
+ const files = await readdir(folderPath);
178
+ for (const file of files) {
179
+ const filePath = path_1.default.join(folderPath, file);
180
+ const fileStat = await stat(filePath);
181
+ if (fileStat.isDirectory()) {
182
+ totalSize += await this.calculateFolderSize(filePath); // Recursive call for subdirectories
183
+ }
184
+ else {
185
+ totalSize += BigInt(fileStat.size); // Add file size to total
186
+ }
187
+ }
188
+ return totalSize;
189
+ }
190
+ static getAllStores() {
191
+ const storeFolders = fs_1.default.readdirSync(config_1.STORE_PATH);
192
+ const storIds = storeFolders.filter((folder) => /^[a-f0-9]{64}$/.test(folder) &&
193
+ fs_1.default.lstatSync(path_1.default.join(config_1.STORE_PATH, folder)).isDirectory());
194
+ return storIds.map((storeId) => DataStore.from(storeId));
195
+ }
196
+ async fetchCoinInfo() {
197
+ try {
198
+ // Initialize the cache for the current storeId's coin info
199
+ const storeCoinCache = new FileCache_1.FileCache(`stores`);
200
+ // Try to get cached store info
201
+ const cachedInfo = storeCoinCache.get(this.storeId);
202
+ if (cachedInfo) {
203
+ try {
204
+ const { latestStore: serializedStore, latestHeight: previousHeight, latestHash: previousHash, } = cachedInfo;
205
+ // Deserialize the stored data using DataStoreSerializer
206
+ const { latestStore: previousInfo } = DataStoreSerializer_1.DataStoreSerializer.deserialize({
207
+ latestStore: serializedStore,
208
+ latestHeight: previousHeight.toString(),
209
+ latestHash: previousHash,
210
+ });
211
+ // Sync with peer if necessary
212
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
213
+ const { latestStore, latestHeight } = await peer.syncStore(previousInfo, previousHeight, Buffer.from(previousHash, "hex"), false);
214
+ const latestHash = await peer.getHeaderHash(latestHeight);
215
+ // Serialize the store data for caching
216
+ const serializedLatestStore = new DataStoreSerializer_1.DataStoreSerializer(latestStore, latestHeight, latestHash).serialize();
217
+ // Cache updated store info
218
+ storeCoinCache.set(this.storeId, {
219
+ latestStore: serializedLatestStore,
220
+ latestHeight,
221
+ latestHash: latestHash.toString("hex"),
222
+ });
223
+ return { latestStore, latestHeight, latestHash };
224
+ }
225
+ catch {
226
+ // Return cached info if sync fails
227
+ const { latestStore, latestHeight, latestHash } = DataStoreSerializer_1.DataStoreSerializer.deserialize({
228
+ latestStore: cachedInfo.latestStore,
229
+ latestHeight: cachedInfo.latestHeight.toString(),
230
+ latestHash: cachedInfo.latestHash,
231
+ });
232
+ return {
233
+ latestStore,
234
+ latestHeight,
235
+ latestHash: latestHash,
236
+ };
237
+ }
238
+ }
239
+ // Use getCreationHeight to retrieve height and hash information
240
+ const { createdAtHeight, createdAtHash } = await this.getCreationHeight();
241
+ // Sync store from peer
242
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
243
+ const { latestStore, latestHeight } = await peer.syncStoreFromLauncherId(Buffer.from(this.storeId, "hex"), createdAtHeight, createdAtHash, false);
244
+ const latestHash = await peer.getHeaderHash(latestHeight);
245
+ // Serialize the latest store info for caching
246
+ const serializedLatestStore = new DataStoreSerializer_1.DataStoreSerializer(latestStore, latestHeight, latestHash).serialize();
247
+ // Cache the latest store info
248
+ storeCoinCache.set(this.storeId, {
249
+ latestStore: serializedLatestStore,
250
+ latestHeight,
251
+ latestHash: latestHash.toString("hex"),
252
+ });
253
+ return { latestStore, latestHeight, latestHash };
254
+ }
255
+ catch (error) {
256
+ console.trace("Failed to fetch coin info", error);
257
+ throw error;
258
+ }
259
+ }
260
+ async getCreationHeight() {
261
+ const defaultHeight = config_1.MIN_HEIGHT;
262
+ const defaultHash = Buffer.from(config_1.MIN_HEIGHT_HEADER_HASH, "hex");
263
+ // Initialize the FileCache for the height file
264
+ const fileCache = new FileCache_1.FileCache(`stores/${this.storeId}`);
265
+ // Try to retrieve the cached height information
266
+ const cachedHeightInfo = fileCache.get("height");
267
+ if (!cachedHeightInfo) {
268
+ // If no cache, return the default values
269
+ return { createdAtHeight: defaultHeight, createdAtHash: defaultHash };
270
+ }
271
+ // Parse the cached height and hash values
272
+ const { height, hash } = cachedHeightInfo;
273
+ return {
274
+ createdAtHeight: height || defaultHeight,
275
+ createdAtHash: Buffer.from(hash || config_1.MIN_HEIGHT_HEADER_HASH, "hex"),
276
+ };
277
+ }
278
+ async setCreationHeight(height, hash) {
279
+ const fileCache = new FileCache_1.FileCache(`stores/${this.storeId}`);
280
+ // Cache the height and hash information
281
+ fileCache.set("height", {
282
+ height,
283
+ hash: hash.toString("hex"),
284
+ });
285
+ }
286
+ async getRootHistory() {
287
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
288
+ const { createdAtHeight, createdAtHash } = await this.getCreationHeight();
289
+ const { rootHashes, rootHashesTimestamps } = await peer.syncStoreFromLauncherId(Buffer.from(this.storeId, "hex"), createdAtHeight, createdAtHash, true);
290
+ if (!rootHashes) {
291
+ return [];
292
+ }
293
+ return rootHashes.map((rootHash, index) => ({
294
+ root_hash: rootHash.toString("hex"),
295
+ timestamp: Number(rootHashesTimestamps?.[index].toString()),
296
+ }));
297
+ }
298
+ async getLocalRootHistory() {
299
+ const manifestFilePath = (0, config_1.getManifestFilePath)(this.storeId);
300
+ if (!fs_1.default.existsSync(manifestFilePath)) {
301
+ console.error("Manifest file not found", manifestFilePath);
302
+ return undefined;
303
+ }
304
+ const manifestHashes = fs_1.default
305
+ .readFileSync(manifestFilePath, "utf-8")
306
+ .split("\n")
307
+ .filter(Boolean);
308
+ return manifestHashes.map((rootHash) => ({
309
+ root_hash: rootHash,
310
+ timestamp: 0, // Timestamps are not yet included in the manifest
311
+ }));
312
+ }
313
+ async validate() {
314
+ const rootHistory = await this.getRootHistory();
315
+ const manifestFilePath = (0, config_1.getManifestFilePath)(this.storeId);
316
+ if (!fs_1.default.existsSync(manifestFilePath)) {
317
+ console.error("Manifest file not found", manifestFilePath);
318
+ return false;
319
+ }
320
+ const manifestHashes = fs_1.default
321
+ .readFileSync(manifestFilePath, "utf-8")
322
+ .split("\n")
323
+ .filter(Boolean);
324
+ if (manifestHashes.length > rootHistory.length) {
325
+ console.error("The store is corrupted: Manifest file has more hashes than the root history.");
326
+ return false;
327
+ }
328
+ if (rootHistory.length > manifestHashes.length) {
329
+ console.error("The store is not synced: Root history has more hashes than the manifest file.");
330
+ return false;
331
+ }
332
+ for (let i = 0; i < manifestHashes.length; i++) {
333
+ if (manifestHashes[i] !== rootHistory[i]?.root_hash) {
334
+ console.error(`Root hash mismatch at position ${i}: expected ${manifestHashes[i]} but found ${rootHistory[i]?.root_hash}`);
335
+ return false;
336
+ }
337
+ }
338
+ let filesIntegrityIntact = true;
339
+ for (const rootHash of manifestHashes) {
340
+ const datFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, `${rootHash}.dat`);
341
+ if (!fs_1.default.existsSync(datFilePath)) {
342
+ console.error(`Data file for root hash ${rootHash} not found`);
343
+ return false;
344
+ }
345
+ const datFileContent = JSON.parse(fs_1.default.readFileSync(datFilePath, "utf-8"));
346
+ if (datFileContent.root !== rootHash) {
347
+ console.error(`Root hash in data file does not match: ${datFileContent.root} !== ${rootHash}`);
348
+ return false;
349
+ }
350
+ for (const [fileKey, fileData] of Object.entries(datFileContent.files)) {
351
+ const integrityCheck = (0, utils_1.validateFileSha256)(fileData.sha256, path_1.default.join(config_1.STORE_PATH, this.storeId, "data"));
352
+ if (!integrityCheck) {
353
+ filesIntegrityIntact = false;
354
+ }
355
+ }
356
+ }
357
+ if (!filesIntegrityIntact) {
358
+ console.error("Store Corrupted: Data failed SHA256 validation.");
359
+ return false;
360
+ }
361
+ return true;
362
+ }
363
+ async getMetaData() {
364
+ const { latestStore } = await this.fetchCoinInfo();
365
+ return latestStore.metadata;
366
+ }
367
+ async isSynced() {
368
+ const rootHistory = await this.getRootHistory();
369
+ const manifestFilePath = (0, config_1.getManifestFilePath)(this.storeId);
370
+ if (!fs_1.default.existsSync(manifestFilePath)) {
371
+ return false;
372
+ }
373
+ const manifestHashes = fs_1.default
374
+ .readFileSync(manifestFilePath, "utf-8")
375
+ .split("\n")
376
+ .filter(Boolean);
377
+ return rootHistory.length === manifestHashes.length;
378
+ }
379
+ async hasMetaWritePermissions(publicSyntheticKey) {
380
+ const wallet = await Wallet_1.Wallet.load("default");
381
+ const { latestStore } = await this.fetchCoinInfo();
382
+ let ownerPuzzleHash = publicSyntheticKey
383
+ ? (0, datalayer_driver_1.syntheticKeyToPuzzleHash)(publicSyntheticKey)
384
+ : await wallet.getOwnerPuzzleHash();
385
+ const isStoreOwner = latestStore.ownerPuzzleHash.equals(ownerPuzzleHash);
386
+ const hasWriteAccess = latestStore.delegatedPuzzles.some((puzzle) => puzzle.adminInnerPuzzleHash?.equals(ownerPuzzleHash) ||
387
+ puzzle.writerInnerPuzzleHash?.equals(ownerPuzzleHash));
388
+ return isStoreOwner || hasWriteAccess;
389
+ }
390
+ async updateMetadata(metadata) {
391
+ const peer = await FullNodePeer_1.FullNodePeer.connect();
392
+ const wallet = await Wallet_1.Wallet.load("default");
393
+ const publicSyntheticKey = await wallet.getPublicSyntheticKey();
394
+ const { latestStore } = await this.fetchCoinInfo();
395
+ const updateStoreResponse = (0, datalayer_driver_1.updateStoreMetadata)(latestStore, metadata.rootHash, metadata.label, metadata.description, metadata.bytes, publicSyntheticKey, null, null);
396
+ const fee = await (0, coins_1.calculateFeeForCoinSpends)(peer, null);
397
+ const unspentCoins = await (0, coins_1.selectUnspentCoins)(peer, BigInt(0), fee);
398
+ const feeCoinSpends = await (0, datalayer_driver_1.addFee)(publicSyntheticKey, unspentCoins, updateStoreResponse.coinSpends.map((coinSpend) => (0, datalayer_driver_1.getCoinId)(coinSpend.coin)), fee);
399
+ const combinedCoinSpends = [
400
+ ...updateStoreResponse.coinSpends,
401
+ ...feeCoinSpends,
402
+ ];
403
+ const sig = (0, datalayer_driver_1.signCoinSpends)(combinedCoinSpends, [await wallet.getPrivateSyntheticKey()], false);
404
+ const err = await peer.broadcastSpend(combinedCoinSpends, [sig]);
405
+ if (err) {
406
+ throw new Error(err);
407
+ }
408
+ return updateStoreResponse.newStore;
409
+ }
410
+ async getFileSetForRootHash(rootHash) {
411
+ const datFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, `${rootHash}.dat`);
412
+ const datFileContent = JSON.parse(fs_1.default.readFileSync(datFilePath, "utf-8"));
413
+ const heightDatFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, "height.json");
414
+ const manifestFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, "manifest.dat");
415
+ const filesInvolved = [];
416
+ filesInvolved.push(manifestFilePath);
417
+ filesInvolved.push(datFilePath);
418
+ filesInvolved.push(heightDatFilePath);
419
+ for (const [fileKey, fileData] of Object.entries(datFileContent.files)) {
420
+ const filepath = path_1.default.join(config_1.STORE_PATH, this.storeId, "data", fileKey);
421
+ const filePath = (0, hashUtils_1.getFilePathFromSha256)(datFileContent.files[fileKey].sha256, path_1.default.join(config_1.STORE_PATH, this.storeId, "data"));
422
+ filesInvolved.push(filePath);
423
+ }
424
+ return filesInvolved;
425
+ }
426
+ getManifestHashes() {
427
+ const manifestFilePath = path_1.default.join(config_1.STORE_PATH, this.storeId, "manifest.dat");
428
+ return fs_1.default.existsSync(manifestFilePath)
429
+ ? fs_1.default.readFileSync(manifestFilePath, "utf-8").split("\n").filter(Boolean)
430
+ : [];
431
+ }
432
+ }
433
+ exports.DataStore = DataStore;
@@ -0,0 +1,52 @@
1
+ import { DataStore } from "datalayer-driver";
2
+ import { Buffer } from "buffer";
3
+ export declare class DataStoreSerializer {
4
+ private storeInfo;
5
+ private latestHeight;
6
+ private latestHash;
7
+ constructor(storeInfo: DataStore, latestHeight: number, latestHash: Buffer);
8
+ serialize(): {
9
+ coin: {
10
+ parentCoinInfo: string;
11
+ puzzleHash: string;
12
+ amount: string;
13
+ };
14
+ launcherId: string;
15
+ proof: {
16
+ lineageProof: {
17
+ parentParentCoinInfo: string;
18
+ parentInnerPuzzleHash: string;
19
+ parentAmount: string;
20
+ } | undefined;
21
+ eveProof: {
22
+ parentParentCoinInfo: string;
23
+ parentAmount: string;
24
+ } | undefined;
25
+ };
26
+ metadata: {
27
+ rootHash: string;
28
+ label: string | undefined;
29
+ description: string | undefined;
30
+ bytes: string | undefined;
31
+ };
32
+ ownerPuzzleHash: string;
33
+ delegatedPuzzles: {
34
+ adminInnerPuzzleHash: string | undefined;
35
+ writerInnerPuzzleHash: string | undefined;
36
+ oraclePaymentPuzzleHash: string | undefined;
37
+ oracleFee: string | undefined;
38
+ }[];
39
+ latestHeight: string;
40
+ latestHash: string;
41
+ };
42
+ static deserialize(data: {
43
+ latestStore: any;
44
+ latestHeight: string;
45
+ latestHash: string;
46
+ }): {
47
+ latestStore: DataStore;
48
+ latestHeight: number;
49
+ latestHash: Buffer;
50
+ };
51
+ }
52
+ //# sourceMappingURL=DataStoreSerializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataStoreSerializer.d.ts","sourceRoot":"","sources":["../../src/blockchain/DataStoreSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAKV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;gBAEf,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAOnE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAgDF,WAAW,CACvB,IAAI,EAAE;QACJ,WAAW,EAAE,GAAG,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,GACA;QACD,WAAW,EAAE,SAAS,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB;CAuEF"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataStoreSerializer = void 0;
4
+ const buffer_1 = require("buffer");
5
+ class DataStoreSerializer {
6
+ constructor(storeInfo, latestHeight, latestHash) {
7
+ this.storeInfo = storeInfo;
8
+ this.latestHeight = latestHeight;
9
+ this.latestHash = latestHash;
10
+ }
11
+ // Serialize the DataStore object and additional fields
12
+ serialize() {
13
+ return {
14
+ coin: {
15
+ parentCoinInfo: this.storeInfo.coin.parentCoinInfo.toString("hex"),
16
+ puzzleHash: this.storeInfo.coin.puzzleHash.toString("hex"),
17
+ amount: this.storeInfo.coin.amount.toString(),
18
+ },
19
+ launcherId: this.storeInfo.launcherId.toString("hex"),
20
+ proof: {
21
+ lineageProof: this.storeInfo.proof.lineageProof
22
+ ? {
23
+ parentParentCoinInfo: this.storeInfo.proof.lineageProof.parentParentCoinInfo.toString("hex"),
24
+ parentInnerPuzzleHash: this.storeInfo.proof.lineageProof.parentInnerPuzzleHash.toString("hex"),
25
+ parentAmount: this.storeInfo.proof.lineageProof.parentAmount.toString(),
26
+ }
27
+ : undefined,
28
+ eveProof: this.storeInfo.proof.eveProof
29
+ ? {
30
+ parentParentCoinInfo: this.storeInfo.proof.eveProof.parentParentCoinInfo.toString("hex"),
31
+ parentAmount: this.storeInfo.proof.eveProof.parentAmount.toString(),
32
+ }
33
+ : undefined,
34
+ },
35
+ metadata: {
36
+ rootHash: this.storeInfo.metadata.rootHash.toString("hex"),
37
+ label: this.storeInfo.metadata.label,
38
+ description: this.storeInfo.metadata.description,
39
+ bytes: this.storeInfo.metadata.bytes?.toString(),
40
+ },
41
+ ownerPuzzleHash: this.storeInfo.ownerPuzzleHash.toString("hex"),
42
+ delegatedPuzzles: this.storeInfo.delegatedPuzzles.map((puzzle) => ({
43
+ adminInnerPuzzleHash: puzzle.adminInnerPuzzleHash?.toString("hex"),
44
+ writerInnerPuzzleHash: puzzle.writerInnerPuzzleHash?.toString("hex"),
45
+ oraclePaymentPuzzleHash: puzzle.oraclePaymentPuzzleHash?.toString("hex"),
46
+ oracleFee: puzzle.oracleFee?.toString(),
47
+ })),
48
+ latestHeight: this.latestHeight.toString(),
49
+ latestHash: this.latestHash.toString("base64"), // Use base64 for Buffer
50
+ };
51
+ }
52
+ // Deserialize the data back into DataStore and associated fields
53
+ static deserialize(data) {
54
+ const coin = {
55
+ parentCoinInfo: buffer_1.Buffer.from(data.latestStore.coin.parentCoinInfo, "hex"),
56
+ puzzleHash: buffer_1.Buffer.from(data.latestStore.coin.puzzleHash, "hex"),
57
+ amount: BigInt(data.latestStore.coin.amount),
58
+ };
59
+ const proof = {
60
+ lineageProof: data.latestStore.proof.lineageProof
61
+ ? {
62
+ parentParentCoinInfo: buffer_1.Buffer.from(data.latestStore.proof.lineageProof.parentParentCoinInfo, "hex"),
63
+ parentInnerPuzzleHash: buffer_1.Buffer.from(data.latestStore.proof.lineageProof.parentInnerPuzzleHash, "hex"),
64
+ parentAmount: BigInt(data.latestStore.proof.lineageProof.parentAmount),
65
+ }
66
+ : undefined,
67
+ eveProof: data.latestStore.proof.eveProof
68
+ ? {
69
+ parentParentCoinInfo: buffer_1.Buffer.from(data.latestStore.proof.eveProof.parentParentCoinInfo, "hex"),
70
+ parentAmount: BigInt(data.latestStore.proof.eveProof.parentAmount),
71
+ }
72
+ : undefined,
73
+ };
74
+ const metadata = {
75
+ rootHash: buffer_1.Buffer.from(data.latestStore.metadata.rootHash, "hex"),
76
+ label: data.latestStore.metadata.label,
77
+ description: data.latestStore.metadata.description,
78
+ bytes: data.latestStore.metadata.bytes
79
+ ? BigInt(data.latestStore.metadata.bytes)
80
+ : undefined,
81
+ };
82
+ const delegatedPuzzles = data.latestStore.delegatedPuzzles.map((puzzle) => ({
83
+ adminInnerPuzzleHash: puzzle.adminInnerPuzzleHash
84
+ ? buffer_1.Buffer.from(puzzle.adminInnerPuzzleHash, "hex")
85
+ : undefined,
86
+ writerInnerPuzzleHash: puzzle.writerInnerPuzzleHash
87
+ ? buffer_1.Buffer.from(puzzle.writerInnerPuzzleHash, "hex")
88
+ : undefined,
89
+ oraclePaymentPuzzleHash: puzzle.oraclePaymentPuzzleHash
90
+ ? buffer_1.Buffer.from(puzzle.oraclePaymentPuzzleHash, "hex")
91
+ : undefined,
92
+ oracleFee: puzzle.oracleFee ? BigInt(puzzle.oracleFee) : undefined,
93
+ }));
94
+ const dataStoreInfo = {
95
+ coin,
96
+ launcherId: buffer_1.Buffer.from(data.latestStore.launcherId, "hex"),
97
+ proof,
98
+ metadata,
99
+ ownerPuzzleHash: buffer_1.Buffer.from(data.latestStore.ownerPuzzleHash, "hex"),
100
+ delegatedPuzzles,
101
+ };
102
+ return {
103
+ latestStore: dataStoreInfo,
104
+ latestHeight: parseInt(data.latestHeight, 10),
105
+ latestHash: buffer_1.Buffer.from(data.latestHash, "base64"), // Deserialize from base64
106
+ };
107
+ }
108
+ }
109
+ exports.DataStoreSerializer = DataStoreSerializer;
@@ -0,0 +1,24 @@
1
+ import { Peer } from "datalayer-driver";
2
+ export declare class FullNodePeer {
3
+ private static cachedPeer;
4
+ private static memoizedFetchNewPeerIPs;
5
+ private peer;
6
+ private constructor();
7
+ static connect(): Promise<Peer>;
8
+ private static isPortReachable;
9
+ private static isValidIpAddress;
10
+ /**
11
+ * Retrieves the TRUSTED_FULLNODE IP from the environment
12
+ * and verifies if it is a valid IP address.
13
+ *
14
+ * @returns {string | null} The valid IP address or null if invalid
15
+ */
16
+ private static getTrustedFullNode;
17
+ private static fetchNewPeerIPs;
18
+ private static getPeerIPs;
19
+ private static createPeerProxy;
20
+ private static getBestPeer;
21
+ getPeer(): Peer;
22
+ static waitForConfirmation(parentCoinInfo: Buffer): Promise<boolean>;
23
+ }
24
+ //# sourceMappingURL=FullNodePeer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAmBxC,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkD;IAC3E,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA0B;IAChE,OAAO,CAAC,IAAI,CAAO;IAQnB,OAAO;WAIa,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5C,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;mBASZ,eAAe;mBAiDf,UAAU;IAyB/B,OAAO,CAAC,MAAM,CAAC,eAAe;mBAgDT,WAAW;IAgGzB,OAAO,IAAI,IAAI;WAIF,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAwBpB"}