@ethernity-cloud/sdk-js 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +185 -0
  3. package/build.js +22 -0
  4. package/init.js +301 -0
  5. package/nodenithy/build/las/Dockerfile +5 -0
  6. package/nodenithy/build/securelock/Dockerfile.tmpl +65 -0
  7. package/nodenithy/build/securelock/scripts/binary-fs-build.sh +28 -0
  8. package/nodenithy/build/securelock/src/.env +3 -0
  9. package/nodenithy/build/securelock/src/etny_crypto.js +201 -0
  10. package/nodenithy/build/securelock/src/etny_exec.js +65 -0
  11. package/nodenithy/build/securelock/src/image_registry_abi.js +808 -0
  12. package/nodenithy/build/securelock/src/models.js +261 -0
  13. package/nodenithy/build/securelock/src/package.json +40 -0
  14. package/nodenithy/build/securelock/src/pox_abi.js +1491 -0
  15. package/nodenithy/build/securelock/src/securelock.js.tmpl +421 -0
  16. package/nodenithy/build/securelock/src/swift_stream_service.js +147 -0
  17. package/nodenithy/build/securelock/src/task_status.js +15 -0
  18. package/nodenithy/build/securelock/src/wallet.js +29 -0
  19. package/nodenithy/build/squash/Dockerfile +7 -0
  20. package/nodenithy/build/trustedzone/Dockerfile.tmpl +57 -0
  21. package/nodenithy/build/trustedzone/scripts/binary-fs-build.sh +22 -0
  22. package/nodenithy/build/trustedzone/src/.env +3 -0
  23. package/nodenithy/build/trustedzone/src/etny_crypto.js +202 -0
  24. package/nodenithy/build/trustedzone/src/etny_exec.js +54 -0
  25. package/nodenithy/build/trustedzone/src/image_registry_abi.js +808 -0
  26. package/nodenithy/build/trustedzone/src/models.js +261 -0
  27. package/nodenithy/build/trustedzone/src/package.json +40 -0
  28. package/nodenithy/build/trustedzone/src/pox_abi.js +1491 -0
  29. package/nodenithy/build/trustedzone/src/swift_stream_service.js +147 -0
  30. package/nodenithy/build/trustedzone/src/task_status.js +15 -0
  31. package/nodenithy/build/trustedzone/src/test.js +44 -0
  32. package/nodenithy/build/trustedzone/src/trustedzone.js.tmpl +508 -0
  33. package/nodenithy/build/trustedzone/src/wallet.js +28 -0
  34. package/nodenithy/build/validator/Dockerfile +58 -0
  35. package/nodenithy/build/validator/package-lock.json +6 -0
  36. package/nodenithy/build/validator/scripts/binary-fs-build.sh +19 -0
  37. package/nodenithy/build/validator/src/.env +3 -0
  38. package/nodenithy/build/validator/src/cert.pem +5 -0
  39. package/nodenithy/build/validator/src/etny_crypto.js +204 -0
  40. package/nodenithy/build/validator/src/etny_exec.js +52 -0
  41. package/nodenithy/build/validator/src/image_registry_abi.js +808 -0
  42. package/nodenithy/build/validator/src/key.pem +6 -0
  43. package/nodenithy/build/validator/src/models.js +261 -0
  44. package/nodenithy/build/validator/src/package-lock.json +2498 -0
  45. package/nodenithy/build/validator/src/package.json +40 -0
  46. package/nodenithy/build/validator/src/pox_abi.js +1491 -0
  47. package/nodenithy/build/validator/src/swift_stream_service.js +147 -0
  48. package/nodenithy/build/validator/src/task_status.js +15 -0
  49. package/nodenithy/build/validator/src/test.js +44 -0
  50. package/nodenithy/build/validator/src/trustedzone.js +613 -0
  51. package/nodenithy/build/validator/src/validator_abi.js +834 -0
  52. package/nodenithy/build/validator/src/wallet.js +28 -0
  53. package/nodenithy/build.js +184 -0
  54. package/nodenithy/build.mjs +179 -0
  55. package/nodenithy/build.sh +161 -0
  56. package/nodenithy/ipfs.js +135 -0
  57. package/nodenithy/ipfs.mjs +551 -0
  58. package/nodenithy/public/favicon.ico +0 -0
  59. package/nodenithy/public/index.html +43 -0
  60. package/nodenithy/public/logo192.png +0 -0
  61. package/nodenithy/public/logo512.png +0 -0
  62. package/nodenithy/public/manifest.json +25 -0
  63. package/nodenithy/public/robots.txt +3 -0
  64. package/nodenithy/run/__pycache__/swift_stream_service.cpython-312.pyc +0 -0
  65. package/nodenithy/run/app/input.txt +4 -0
  66. package/nodenithy/run/app/payload.js +4 -0
  67. package/nodenithy/run/docker-compose-final.yml.tmpl +65 -0
  68. package/nodenithy/run/docker-compose-swift-stream.yml +17 -0
  69. package/nodenithy/run/docker-compose.yml.tmpl +76 -0
  70. package/nodenithy/run/etny-securelock-test.yaml.tpl +46 -0
  71. package/nodenithy/run/etny-trustedzone-test.yaml.tpl +45 -0
  72. package/nodenithy/run/git.sh +22 -0
  73. package/nodenithy/run/image_registry.abi +1 -0
  74. package/nodenithy/run/image_registry.js +372 -0
  75. package/nodenithy/run/image_registry.py +327 -0
  76. package/nodenithy/run/image_registry_runner.py +71 -0
  77. package/nodenithy/run/ipfs.sh +58 -0
  78. package/nodenithy/run/ipfs_pre.sh +75 -0
  79. package/nodenithy/run/public_key_service.js +90 -0
  80. package/nodenithy/run/public_key_service.py +107 -0
  81. package/nodenithy/run/swift_stream_service.py +212 -0
  82. package/nodenithy/run/swiftstream.py +37 -0
  83. package/nodenithy/run/swiftstream1.py +27 -0
  84. package/nodenithy/run.js +538 -0
  85. package/nodenithy/run.sh +277 -0
  86. package/nodenithy/scripts/build-ipfs-upload.sh +23 -0
  87. package/nodenithy/scripts/build.sh +40 -0
  88. package/nodenithy/scripts/ipfs-daemon.sh +7 -0
  89. package/nodenithy/scripts/run.sh +50 -0
  90. package/nodenithy/src/App.css +57 -0
  91. package/nodenithy/src/ec_helloworld_example.js +64 -0
  92. package/nodenithy/src/index.css +13 -0
  93. package/nodenithy/src/index.js +17 -0
  94. package/nodenithy/src/preStart.js +45 -0
  95. package/nodenithy/src/preStart.mjs +57 -0
  96. package/nodenithy/src/reportWebVitals.js +13 -0
  97. package/nodenithy/src/serverless/backend.js +5 -0
  98. package/package.json +48 -0
  99. package/postinstall.js +34 -0
  100. package/publish.js +126 -0
  101. package/pynithy/build/docker-compose.yml +68 -0
  102. package/pynithy/build/las/Dockerfile +11 -0
  103. package/pynithy/build/las/src/etny_entrypoint.sh +6 -0
  104. package/pynithy/build/las/src/las_entrypoint.sh +26 -0
  105. package/pynithy/build/scripts/binary-fs-build.sh +28 -0
  106. package/pynithy/build/securelock/Dockerfile.tmpl +78 -0
  107. package/pynithy/build/securelock/scripts/binary-fs-build.sh +41 -0
  108. package/pynithy/build/securelock/src/app/.env +5 -0
  109. package/pynithy/build/securelock/src/app/cert1-ca1-clean.crt +10 -0
  110. package/pynithy/build/securelock/src/app/cert1-ca1-clean.key +6 -0
  111. package/pynithy/build/securelock/src/app/enclave_pub_cert.pem +10 -0
  112. package/pynithy/build/securelock/src/app/input.txt +1 -0
  113. package/pynithy/build/securelock/src/app/payload.py +25 -0
  114. package/pynithy/build/securelock/src/app/public-cert-clean.pem +10 -0
  115. package/pynithy/build/securelock/src/app/result.txt +1 -0
  116. package/pynithy/build/securelock/src/app/transaction.txt +1 -0
  117. package/pynithy/build/securelock/src/etny_crypto.py +167 -0
  118. package/pynithy/build/securelock/src/etny_exec.py +79 -0
  119. package/pynithy/build/securelock/src/image_registry.abi +1 -0
  120. package/pynithy/build/securelock/src/key_generation.py +17 -0
  121. package/pynithy/build/securelock/src/models.py +176 -0
  122. package/pynithy/build/securelock/src/pox.abi +1489 -0
  123. package/pynithy/build/securelock/src/securelock.py.tmpl +411 -0
  124. package/pynithy/build/securelock/src/swift_stream_service.py +186 -0
  125. package/pynithy/build/trustedzone/Dockerfile.tmpl +56 -0
  126. package/pynithy/build/trustedzone/scripts/binary-fs-build.sh +32 -0
  127. package/pynithy/build/trustedzone/src/app/.env +5 -0
  128. package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.crt +10 -0
  129. package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.key +6 -0
  130. package/pynithy/build/trustedzone/src/app/enclave_pub_cert.pem +10 -0
  131. package/pynithy/build/trustedzone/src/app/input.txt +1 -0
  132. package/pynithy/build/trustedzone/src/app/payload.py +25 -0
  133. package/pynithy/build/trustedzone/src/app/public-cert-clean.pem +10 -0
  134. package/pynithy/build/trustedzone/src/app/result.txt +1 -0
  135. package/pynithy/build/trustedzone/src/app/securelock.crt +10 -0
  136. package/pynithy/build/trustedzone/src/app/transaction.txt +1 -0
  137. package/pynithy/build/trustedzone/src/app/trustedzone.crt +10 -0
  138. package/pynithy/build/trustedzone/src/etny_crypto.py +188 -0
  139. package/pynithy/build/trustedzone/src/etny_exec.py +56 -0
  140. package/pynithy/build/trustedzone/src/formatter.py +42 -0
  141. package/pynithy/build/trustedzone/src/image_registry.abi +1 -0
  142. package/pynithy/build/trustedzone/src/key_generation.py +17 -0
  143. package/pynithy/build/trustedzone/src/models.py +176 -0
  144. package/pynithy/build/trustedzone/src/pox.abi +1489 -0
  145. package/pynithy/build/trustedzone/src/swift_stream_service.py +186 -0
  146. package/pynithy/build/trustedzone/src/trustedzone.py.tmpl +460 -0
  147. package/pynithy/build.mjs +179 -0
  148. package/pynithy/docker-compose.yml +0 -0
  149. package/pynithy/ipfs.mjs +244 -0
  150. package/pynithy/public/favicon.ico +0 -0
  151. package/pynithy/public/index.html +43 -0
  152. package/pynithy/public/logo192.png +0 -0
  153. package/pynithy/public/logo512.png +0 -0
  154. package/pynithy/public/manifest.json +25 -0
  155. package/pynithy/public/robots.txt +3 -0
  156. package/pynithy/run/certs/cert.pem +31 -0
  157. package/pynithy/run/certs/challenge.crt +10 -0
  158. package/pynithy/run/certs/key.pem +52 -0
  159. package/pynithy/run/docker-compose-final.yml +59 -0
  160. package/pynithy/run/docker-compose-final.yml.tmpl +59 -0
  161. package/pynithy/run/docker-compose-swift-stream.yml +27 -0
  162. package/pynithy/run/docker-compose-swift-stream.yml.tmpl +27 -0
  163. package/pynithy/run/docker-compose.yml +55 -0
  164. package/pynithy/run/docker-compose.yml.tmpl +55 -0
  165. package/pynithy/run/etny-pynity-test.yaml.tpl +46 -0
  166. package/pynithy/run/etny-securelock-test.yaml.tpl +46 -0
  167. package/pynithy/run/etny-trustedzone-test.yaml.tpl +46 -0
  168. package/pynithy/run/git.sh +22 -0
  169. package/pynithy/run/image_registry.abi +1 -0
  170. package/pynithy/run/image_registry.js +372 -0
  171. package/pynithy/run/image_registry.py +139 -0
  172. package/pynithy/run/image_registry_runner.py +45 -0
  173. package/pynithy/run/ipfs.sh +89 -0
  174. package/pynithy/run/public_key_service.js +90 -0
  175. package/pynithy/run/swiftstream.py +28 -0
  176. package/pynithy/run.js +538 -0
  177. package/pynithy/src/App.css +57 -0
  178. package/pynithy/src/ec_helloworld_example.js +64 -0
  179. package/pynithy/src/index.css +13 -0
  180. package/pynithy/src/index.js +17 -0
  181. package/pynithy/src/preStart.mjs +57 -0
  182. package/pynithy/src/reportWebVitals.js +13 -0
  183. package/pynithy/src/serverless/__init__.py +0 -0
  184. package/pynithy/src/serverless/backend.py +2 -0
@@ -0,0 +1,135 @@
1
+ import { create } from 'ipfs-http-client';
2
+ import { delay, getRetryDelay } from './utils';
3
+ import { ECError } from './enums';
4
+
5
+ let ipfs = null;
6
+ const writeFile = promisify(fs.writeFile);
7
+
8
+ export const initialize = (host, protocol, port, token) => {
9
+ if (host.search('http') !== -1) {
10
+ ipfs = create(host);
11
+ } else if (token === '') {
12
+ ipfs = create({
13
+ host,
14
+ protocol,
15
+ port
16
+ });
17
+ } else {
18
+ // example of authorization headers
19
+ // headers: {
20
+ // authorization: 'Bearer ' + TOKEN
21
+ // }
22
+ // const auth =
23
+ // 'Basic ' + Buffer.from(INFURA_ID + ':' + INFURA_SECRET_KEY).toString('base64');
24
+ ipfs = create({
25
+ host,
26
+ protocol,
27
+ port,
28
+ headers: { authorization: token }
29
+ });
30
+ }
31
+ };
32
+
33
+ export const uploadToIPFS = async (code) => {
34
+ try {
35
+ const response = await ipfs.add(code);
36
+ return response.path;
37
+ } catch (e) {
38
+ console.log(e);
39
+ return null;
40
+ }
41
+ };
42
+
43
+ export const uploadFileToIPFS = async (path) => {
44
+ try {
45
+ const response = await ipfs.add(path);
46
+ return response.path;
47
+ } catch (e) {
48
+ console.log(e);
49
+ return null;
50
+ }
51
+ };
52
+
53
+ export const uploadFolderToIPFS = async (path) => {
54
+ try {
55
+ const response = await ipfs.add(path, { recursive: true });
56
+ return response.path;
57
+ } catch (e) {
58
+ console.log(e);
59
+ return null;
60
+ }
61
+ };
62
+
63
+ // export const getFromIPFS = async (hash) => {
64
+ // let res = '';
65
+ // try {
66
+ // // eslint-disable-next-line no-restricted-syntax
67
+ // for await (const file of ipfs.cat(hash)) {
68
+ // res += new TextDecoder().decode(file.buffer);
69
+ // }
70
+ //
71
+ // return res;
72
+ // } catch (error) {
73
+ // console.error(error.message);
74
+ // await delay(2000);
75
+ // return getFromIPFS(hash);
76
+ // }
77
+ // };
78
+
79
+ export const getFromIPFS = async (hash, filePath, maxRetries = process.env.REACT_APP_IPFS_RETRIES || 5) => {
80
+ let res = '';
81
+ let retryCount = 0;
82
+
83
+ while (retryCount < maxRetries) {
84
+ try {
85
+ // eslint-disable-next-line no-restricted-syntax,no-await-in-loop
86
+ for await (const file of ipfs.cat(hash)) {
87
+ res += new TextDecoder().decode(file.buffer);
88
+ }
89
+
90
+ // Save the content to a file
91
+ await writeFile(filePath, res);
92
+ return res;
93
+ } catch (error) {
94
+ console.error(error.message);
95
+ retryCount += 1;
96
+
97
+ if (retryCount < maxRetries) {
98
+ // eslint-disable-next-line no-await-in-loop
99
+ await delay(getRetryDelay(retryCount));
100
+ // eslint-disable-next-line no-continue
101
+ continue;
102
+ } else {
103
+ throw new Error(ECError.IPFS_DOWNLOAD_ERROR);
104
+ }
105
+ }
106
+ }
107
+ };
108
+
109
+ export const getContentFromIPFS = async (hash, maxRetries = process.env.REACT_APP_IPFS_RETRIES || 5) => {
110
+ let res = '';
111
+ let retryCount = 0;
112
+
113
+ while (retryCount < maxRetries) {
114
+ try {
115
+ // eslint-disable-next-line no-restricted-syntax,no-await-in-loop
116
+ for await (const file of ipfs.cat(hash)) {
117
+ res += new TextDecoder().decode(file.buffer);
118
+ }
119
+
120
+ return res;
121
+ } catch (error) {
122
+ console.error(error.message);
123
+ retryCount += 1;
124
+
125
+ if (retryCount < maxRetries) {
126
+ // eslint-disable-next-line no-await-in-loop
127
+ await delay(getRetryDelay(retryCount));
128
+ // eslint-disable-next-line no-continue
129
+ continue;
130
+ } else {
131
+ throw new Error(ECError.IPFS_DOWNLOAD_ERROR);
132
+ }
133
+ }
134
+ }
135
+ };
@@ -0,0 +1,551 @@
1
+ // ipfsClient.js
2
+ import { create, globSource } from 'kubo-rpc-client';
3
+ import { promisify } from 'util';
4
+ import fs from 'fs';
5
+ import { Command } from 'commander';
6
+ import { promises as fss } from 'fs';
7
+ import path from 'path';
8
+ import { MultiBar, Presets } from 'cli-progress';
9
+
10
+ const program = new Command();
11
+ const writeFile = promisify(fs.writeFile);
12
+ const delay = (ms) => new Promise((res) => setTimeout(res, ms));
13
+ const getRetryDelay = (retryCount, baseDelay = 1) => baseDelay * 2 ** retryCount;
14
+
15
+ let ipfs = null;
16
+
17
+ const initialize = (host, protocol, port, token) => {
18
+ if (host.search('http') !== -1) {
19
+ ipfs = create(host); //{ timeout: '4m' }
20
+ } else if (token === '') {
21
+ ipfs = create({
22
+ host,
23
+ protocol,
24
+ port,
25
+ // timeout: '4m'
26
+ });
27
+ } else {
28
+ ipfs = create({
29
+ host,
30
+ protocol,
31
+ port,
32
+ headers: { authorization: token },
33
+ // timeout: '4m'
34
+ });
35
+ }
36
+ };
37
+
38
+ const uploadFileToIPFS = async (filePath) => {
39
+ try {
40
+ const fileContent = await fss.readFile(filePath);
41
+ const response = await ipfs.add({ path: filePath, content: fileContent });
42
+ await fss.writeFile(`./IPFS_DOCKER_COMPOSE_HASH.ipfs`, response.cid.toString());
43
+ return response.cid.toString();
44
+ } catch (e) {
45
+ console.error();
46
+ return "Failed to upload file to IPFS, please try again.";
47
+ }
48
+ };
49
+
50
+ const uploadFolderToIPFS2 = async (path) => {
51
+ try {
52
+ console.log(`Uploading folder to IPFS: ${path}`);
53
+ const response = await ipfs.add(path, { pin: true , recursive: true }).catch((e) => console.log(e));
54
+ // console.log(JSON.stringify(response, null, 2));
55
+ const { cid } = response;
56
+ // while (true) {
57
+ // const { cid } = response;
58
+ // if (response.path) {
59
+ // break;
60
+ // }
61
+ // // console.log(`Added file: ${cid}`);
62
+ // delay(50000);
63
+ // }
64
+ // console.log(`response: ${response}`);
65
+ return cid;
66
+ } catch (e) {
67
+ console.log(e);
68
+ return null;
69
+ }
70
+ };
71
+
72
+ const MAX_BATCH_SIZE = 20 * 1024 * 1024; // 100MB
73
+
74
+ const uploadFolderToIPFSBatch = async (folderPath) => {
75
+ try {
76
+ const files = [];
77
+ const readDirectory = (dir) => {
78
+ fs.readdirSync(dir).forEach((file) => {
79
+ const fullPath = path.join(dir, file);
80
+ if (fs.statSync(fullPath).isDirectory()) {
81
+ readDirectory(fullPath);
82
+ } else {
83
+ files.push({
84
+ path: path.relative(folderPath, fullPath),
85
+ content: fs.readFileSync(fullPath),
86
+ size: fs.statSync(fullPath).size
87
+ });
88
+ }
89
+ });
90
+ };
91
+
92
+ readDirectory(folderPath);
93
+ console.log(`Uploading folder to IPFS: ${folderPath}`);
94
+ console.log(`Number of files: ${files.length}`);
95
+
96
+ const ipfsOptions = {
97
+ wrapWithDirectory: false,
98
+ pin: true,
99
+ progress: (prog) => console.log(`Added ${prog / 1024 / 1024} MB`),
100
+ timeout: '2m'
101
+ };
102
+
103
+ const allCids = [];
104
+ let currentBatch = [];
105
+ let currentBatchSize = 0;
106
+
107
+ for (const file of files) {
108
+ if (file.size > MAX_BATCH_SIZE) {
109
+ // Upload large files individually
110
+ console.log(`Uploading large file individually: ${file.path}, size: ${file.size / 1024 / 1024} MB`);
111
+ for await (const result of ipfs.addAll([file], ipfsOptions)) {
112
+ allCids.push(result.cid);
113
+ }
114
+ } else {
115
+ // Add file to current batch
116
+ if (currentBatchSize + file.size > MAX_BATCH_SIZE) {
117
+ // await delay(30000);
118
+ // Upload current batch, display in mb
119
+ console.log(`Uploading batch of size ${currentBatchSize / 1024 / 1024} MB`);
120
+ for await (const result of ipfs.addAll(currentBatch, ipfsOptions)) {
121
+ allCids.push(result.cid);
122
+ }
123
+ // Reset batch
124
+ currentBatch = [];
125
+ currentBatchSize = 0;
126
+ }
127
+ currentBatch.push(file);
128
+ currentBatchSize += file.size;
129
+ }
130
+ }
131
+
132
+ // Upload any remaining files in the last batch
133
+ if (currentBatch.length > 0) {
134
+ console.log(`Uploading final batch of size ${currentBatchSize / 1024 / 1024} MB`);
135
+ for await (const result of ipfs.addAll(currentBatch, ipfsOptions)) {
136
+ allCids.push(result.cid);
137
+ }
138
+ }
139
+
140
+ // Wrap all files into a single directory
141
+ const directory = await ipfs.addAll(allCids.map(cid => ({ path: cid.toString(), content: ipfs.cat(cid) })), {
142
+ wrapWithDirectory: true,
143
+ pin: true,
144
+ timeout: '2m'
145
+ });
146
+
147
+ console.log(`response: ${JSON.stringify(directory, null, 2)}`);
148
+ return directory.cid;
149
+ } catch (e) {
150
+ console.error(e);
151
+ return "error";
152
+ }
153
+ };
154
+
155
+ const uploadFolderToIPFS3 = async (folderPath) => {
156
+ try {
157
+ const files = [];
158
+
159
+ const readDirectory = (dir) => {
160
+ const items = fs.readdirSync(dir);
161
+ items.forEach((item) => {
162
+ const fullPath = path.join(dir, item);
163
+ const stats = fs.statSync(fullPath);
164
+ if (stats.isDirectory()) {
165
+ readDirectory(fullPath);
166
+ } else {
167
+ files.push({
168
+ path: path.relative(folderPath, fullPath),
169
+ content: fs.readFileSync(fullPath)
170
+ });
171
+ }
172
+ });
173
+ };
174
+
175
+ readDirectory(folderPath);
176
+ console.log(`Uploading folder to IPFS: ${folderPath}`);
177
+ // console.log(`Files: ${JSON.stringify(files[0], null, 2)}`);
178
+ console.log(`number of files: ${files.length}`);
179
+ // const response = await ipfs.addAll(files, { wrapWithDirectory: true, pin: true, timeout: 600000, progress: (prog) => console.log(`Added ${prog} bytes`)});
180
+ // const response = await ipfs.addAll(files);
181
+ for await (const file of ipfs.addAll(files, { wrapWithDirectory: true, pin: true, timeout: 600000, progress: (prog) => console.log(`Added ${prog} bytes`)})) {
182
+ console.log(file)
183
+ }
184
+ console.log(`response: ${JSON.stringify(response, null, 2)}`);
185
+ return response.cid;
186
+ } catch (e) {
187
+ console.log(e);
188
+ return "error";
189
+ }
190
+ };
191
+
192
+ // const uploadFolderToIPFS = async (folderPath) => {
193
+ // try {
194
+ // const addedFiles = [nume, continut];
195
+ // const ipfsOptions = {
196
+ // wrapWithDirectory: true,
197
+ // pin: true,
198
+ // progress: (prog) => console.log(`Added ${prog / 1024 / 1024} MB`),
199
+ // timeout: '5m'
200
+ // };
201
+ // console.log(`Uploading folder to IPFS: ${folderPath}`);
202
+ // for await (const file of ipfs.addAll(globSource(folderPath, '**/*'),{ ...ipfsOptions })) {
203
+ // addedFiles.push({
204
+ // cid: file.cid.toString(),
205
+ // path: file.path,
206
+ // size: file.size,
207
+ // });
208
+ // }
209
+
210
+ // // for await (const file of ipfs.addAll(
211
+ // // globSource(folderPath, '**/*', { hidden: true }),
212
+ // // { ...ipfsOptions, fileImportConcurrency: 1 }
213
+ // // )) {
214
+ // // // export each added file to a json file
215
+ // // await writeFile(`./files/addedFile${file.cid.toString()}.json`, JSON.stringify(file, null, 2));
216
+ // // console.log(`Added file: ${file.path} with CID: ${file.cid.toString()}`);
217
+ // // addedFiles.push({
218
+ // // cid: file.cid.toString(),
219
+ // // path: file.path,
220
+ // // size: file.size,
221
+ // // });
222
+ // // }
223
+ // // // export added files to a json file
224
+ // // await writeFile('addedFiles, json', JSON.stringify(addedFiles, null, 2));
225
+
226
+ // // console.log("addedFiles: ", JSON.stringify(addedFiles, null, 2));
227
+
228
+ // // Return the CID of the root directory
229
+ // return addedFiles.find(file => file.path === '').cid;
230
+ // // return;
231
+ // } catch (e) {
232
+ // console.error(e);
233
+ // return "err";
234
+ // }
235
+ // };
236
+
237
+ const uploadFolderToIPFS = async (folderPath) => {
238
+ try {
239
+ const addedFiles = [];
240
+ const ipfsOptions = {
241
+ wrapWithDirectory: true,
242
+ pin: true,
243
+ hidden: true,
244
+ timeout: '5m'
245
+ };
246
+
247
+ console.log(`Uploading folder to IPFS: ${folderPath}`);
248
+
249
+ const multiBar = new MultiBar({
250
+ clearOnComplete: false,
251
+ hideCursor: true,
252
+ format: 'Progress [{bar}] {percentage}% | {value}/{total} MB'
253
+ }, Presets.shades_classic);
254
+
255
+ const files = [];
256
+ const readDirectory = (dir) => {
257
+ fs.readdirSync(dir).forEach((file) => {
258
+ const fullPath = path.join(dir, file);
259
+ if (fs.statSync(fullPath).isDirectory()) {
260
+ readDirectory(fullPath);
261
+ } else {
262
+ files.push({
263
+ path: path.relative(folderPath, fullPath),
264
+ size: fs.statSync(fullPath).size
265
+ });
266
+ }
267
+ });
268
+ };
269
+
270
+ readDirectory(folderPath);
271
+ const totalSize = files.reduce((acc, file) => acc + file.size, 0);
272
+
273
+ const progressBar = multiBar.create(totalSize / 1024 / 1024, 0);
274
+
275
+ for await (const file of ipfs.addAll(files.map(file => ({
276
+ path: file.path.replace(/\\/g, '/'),
277
+ content: fs.createReadStream(path.join(folderPath, file.path))
278
+ })), { ...ipfsOptions })) {
279
+ addedFiles.push({
280
+ cid: file.cid.toString(),
281
+ path: file.path,
282
+ size: file.size,
283
+ });
284
+ progressBar.increment(file.size / 1024 / 1024);
285
+ }
286
+ progressBar.update(totalSize / 1024 / 1024);
287
+ multiBar.stop();
288
+ const _hash = addedFiles.find(file => file.path === '').cid;
289
+ // Return the CID of the root directory
290
+ await fss.writeFile(`./IPFS_HASH.ipfs`, _hash);
291
+ return _hash;
292
+ } catch (e) {
293
+ return "Upload failed.";
294
+ }
295
+ };
296
+
297
+ const getFromIPFS = async (hhash, filePath, maxRetries = process.env.REACT_APP_IPFS_RETRIES || 5) => {
298
+ let res = '';
299
+ let retryCount = 0;
300
+ // console.log('Downloading file from IPFS...');
301
+ // console.log(`Hash: ${hhash}`);
302
+ // console.log(`Max Retries: ${maxRetries}`);
303
+
304
+ while (retryCount < maxRetries) {
305
+ try {
306
+ for await (const file of ipfs.cat(hhash)) {
307
+ res += new TextDecoder().decode(file.buffer);
308
+ }
309
+ await writeFile(filePath, res);
310
+ return;
311
+ } catch (error) {
312
+ console.error(`Error: ${error.message}`);
313
+ retryCount += 1;
314
+
315
+ if (retryCount < maxRetries) {
316
+ console.log(`Retrying... (${retryCount}/${maxRetries})`);
317
+ await delay(getRetryDelay(retryCount));
318
+ continue;
319
+ } else {
320
+ throw new Error("ECError.IPFS_DOWNLOAD_ERROR");
321
+ }
322
+ }
323
+ }
324
+ };
325
+
326
+ const downloadFromIPFS = async (hash, folderPath, maxRetries = process.env.REACT_APP_IPFS_RETRIES || 5) => {
327
+ let retryCount = 0;
328
+ console.log(`Hash: ${hash}`);
329
+ console.log(`Folder Path: ${folderPath}`);
330
+ console.log(`Max Retries: ${maxRetries}`);
331
+
332
+ while (retryCount < maxRetries) {
333
+ try {
334
+ for await (const file of ipfs.get(hash)) {
335
+ console.log(`file: ${JSON.stringify(file, null, 2)}`);
336
+ const filePathToWrite = path.join(folderPath, file.path);
337
+
338
+ if (file.type === 'dir') {
339
+ await fs.mkdir(filePathToWrite, { recursive: true });
340
+ } else {
341
+ const content = new TextDecoder().decode(file.content);
342
+ await fs.mkdir(path.dirname(filePathToWrite), { recursive: true });
343
+ await fs.writeFile(filePathToWrite, content);
344
+ }
345
+ }
346
+ console.log(`Download complete. Files saved to ${folderPath}`);
347
+ return;
348
+ } catch (error) {
349
+ console.error(`Error: ${error.message}`);
350
+ retryCount += 1;
351
+
352
+ if (retryCount < maxRetries) {
353
+ console.log(`Retrying... (${retryCount}/${maxRetries})`);
354
+ await delay(getRetryDelay(retryCount));
355
+ continue;
356
+ } else {
357
+ throw new Error("ECError.IPFS_DOWNLOAD_ERROR");
358
+ }
359
+ }
360
+ }
361
+ };
362
+
363
+ const downloadFolderFromIPFS = async (cid, outputPath) => {
364
+ try {
365
+ // const ipfs = create({ url: 'http://localhost:5001' }); // Adjust the IPFS API URL if necessary
366
+
367
+ console.log(`Downloading folder from IPFS: ${cid}`);
368
+
369
+ const multiBar = new MultiBar({
370
+ clearOnComplete: false,
371
+ hideCursor: true,
372
+ format: 'Progress [{bar}] {percentage}% | {value}/{total} MB'
373
+ }, Presets.shades_classic);
374
+
375
+ const files = [];
376
+ for await (const file of ipfs.get(cid)) {
377
+ console.log(`file: ${JSON.stringify(file, null, 2)}`);
378
+ if (!file.content) continue;
379
+
380
+ const filePath = path.join(outputPath, file.path);
381
+ const dir = path.dirname(filePath);
382
+
383
+ if (!fs.existsSync(dir)) {
384
+ fs.mkdirSync(dir, { recursive: true });
385
+ }
386
+
387
+ const writeStream = fs.createWriteStream(filePath);
388
+ const progressBar = multiBar.create(file.size / 1024 / 1024, 0);
389
+
390
+ for await (const chunk of file.content) {
391
+ writeStream.write(chunk);
392
+ progressBar.increment(chunk.length / 1024 / 1024);
393
+ }
394
+
395
+ writeStream.end();
396
+ progressBar.update(file.size / 1024 / 1024);
397
+ files.push(filePath);
398
+ }
399
+
400
+ multiBar.stop();
401
+ console.log(`Downloaded ${files.length} files to ${outputPath}`);
402
+ } catch (e) {
403
+ console.error(e);
404
+ return "err";
405
+ }
406
+ };
407
+
408
+ // const downloadFolderFromIPFS = async (cid, folderPath) => {
409
+ // try {
410
+ // console.log(`Downloading folder from IPFS: ${cid}`);
411
+
412
+ // // let res = await ipfs.get(cid);
413
+
414
+ // // const buffer = res[0];
415
+
416
+ // const utf8Decode = new TextDecoder('utf-8');
417
+ // // const string = utf8Decode.decode(buffer);
418
+
419
+ // // const object = JSON.parse(string);
420
+ // // console.log(`object: ${JSON.stringify(string, null, 2)}`);
421
+ // for await (const file of ipfs.get(cid)) {
422
+
423
+ // // console.log(`file: ${JSON.stringify(file, null, 2)}`);
424
+ // console.log(`file decoded: ${JSON.stringify(utf8Decode.decode(file), null, 2)}`);
425
+ // // const buffer = file[0];
426
+ // // console.log(`file: ${JSON.stringify(utf8Decode.decode(buffer), null, 2)}`);
427
+ // process.exit(0);
428
+ // // console.log(`${JSON.stringify(new TextDecoder().decode(file), null, 2)}`)
429
+ // // console.log(`file: ${JSON.stringify(file, null, 2)}`);
430
+ // // console.log(`file: ${JSON.stringify(file, null, 2)}`);
431
+ // // for await (const ffile of ipfs.ls(file.path)) {
432
+ // // console.log(`ffile: ${JSON.stringify(ffile, null, 2)}`);
433
+ // // }
434
+ // // for await (const ffile of ipfs.get("QmbjQpKFbueKR6QDU2Cj4ChsyGBR2spMwKV2S3yqrjF6w7")) {
435
+ // // console.log(`ffile: ${JSON.stringify(ffile, null, 2)}`);
436
+ // // }
437
+ // // console.log(`file cid: ${JSON.stringify(await ipfs.get("QmbjQpKFbueKR6QDU2Cj4ChsyGBR2spMwKV2S3yqrjF6w7"), null, 2)}`);
438
+
439
+ // // if (!file.path) {
440
+ // // // console.warn(`Skipping file with undefined path: ${JSON.stringify(file)}`);
441
+ // // continue;
442
+ // // }
443
+
444
+ // // const filePath = path.join(folderPath, file.path);
445
+ // // console.log(`Downloading file: ${filePath}`);
446
+ // // if (file.type === 'dir') {
447
+ // // fs.mkdirSync(filePath, { recursive: true });
448
+ // // } else {
449
+ // // fs.mkdirSync(path.dirname(filePath), { recursive: true });
450
+ // // const content = [];
451
+ // // for await (const chunk of file.content) {
452
+ // // content.push(chunk);
453
+ // // }
454
+ // // fs.writeFileSync(filePath, Buffer.concat(content));
455
+ // // }
456
+ // }
457
+
458
+ // console.log(`Download complete: ${folderPath}`);
459
+ // } catch (e) {
460
+ // console.error(e);
461
+ // return "err";
462
+ // }
463
+ // };
464
+
465
+ const getContentFromIPFS = async (hash, maxRetries = process.env.REACT_APP_IPFS_RETRIES || 5) => {
466
+ let res = '';
467
+ let retryCount = 0;
468
+
469
+ while (retryCount < maxRetries) {
470
+ try {
471
+ for await (const file of ipfs.cat(hash)) {
472
+ res += new TextDecoder().decode(file.buffer);
473
+ }
474
+
475
+ return res;
476
+ } catch (error) {
477
+ console.error(error.message);
478
+ retryCount += 1;
479
+
480
+ if (retryCount < maxRetries) {
481
+ await delay(getRetryDelay(retryCount));
482
+ continue;
483
+ } else {
484
+ throw new Error("ECIPFSDownloadError");
485
+ }
486
+ }
487
+ }
488
+ };
489
+
490
+ program
491
+ .option('--host <host>', 'IPFS host')
492
+ .option('--hhash <hhash>', 'IPFS hash')
493
+ .option('--filePath <path>', 'Path to the file')
494
+ .option('--folderPath <path>', 'Path to the folder')
495
+ .option('--action <action>', 'Action to perform (upload, download)')
496
+ .option('--output <path>', 'Output path for download');
497
+
498
+ program.parse(process.argv);
499
+
500
+ const options = program.opts();
501
+
502
+ const main = async () => {
503
+ const host = options.host || 'localhost';
504
+ initialize(host);
505
+
506
+ if (options.action === 'upload') {
507
+ if (options.filePath) {
508
+ const hhash = await uploadFileToIPFS(options.filePath);
509
+ console.log(`${hhash}`);
510
+ } else if (options.folderPath) {
511
+ // const hhash = await uploadFolderToIPFSBatch(options.folderPath);
512
+ let retryCount = 0;
513
+ let hhash = null;
514
+ try {
515
+ hhash = await uploadFolderToIPFS(options.folderPath);
516
+ console.log(`${hhash}`);
517
+ } catch (e) {
518
+ // console.log(e);
519
+ }
520
+ while ((!hhash || hhash === 'Upload failed.') && retryCount < 3) {
521
+ console.log(`Retrying... (${retryCount}/3)`);
522
+ hhash = await uploadFolderToIPFS(options.folderPath);
523
+ console.log(`${hhash}`);
524
+ retryCount += 1;
525
+ }
526
+
527
+ if (!hhash || hhash === 'Upload failed.') {
528
+ console.log(`Failed to upload folder to IPFS, please try again.`);
529
+ }
530
+ process.exit(0);
531
+ } else {
532
+ console.error('Please provide a filePath or folderPath for upload.');
533
+ }
534
+ } else if (options.action === 'download') {
535
+ if (options.filePath) {
536
+ console.log(`Downloading file from IPFS: ${options.hhash}`);
537
+ const content = await getFromIPFS(options.hhash, options.filePath);
538
+ console.log(`File downloaded. ${options.hhash}`);
539
+ } else if (options.folderPath) {
540
+ console.log(`Downloading folder from IPFS: ${options.hhash}`);
541
+ const content = await downloadFolderFromIPFS(options.hhash, options.folderPath);
542
+ console.log(`Folder downloaded. ${options.hhash}`);
543
+ } else {
544
+ console.error('Please provide a filePath or folderPath for download.');
545
+ }
546
+ } else {
547
+ console.error('Please provide a valid action (upload, download).');
548
+ }
549
+ };
550
+
551
+ main();
Binary file