neozipkit 0.2.1 → 0.3.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 (301) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +410 -186
  3. package/contracts/ABI.txt +889 -0
  4. package/contracts/Bytecode.txt +1 -0
  5. package/contracts/COMPILATION_NOTES.md +59 -0
  6. package/contracts/QUICK_DEPLOY.md +286 -0
  7. package/contracts/README.md +235 -131
  8. package/contracts/VERIFICATION.md +308 -0
  9. package/contracts/deploy-interactive.js +448 -0
  10. package/contracts/deployment-arbitrum-sepolia.json +12 -0
  11. package/contracts/deployment-arbitrum.json +12 -0
  12. package/contracts/deployment-eth-sepolia.json +12 -0
  13. package/contracts/hardhat.config.js +114 -0
  14. package/contracts/package.json +20 -0
  15. package/contracts/scripts/compile-and-extract.js +119 -0
  16. package/contracts/scripts/verify-contract.js +223 -0
  17. package/contracts/src/{NZIP-NFT-Private.sol → NZIP-NFT-v2.0.sol} +66 -151
  18. package/contracts/src/NZIP-NFT.sol +9 -15
  19. package/dist/blockchain/browser/TokenVerifierBrowser.d.ts +67 -0
  20. package/dist/blockchain/browser/TokenVerifierBrowser.d.ts.map +1 -0
  21. package/dist/blockchain/browser/TokenVerifierBrowser.js +313 -0
  22. package/dist/blockchain/browser/TokenVerifierBrowser.js.map +1 -0
  23. package/dist/blockchain/browser/WalletManagerBrowser.d.ts +98 -0
  24. package/dist/blockchain/browser/WalletManagerBrowser.d.ts.map +1 -0
  25. package/dist/blockchain/browser/WalletManagerBrowser.js +434 -0
  26. package/dist/blockchain/browser/WalletManagerBrowser.js.map +1 -0
  27. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts +58 -0
  28. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts.map +1 -0
  29. package/dist/blockchain/browser/ZipkitMinterBrowser.js +317 -0
  30. package/dist/blockchain/browser/ZipkitMinterBrowser.js.map +1 -0
  31. package/dist/blockchain/browser/index.d.ts +11 -0
  32. package/dist/blockchain/browser/index.d.ts.map +1 -0
  33. package/dist/blockchain/browser/index.js +16 -0
  34. package/dist/blockchain/browser/index.js.map +1 -0
  35. package/dist/blockchain/core/WalletManager.d.ts +124 -0
  36. package/dist/blockchain/core/WalletManager.d.ts.map +1 -0
  37. package/dist/blockchain/{ZipKitWallet.js → core/WalletManager.js} +157 -177
  38. package/dist/blockchain/core/WalletManager.js.map +1 -0
  39. package/dist/blockchain/{ZipKitMinter.d.ts → core/ZipkitMinter.d.ts} +46 -11
  40. package/dist/blockchain/core/ZipkitMinter.d.ts.map +1 -0
  41. package/dist/blockchain/core/ZipkitMinter.js +548 -0
  42. package/dist/blockchain/core/ZipkitMinter.js.map +1 -0
  43. package/dist/blockchain/{ZipKitOTS.d.ts → core/ZipkitOTS.d.ts} +6 -15
  44. package/dist/blockchain/core/ZipkitOTS.d.ts.map +1 -0
  45. package/dist/blockchain/{ZipKitOTS.js → core/ZipkitOTS.js} +26 -84
  46. package/dist/blockchain/core/ZipkitOTS.js.map +1 -0
  47. package/dist/blockchain/core/ZipkitVerifier.d.ts +177 -0
  48. package/dist/blockchain/core/ZipkitVerifier.d.ts.map +1 -0
  49. package/dist/blockchain/core/ZipkitVerifier.js +632 -0
  50. package/dist/blockchain/core/ZipkitVerifier.js.map +1 -0
  51. package/dist/blockchain/core/contracts.d.ts +83 -0
  52. package/dist/blockchain/core/contracts.d.ts.map +1 -0
  53. package/dist/blockchain/core/contracts.js +341 -0
  54. package/dist/blockchain/core/contracts.js.map +1 -0
  55. package/dist/blockchain/core/index.d.ts +12 -0
  56. package/dist/blockchain/core/index.d.ts.map +1 -0
  57. package/dist/blockchain/core/index.js +59 -0
  58. package/dist/blockchain/core/index.js.map +1 -0
  59. package/dist/blockchain/index.d.ts +11 -7
  60. package/dist/blockchain/index.d.ts.map +1 -0
  61. package/dist/blockchain/index.js +18 -34
  62. package/dist/blockchain/index.js.map +1 -0
  63. package/dist/blockchain/node/WalletManagerNode.d.ts +47 -0
  64. package/dist/blockchain/node/WalletManagerNode.d.ts.map +1 -0
  65. package/dist/blockchain/node/WalletManagerNode.js +203 -0
  66. package/dist/blockchain/node/WalletManagerNode.js.map +1 -0
  67. package/dist/blockchain/node/index.d.ts +12 -0
  68. package/dist/blockchain/node/index.d.ts.map +1 -0
  69. package/dist/blockchain/node/index.js +24 -0
  70. package/dist/blockchain/node/index.js.map +1 -0
  71. package/dist/browser/ZipkitBrowser.d.ts +27 -0
  72. package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
  73. package/dist/browser/{ZipKitBrowser.js → ZipkitBrowser.js} +96 -43
  74. package/dist/browser/ZipkitBrowser.js.map +1 -0
  75. package/dist/browser/index.d.ts +12 -0
  76. package/dist/browser/index.d.ts.map +1 -0
  77. package/dist/browser/index.js +42 -0
  78. package/dist/browser/index.js.map +1 -0
  79. package/dist/browser-esm/index.d.ts +12 -0
  80. package/dist/browser-esm/index.js +59559 -0
  81. package/dist/browser-esm/index.js.map +7 -0
  82. package/dist/browser-umd/index.d.ts +12 -0
  83. package/dist/browser-umd/index.js +59576 -0
  84. package/dist/browser-umd/index.js.map +7 -0
  85. package/dist/browser-umd/index.min.js +63 -0
  86. package/dist/browser.d.ts +8 -14
  87. package/dist/browser.js +13 -28
  88. package/dist/core/ZipCompress.d.ts +99 -0
  89. package/dist/core/ZipCompress.d.ts.map +1 -0
  90. package/dist/core/ZipCompress.js +309 -0
  91. package/dist/core/ZipCompress.js.map +1 -0
  92. package/dist/core/ZipDecompress.d.ts +58 -0
  93. package/dist/core/ZipDecompress.d.ts.map +1 -0
  94. package/dist/core/ZipDecompress.js +172 -0
  95. package/dist/core/ZipDecompress.js.map +1 -0
  96. package/dist/{shared → core}/ZipEntry.d.ts +8 -1
  97. package/dist/core/ZipEntry.d.ts.map +1 -0
  98. package/dist/{shared → core}/ZipEntry.js +225 -82
  99. package/dist/core/ZipEntry.js.map +1 -0
  100. package/dist/core/Zipkit.d.ts +315 -0
  101. package/dist/core/Zipkit.d.ts.map +1 -0
  102. package/dist/core/Zipkit.js +647 -0
  103. package/dist/core/Zipkit.js.map +1 -0
  104. package/dist/core/components/HashCalculator.d.ts +138 -0
  105. package/dist/core/components/HashCalculator.d.ts.map +1 -0
  106. package/dist/core/components/HashCalculator.js +360 -0
  107. package/dist/core/components/HashCalculator.js.map +1 -0
  108. package/dist/core/components/Logger.d.ts +73 -0
  109. package/dist/core/components/Logger.d.ts.map +1 -0
  110. package/dist/core/components/Logger.js +156 -0
  111. package/dist/core/components/Logger.js.map +1 -0
  112. package/dist/core/components/ProgressTracker.d.ts +43 -0
  113. package/dist/core/components/ProgressTracker.d.ts.map +1 -0
  114. package/dist/core/components/ProgressTracker.js +112 -0
  115. package/dist/core/components/ProgressTracker.js.map +1 -0
  116. package/dist/{shared → core}/components/Support.d.ts +1 -0
  117. package/dist/core/components/Support.d.ts.map +1 -0
  118. package/dist/{shared → core}/components/Support.js +1 -0
  119. package/dist/core/components/Support.js.map +1 -0
  120. package/dist/{shared → core}/components/Util.d.ts +7 -2
  121. package/dist/core/components/Util.d.ts.map +1 -0
  122. package/dist/{shared → core}/components/Util.js +14 -34
  123. package/dist/core/components/Util.js.map +1 -0
  124. package/dist/{shared → core}/constants/Errors.d.ts +1 -2
  125. package/dist/core/constants/Errors.d.ts.map +1 -0
  126. package/dist/{shared → core}/constants/Errors.js +1 -3
  127. package/dist/core/constants/Errors.js.map +1 -0
  128. package/dist/{shared → core}/constants/Headers.d.ts +3 -0
  129. package/dist/core/constants/Headers.d.ts.map +1 -0
  130. package/dist/{shared → core}/constants/Headers.js +20 -17
  131. package/dist/core/constants/Headers.js.map +1 -0
  132. package/dist/core/encryption/Manager.d.ts +58 -0
  133. package/dist/core/encryption/Manager.d.ts.map +1 -0
  134. package/dist/core/encryption/Manager.js +121 -0
  135. package/dist/core/encryption/Manager.js.map +1 -0
  136. package/dist/core/encryption/ZipCrypto.d.ts +172 -0
  137. package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
  138. package/dist/core/encryption/ZipCrypto.js +554 -0
  139. package/dist/core/encryption/ZipCrypto.js.map +1 -0
  140. package/dist/core/encryption/index.d.ts +9 -0
  141. package/dist/core/encryption/index.d.ts.map +1 -0
  142. package/dist/core/encryption/index.js +17 -0
  143. package/dist/core/encryption/index.js.map +1 -0
  144. package/dist/core/encryption/types.d.ts +29 -0
  145. package/dist/core/encryption/types.d.ts.map +1 -0
  146. package/dist/core/encryption/types.js +12 -0
  147. package/dist/core/encryption/types.js.map +1 -0
  148. package/dist/core/index.d.ts +24 -0
  149. package/dist/core/index.d.ts.map +1 -0
  150. package/dist/core/index.js +57 -0
  151. package/dist/core/index.js.map +1 -0
  152. package/dist/core/version.d.ts +5 -0
  153. package/dist/core/version.d.ts.map +1 -0
  154. package/dist/core/version.js +31 -0
  155. package/dist/core/version.js.map +1 -0
  156. package/dist/index.d.ts +8 -18
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +29 -35
  159. package/dist/index.js.map +1 -0
  160. package/dist/node/ZipCompressNode.d.ts +123 -0
  161. package/dist/node/ZipCompressNode.d.ts.map +1 -0
  162. package/dist/node/ZipCompressNode.js +576 -0
  163. package/dist/node/ZipCompressNode.js.map +1 -0
  164. package/dist/node/ZipDecompressNode.d.ts +120 -0
  165. package/dist/node/ZipDecompressNode.d.ts.map +1 -0
  166. package/dist/node/ZipDecompressNode.js +461 -0
  167. package/dist/node/ZipDecompressNode.js.map +1 -0
  168. package/dist/node/ZipkitNode.d.ts +406 -0
  169. package/dist/node/ZipkitNode.d.ts.map +1 -0
  170. package/dist/node/ZipkitNode.js +1305 -0
  171. package/dist/node/ZipkitNode.js.map +1 -0
  172. package/dist/node/index.d.ts +26 -0
  173. package/dist/node/index.d.ts.map +1 -0
  174. package/dist/node/index.js +65 -0
  175. package/dist/node/index.js.map +1 -0
  176. package/dist/types/index.d.ts +59 -0
  177. package/dist/types/index.d.ts.map +1 -0
  178. package/dist/types/index.js +36 -1
  179. package/dist/types/index.js.map +1 -0
  180. package/examples/README.md +269 -0
  181. package/examples/blockchain-tokenize.ts +354 -0
  182. package/examples/create-zip.ts +172 -0
  183. package/examples/extract-zip.ts +158 -0
  184. package/examples/list-zip.ts +161 -0
  185. package/examples/test-files/data.json +116 -0
  186. package/examples/test-files/document.md +80 -0
  187. package/examples/test-files/document.txt +2 -0
  188. package/examples/test-files/file1.txt +48 -0
  189. package/examples/test-files/file2.txt +80 -0
  190. package/examples/tsconfig.json +44 -0
  191. package/examples/unzip-token.ts +491 -0
  192. package/examples/verify-tokenized-zip.ts +305 -0
  193. package/examples/zip-token.ts +604 -0
  194. package/package.json +108 -24
  195. package/src/blockchain/README.md +59 -66
  196. package/src/{browser/TokenVerifierBrowser.ts-remove → blockchain/browser/TokenVerifierBrowser.ts} +125 -79
  197. package/src/blockchain/browser/WalletManagerBrowser.ts +486 -0
  198. package/src/blockchain/browser/ZipkitMinterBrowser.ts +400 -0
  199. package/src/blockchain/browser/index.ts +13 -0
  200. package/src/blockchain/{ZipKitWallet.ts → core/WalletManager.ts} +241 -143
  201. package/src/blockchain/core/ZipkitMinter.ts +716 -0
  202. package/src/blockchain/{ZipKitOTS.ts → core/ZipkitOTS.ts} +28 -62
  203. package/src/blockchain/core/ZipkitVerifier.ts +853 -0
  204. package/src/blockchain/core/contracts.ts +370 -0
  205. package/src/blockchain/core/index.ts +71 -0
  206. package/src/blockchain/index.ts +21 -55
  207. package/src/blockchain/node/WalletManagerNode.ts +171 -0
  208. package/src/blockchain/node/index.ts +40 -0
  209. package/src/browser/{ZipKitBrowser.ts → ZipkitBrowser.ts} +104 -41
  210. package/src/browser/index.esm.ts +37 -0
  211. package/src/browser/index.ts +25 -0
  212. package/src/core/ZipCompress.ts +398 -0
  213. package/src/core/ZipDecompress.ts +212 -0
  214. package/src/{shared → core}/ZipEntry.ts +240 -90
  215. package/src/core/Zipkit.ts +794 -0
  216. package/src/core/components/HashCalculator.ts +384 -0
  217. package/src/core/components/Logger.ts +180 -0
  218. package/src/core/components/ProgressTracker.ts +134 -0
  219. package/src/{shared → core}/components/Util.ts +12 -34
  220. package/src/{shared → core}/constants/Errors.ts +0 -4
  221. package/src/{shared → core}/constants/Headers.ts +19 -17
  222. package/src/core/encryption/Manager.ts +137 -0
  223. package/src/core/encryption/ZipCrypto.ts +650 -0
  224. package/src/core/encryption/index.ts +15 -0
  225. package/src/core/encryption/types.ts +33 -0
  226. package/src/core/index.ts +34 -0
  227. package/src/core/version.ts +33 -0
  228. package/src/index.ts +54 -25
  229. package/src/node/ZipCompressNode.ts +632 -0
  230. package/src/node/ZipDecompressNode.ts +508 -0
  231. package/src/node/ZipkitNode.ts +1559 -0
  232. package/src/node/index.ts +69 -0
  233. package/src/types/index.ts +131 -1
  234. package/src/types/modules.d.ts +1 -11
  235. package/src/types/opentimestamps.d.ts +1 -23
  236. package/contracts/INTEGRATION.md +0 -338
  237. package/contracts/NETWORKS.md +0 -156
  238. package/contracts/NZIP-NFT-bytecode.txt +0 -1
  239. package/contracts/constants.ts +0 -952
  240. package/contracts/deploy-bytecode.mjs +0 -94
  241. package/dist/blockchain/CertificateToken.d.ts +0 -48
  242. package/dist/blockchain/CertificateToken.js +0 -386
  243. package/dist/blockchain/ZipKitMinter.js +0 -347
  244. package/dist/blockchain/ZipKitNFT.d.ts +0 -3
  245. package/dist/blockchain/ZipKitNFT.js +0 -7
  246. package/dist/blockchain/ZipKitVerifier.d.ts +0 -69
  247. package/dist/blockchain/ZipKitVerifier.js +0 -289
  248. package/dist/blockchain/ZipKitWallet.d.ts +0 -69
  249. package/dist/blockchain/contracts.d.ts +0 -14
  250. package/dist/blockchain/contracts.js +0 -77
  251. package/dist/blockchain/types.d.ts +0 -47
  252. package/dist/blockchain/types.js +0 -30
  253. package/dist/browser/ZipKitBrowser.d.ts +0 -18
  254. package/dist/browser/ZipKitStampBrowser.d.ts +0 -2
  255. package/dist/browser/ZipKitStampBrowser.js +0 -12
  256. package/dist/browser-index.d.ts +0 -18
  257. package/dist/browser-index.js +0 -57
  258. package/dist/server/ZipKitServer.d.ts +0 -74
  259. package/dist/server/ZipKitServer.js +0 -310
  260. package/dist/shared/ZipKit.d.ts +0 -243
  261. package/dist/shared/ZipKit.js +0 -772
  262. package/dist/shared/components/CertificateOTS.d.ts +0 -15
  263. package/dist/shared/components/CertificateOTS.js +0 -116
  264. package/dist/shared/components/FileSys.d.ts +0 -2
  265. package/dist/shared/components/FileSys.js +0 -113
  266. package/dist/shared/components/HashAccumulator.d.ts +0 -55
  267. package/dist/shared/components/HashAccumulator.js +0 -100
  268. package/dist/shared/components/ZipCrypto.d.ts +0 -3
  269. package/dist/shared/components/ZipCrypto.js +0 -78
  270. package/dist/shared/components/merkleTree.d.ts +0 -66
  271. package/dist/shared/components/merkleTree.js +0 -136
  272. package/dist/shared/types/index.d.ts +0 -21
  273. package/dist/shared/types/index.js +0 -3
  274. package/dist/shared/types.d.ts +0 -33
  275. package/dist/shared/types.js +0 -8
  276. package/dist/shared/version.d.ts +0 -2
  277. package/dist/shared/version.js +0 -6
  278. package/src/blockchain/CertificateToken.ts +0 -444
  279. package/src/blockchain/ZipKitMinter.ts +0 -470
  280. package/src/blockchain/ZipKitNFT.ts +0 -12
  281. package/src/blockchain/ZipKitVerifier.ts +0 -382
  282. package/src/blockchain/contracts.ts +0 -88
  283. package/src/blockchain/types.ts +0 -91
  284. package/src/browser/CertificateGeneratorBrowser.ts-remove +0 -498
  285. package/src/browser/ZipKitStampBrowser.ts +0 -9
  286. package/src/browser-index.ts +0 -36
  287. package/src/server/README.md +0 -25
  288. package/src/server/ZipKitServer.ts +0 -305
  289. package/src/shared/ZipKit.ts +0 -881
  290. package/src/shared/components/CertificateOTS.ts +0 -132
  291. package/src/shared/components/FileSys.ts +0 -87
  292. package/src/shared/components/HashAccumulator.ts +0 -113
  293. package/src/shared/components/ZipCrypto.ts +0 -91
  294. package/src/shared/components/merkleTree.ts +0 -162
  295. package/src/shared/types/index.ts +0 -25
  296. package/src/shared/types/modules.d.ts +0 -22
  297. package/src/shared/types/opentimestamps.d.ts +0 -23
  298. package/src/shared/types.d.ts +0 -8
  299. package/src/shared/types.ts +0 -43
  300. package/src/shared/version.ts +0 -3
  301. /package/src/{shared → core}/components/Support.ts +0 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Compile and Extract Script for NeoZip NFT Contract
5
+ *
6
+ * This script:
7
+ * 1. Compiles the NZIP-NFT.sol contract using Hardhat
8
+ * 2. Extracts the ABI and bytecode from compilation artifacts
9
+ * 3. Writes ABI.txt and Bytecode.txt in the contracts directory
10
+ *
11
+ * Usage:
12
+ * node scripts/compile-and-extract.js
13
+ * or
14
+ * yarn compile:extract
15
+ */
16
+
17
+ const hre = require("hardhat");
18
+ const fs = require("fs");
19
+ const path = require("path");
20
+
21
+ async function main() {
22
+ console.log("=".repeat(70));
23
+ console.log("🔨 Compiling NeoZip NFT Contract");
24
+ console.log("=".repeat(70));
25
+ console.log();
26
+
27
+ try {
28
+ // Compile the contract
29
+ console.log("📦 Compiling contracts...");
30
+ await hre.run("compile");
31
+ console.log("✅ Compilation successful!");
32
+ console.log();
33
+
34
+ // Get the contract artifact
35
+ const contractName = "ZipFileNFTPublic";
36
+
37
+ // Read the build info to get the exact artifact
38
+ // Hardhat stores artifacts in artifacts/src/<source-file>/<contract-name>.json
39
+ const artifactPath = path.join(__dirname, "..", "artifacts", "src", "NZIP-NFT.sol", `${contractName}.json`);
40
+
41
+ if (!fs.existsSync(artifactPath)) {
42
+ throw new Error(`Artifact not found at ${artifactPath}. Make sure the contract compiled successfully.`);
43
+ }
44
+
45
+ const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf8"));
46
+
47
+ // Extract ABI
48
+ const abi = artifact.abi;
49
+ if (!abi || abi.length === 0) {
50
+ throw new Error("ABI not found in artifact");
51
+ }
52
+
53
+ // Extract bytecode (deployment bytecode, not creation code)
54
+ let bytecode = artifact.bytecode;
55
+ if (!bytecode || bytecode === "0x") {
56
+ throw new Error("Bytecode not found in artifact");
57
+ }
58
+
59
+ // Remove 0x prefix if present (deploy-interactive.js handles adding it)
60
+ if (bytecode.startsWith("0x")) {
61
+ bytecode = bytecode.slice(2);
62
+ }
63
+
64
+ // Write to compiled files (NOT the deployment files)
65
+ // ABI.txt and Bytecode.txt are the DEPLOYED versions and must not be overwritten
66
+ const abiPath = path.join(__dirname, "..", "ABI-compiled.txt");
67
+ const bytecodePath = path.join(__dirname, "..", "Bytecode-compiled.txt");
68
+
69
+ fs.writeFileSync(abiPath, JSON.stringify(abi, null, "\t"), "utf8");
70
+ console.log(`✅ ABI written to: ${path.relative(process.cwd(), abiPath)}`);
71
+ console.log(` ⚠️ Note: This is the COMPILED ABI, not the deployed ABI.txt`);
72
+
73
+ fs.writeFileSync(bytecodePath, bytecode, "utf8");
74
+ console.log(`✅ Bytecode written to: ${path.relative(process.cwd(), bytecodePath)}`);
75
+ console.log(` ⚠️ Note: This is the COMPILED bytecode, not the deployed Bytecode.txt`);
76
+ console.log();
77
+
78
+ // Display summary
79
+ console.log("=".repeat(70));
80
+ console.log("📊 Compilation Summary");
81
+ console.log("=".repeat(70));
82
+ console.log(`Contract: ${contractName}`);
83
+ console.log(`ABI Functions: ${abi.filter(item => item.type === "function").length}`);
84
+ console.log(`Bytecode Length: ${bytecode.length} characters (${Math.floor(bytecode.length / 2)} bytes)`);
85
+ console.log();
86
+ console.log("⚠️ IMPORTANT: These are COMPILED files, not the deployed files!");
87
+ console.log(" - ABI-compiled.txt: Newly compiled ABI");
88
+ console.log(" - Bytecode-compiled.txt: Newly compiled bytecode");
89
+ console.log();
90
+ console.log(" The deployed files (ABI.txt and Bytecode.txt) were NOT modified.");
91
+ console.log(" To use the new compilation for deployment:");
92
+ console.log(" 1. Review the compiled files");
93
+ console.log(" 2. If correct, manually copy them to ABI.txt and Bytecode.txt");
94
+ console.log(" 3. Then use deploy-interactive.js to deploy");
95
+ console.log();
96
+
97
+ } catch (error) {
98
+ console.error();
99
+ console.error("❌ Error during compilation:");
100
+ console.error(error.message);
101
+ if (error.stack) {
102
+ console.error();
103
+ console.error("Stack trace:");
104
+ console.error(error.stack);
105
+ }
106
+ process.exit(1);
107
+ }
108
+ }
109
+
110
+ // Run the script
111
+ main()
112
+ .then(() => {
113
+ process.exit(0);
114
+ })
115
+ .catch((error) => {
116
+ console.error(error);
117
+ process.exit(1);
118
+ });
119
+
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Contract Verification Script for NeoZip NFT Contract
5
+ *
6
+ * This script verifies a deployed contract on the appropriate blockchain scanner
7
+ * using Hardhat's verify plugin and Etherscan API V2.
8
+ *
9
+ * Usage:
10
+ * node scripts/verify-contract.js <contractAddress> <network>
11
+ * or
12
+ * yarn verify <contractAddress> <network>
13
+ *
14
+ * Examples:
15
+ * node scripts/verify-contract.js 0x1234...5678 arbitrumSepolia
16
+ * node scripts/verify-contract.js 0x1234...5678 sepolia
17
+ * node scripts/verify-contract.js 0x1234...5678 baseSepolia
18
+ *
19
+ * Supported Networks:
20
+ * - ethereum (Ethereum Mainnet)
21
+ * - sepolia (Ethereum Sepolia)
22
+ * - base (Base Mainnet)
23
+ * - baseSepolia (Base Sepolia)
24
+ * - arbitrum (Arbitrum One)
25
+ * - arbitrumSepolia (Arbitrum Sepolia)
26
+ * - polygon (Polygon Mainnet)
27
+ * - polygonSepolia (Polygon Sepolia)
28
+ */
29
+
30
+ const hre = require("hardhat");
31
+ const path = require("path");
32
+
33
+ // Network name mapping (user-friendly to Hardhat network names)
34
+ const NETWORK_MAP = {
35
+ "eth": "ethereum",
36
+ "ethereum": "ethereum",
37
+ "eth-sepolia": "sepolia",
38
+ "sepolia": "sepolia",
39
+ "base": "base",
40
+ "base-sepolia": "baseSepolia",
41
+ "baseSepolia": "baseSepolia",
42
+ "arbitrum": "arbitrum",
43
+ "arbitrum-one": "arbitrum",
44
+ "arbitrum-sepolia": "arbitrumSepolia",
45
+ "arbitrumSepolia": "arbitrumSepolia",
46
+ "polygon": "polygon",
47
+ "polygon-sepolia": "polygonSepolia",
48
+ "polygonSepolia": "polygonSepolia",
49
+ "amoy": "polygonSepolia"
50
+ };
51
+
52
+ function getNetworkName(userInput) {
53
+ const normalized = userInput.toLowerCase().trim();
54
+ return NETWORK_MAP[normalized] || normalized;
55
+ }
56
+
57
+ function validateAddress(address) {
58
+ if (!address || typeof address !== "string") {
59
+ return false;
60
+ }
61
+ // Basic Ethereum address validation
62
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
63
+ }
64
+
65
+ async function main() {
66
+ console.log("=".repeat(70));
67
+ console.log("🔍 NeoZip NFT Contract Verification");
68
+ console.log("=".repeat(70));
69
+ console.log();
70
+
71
+ // Parse command line arguments
72
+ const args = process.argv.slice(2);
73
+
74
+ if (args.length < 2) {
75
+ console.error("❌ Error: Missing required arguments");
76
+ console.error();
77
+ console.error("Usage: node scripts/verify-contract.js <contractAddress> <network>");
78
+ console.error();
79
+ console.error("Examples:");
80
+ console.error(" node scripts/verify-contract.js 0x1234...5678 arbitrumSepolia");
81
+ console.error(" node scripts/verify-contract.js 0x1234...5678 sepolia");
82
+ console.error();
83
+ console.error("Supported networks:");
84
+ console.error(" - ethereum, sepolia");
85
+ console.error(" - base, baseSepolia");
86
+ console.error(" - arbitrum, arbitrumSepolia");
87
+ console.error(" - polygon, polygonSepolia");
88
+ console.error();
89
+ process.exit(1);
90
+ }
91
+
92
+ const contractAddress = args[0];
93
+ const networkInput = args[1];
94
+ const networkName = getNetworkName(networkInput);
95
+
96
+ // Validate contract address
97
+ if (!validateAddress(contractAddress)) {
98
+ console.error(`❌ Error: Invalid contract address: ${contractAddress}`);
99
+ console.error(" Address must be a valid Ethereum address (0x followed by 40 hex characters)");
100
+ process.exit(1);
101
+ }
102
+
103
+ // Check if network is configured
104
+ const networks = hre.config.networks;
105
+ if (!networks[networkName]) {
106
+ console.error(`❌ Error: Network '${networkName}' is not configured in hardhat.config.js`);
107
+ console.error();
108
+ console.error("Available networks:");
109
+ Object.keys(networks).forEach(net => {
110
+ console.error(` - ${net}`);
111
+ });
112
+ process.exit(1);
113
+ }
114
+
115
+ // Check for API key
116
+ const apiKey = hre.config.etherscan?.apiKey?.[networkName] ||
117
+ hre.config.etherscan?.apiKey?.mainnet ||
118
+ process.env.ETHERSCAN_API_KEY;
119
+
120
+ if (!apiKey) {
121
+ console.error("❌ Error: Etherscan API key not found");
122
+ console.error();
123
+ console.error("Please set one of the following:");
124
+ console.error(" - ETHERSCAN_API_KEY environment variable");
125
+ console.error(" - etherscan.apiKey in hardhat.config.js");
126
+ console.error();
127
+ console.error("Get your API key from:");
128
+ console.error(" https://etherscan.io/apis (works for all Etherscan-based explorers)");
129
+ process.exit(1);
130
+ }
131
+
132
+ console.log(`📋 Contract Address: ${contractAddress}`);
133
+ console.log(`🌐 Network: ${networkName}`);
134
+ console.log();
135
+
136
+ try {
137
+ console.log("🔍 Verifying contract on blockchain scanner...");
138
+ console.log(" This may take a few moments...");
139
+ console.log();
140
+
141
+ // Verify the contract
142
+ // The contract has no constructor arguments
143
+ await hre.run("verify:verify", {
144
+ address: contractAddress,
145
+ network: networkName
146
+ });
147
+
148
+ console.log();
149
+ console.log("=".repeat(70));
150
+ console.log("✅ Contract verified successfully!");
151
+ console.log("=".repeat(70));
152
+ console.log();
153
+
154
+ // Get explorer URL
155
+ const networkConfig = networks[networkName];
156
+ let explorerUrl = "";
157
+
158
+ if (networkName === "sepolia") {
159
+ explorerUrl = `https://sepolia.etherscan.io/address/${contractAddress}`;
160
+ } else if (networkName === "ethereum") {
161
+ explorerUrl = `https://etherscan.io/address/${contractAddress}`;
162
+ } else if (networkName === "baseSepolia") {
163
+ explorerUrl = `https://sepolia.basescan.org/address/${contractAddress}`;
164
+ } else if (networkName === "base") {
165
+ explorerUrl = `https://basescan.org/address/${contractAddress}`;
166
+ } else if (networkName === "arbitrumSepolia") {
167
+ explorerUrl = `https://sepolia.arbiscan.io/address/${contractAddress}`;
168
+ } else if (networkName === "arbitrum") {
169
+ explorerUrl = `https://arbiscan.io/address/${contractAddress}`;
170
+ } else if (networkName === "polygonSepolia") {
171
+ explorerUrl = `https://amoy.polygonscan.com/address/${contractAddress}`;
172
+ } else if (networkName === "polygon") {
173
+ explorerUrl = `https://polygonscan.com/address/${contractAddress}`;
174
+ }
175
+
176
+ if (explorerUrl) {
177
+ console.log(`🔗 View contract on explorer:`);
178
+ console.log(` ${explorerUrl}`);
179
+ console.log();
180
+ }
181
+
182
+ } catch (error) {
183
+ console.error();
184
+ console.error("❌ Verification failed:");
185
+
186
+ if (error.message.includes("Already Verified")) {
187
+ console.error(" Contract is already verified on the explorer.");
188
+ console.error(" This is not an error - the contract is already public.");
189
+ } else if (error.message.includes("bytecode")) {
190
+ console.error(" Bytecode mismatch detected.");
191
+ console.error(" This usually means:");
192
+ console.error(" 1. The contract was compiled with different settings");
193
+ console.error(" 2. The contract source code has changed");
194
+ console.error(" 3. The deployed bytecode doesn't match the source");
195
+ console.error();
196
+ console.error(" Solution:");
197
+ console.error(" 1. Recompile the contract: yarn compile:extract");
198
+ console.error(" 2. Redeploy with the new bytecode");
199
+ console.error(" 3. Or verify using the exact compiler settings used for deployment");
200
+ } else {
201
+ console.error(` ${error.message}`);
202
+ }
203
+
204
+ if (error.stack && !error.message.includes("Already Verified")) {
205
+ console.error();
206
+ console.error("Stack trace:");
207
+ console.error(error.stack);
208
+ }
209
+
210
+ process.exit(1);
211
+ }
212
+ }
213
+
214
+ // Run the script
215
+ main()
216
+ .then(() => {
217
+ process.exit(0);
218
+ })
219
+ .catch((error) => {
220
+ console.error("Unexpected error:", error);
221
+ process.exit(1);
222
+ });
223
+
@@ -6,33 +6,31 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
6
6
  import "@openzeppelin/contracts/access/Ownable.sol";
7
7
 
8
8
  /**
9
- * @title NZIP NFT Private Contract v2.0
10
- * @dev Private NFT contract for tokenizing ZIP files with blockchain metadata
9
+ * @title NZIP NFT Contract v2.0
10
+ * @dev Main NFT contract for tokenizing ZIP files with blockchain metadata
11
11
  * Features:
12
- * - Blockchain metadata (block number, timestamps)
12
+ * - Blockchain metadata (block number, timestamps)
13
13
  * - Multiple tokens allowed for same content (differentiated by timestamp)
14
- * - PRIVATE access control - only token owners can verify their tokens
15
14
  * - Enhanced events with blockchain context
16
- * - Selective authorization system for third-party verification
15
+ * - Structured data organization for better maintainability
17
16
  * - Improved input validation and error handling
18
17
  * - Removed unreliable block hash storage
19
18
  *
20
19
  * Version: 2.0 (New Production Contract - Previous contract deprecated)
20
+ * Previous Contract: 0xb78CB3bcC788fca38c731b1E9D70CF60b04CA015 (DEPRECATED)
21
21
  * Network: Base Sepolia (for testing) / Base Mainnet (for production)
22
- *
23
- * Privacy Model: Owner-controlled verification with optional authorization
24
22
  */
25
- contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
23
+ contract ZipFileNFT is ERC721, ERC721URIStorage, Ownable {
26
24
 
27
25
  // Counter for token IDs
28
26
  uint256 private _tokenIdCounter;
29
27
 
30
- // Struct to store ZIP file information - Latest Enhanced Version
28
+ // Struct to store ZIP file information - Latest Version
31
29
  struct ZipFileInfo {
32
30
  // File identification
33
31
  string fileName; // Original ZIP file name
34
- string merkleRootHash; // Merkle root hash of the ZIP contents (PRIVATE)
35
- string ipfsHash; // IPFS hash where the ZIP file is stored (PRIVATE)
32
+ string merkleRootHash; // Merkle root hash of the ZIP contents
33
+ string ipfsHash; // IPFS hash where the ZIP file is stored
36
34
  address creator; // Address that created/minted this token
37
35
 
38
36
  // Timestamps (grouped together)
@@ -41,63 +39,28 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
41
39
 
42
40
  // Blockchain metadata
43
41
  uint256 blockNumber; // Block number when the token was minted
44
- // Note: Block hash removed - blockhash(block.number) always returns 0
45
42
  }
46
43
 
47
- // PRIVATE storage mappings - not accessible by public
48
- mapping(uint256 => ZipFileInfo) private zipFileInfo;
44
+ // Mapping from token ID to ZIP file information
45
+ mapping(uint256 => ZipFileInfo) public zipFileInfo;
49
46
 
50
47
  // Mapping from composite key (merkleRoot + timestamp) to token ID
51
48
  // This prevents duplicate tokens with same content AND same timestamp
52
- mapping(bytes32 => uint256) private compositeKeyToTokenId;
53
-
54
- // Authorization system - token owners can authorize specific addresses for verification
55
- mapping(uint256 => mapping(address => bool)) public authorizedVerifiers;
49
+ mapping(bytes32 => uint256) public compositeKeyToTokenId;
56
50
 
57
- // Events - Enhanced with blockchain metadata (but verification still requires authorization)
58
- // Note: merkleRootHash included for verification - privacy handled via access control
59
- // Note: ipfsHash excluded from event for privacy
60
- // Note: Block hash removed - not reliably available during execution
51
+ // Events - Enhanced with blockchain metadata
61
52
  event ZipFileTokenized(
62
53
  uint256 indexed tokenId,
63
54
  address indexed creator,
64
55
  string fileName,
65
56
  string merkleRootHash,
66
57
  uint256 creationTimestamp,
58
+ string ipfsHash,
67
59
  uint256 tokenizationTime,
68
60
  uint256 blockNumber
69
61
  );
70
62
 
71
- event VerifierAuthorized(
72
- uint256 indexed tokenId,
73
- address indexed authorizedAddress,
74
- bool authorized
75
- );
76
-
77
- // Custom errors
78
- error NotTokenOwner(uint256 tokenId, address caller);
79
- error NotAuthorized(uint256 tokenId, address caller);
80
- error TokenDoesNotExist(uint256 tokenId);
81
- error ZipFileAlreadyTokenized(string merkleRootHash, uint256 timestamp);
82
-
83
- // Access control modifier
84
- modifier onlyTokenOwner(uint256 tokenId) {
85
- if (ownerOf(tokenId) != msg.sender) {
86
- revert NotTokenOwner(tokenId, msg.sender);
87
- }
88
- _;
89
- }
90
-
91
- // Access control modifier for authorized verifiers
92
- modifier onlyAuthorized(uint256 tokenId) {
93
- address owner = ownerOf(tokenId);
94
- if (owner != msg.sender && !authorizedVerifiers[tokenId][msg.sender]) {
95
- revert NotAuthorized(tokenId, msg.sender);
96
- }
97
- _;
98
- }
99
-
100
- constructor() ERC721("NeoZip File NFT Private v2", "NZIPPRV") Ownable(msg.sender) {}
63
+ constructor() ERC721("NeoZip File NFT v2", "NZIP") Ownable(msg.sender) {}
101
64
 
102
65
  /**
103
66
  * @dev Get the contract version
@@ -145,9 +108,7 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
145
108
  bytes32 compositeKey = generateCompositeKey(merkleRootHash, creationTimestamp);
146
109
 
147
110
  // Check if this exact combination already exists
148
- if (compositeKeyToTokenId[compositeKey] != 0) {
149
- revert ZipFileAlreadyTokenized(merkleRootHash, creationTimestamp);
150
- }
111
+ require(compositeKeyToTokenId[compositeKey] == 0, "ZIP file with this content and timestamp already tokenized");
151
112
 
152
113
  // Increment token counter
153
114
  _tokenIdCounter++;
@@ -175,13 +136,14 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
175
136
  // Store the composite key mapping
176
137
  compositeKeyToTokenId[compositeKey] = tokenId;
177
138
 
178
- // Emit event with merkleRootHash for verification (ipfsHash excluded for privacy)
139
+ // Emit event with blockchain metadata
179
140
  emit ZipFileTokenized(
180
141
  tokenId,
181
142
  msg.sender,
182
143
  fileName,
183
144
  merkleRootHash,
184
145
  creationTimestamp,
146
+ ipfsHash,
185
147
  block.timestamp,
186
148
  block.number
187
149
  );
@@ -190,46 +152,21 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
190
152
  }
191
153
 
192
154
  /**
193
- * @dev Get ZIP file information for a token - OWNER OR AUTHORIZED ONLY
155
+ * @dev Get ZIP file information for a token
194
156
  * @param tokenId The token ID to query
195
157
  * @return ZipFileInfo struct containing all file and blockchain metadata
196
158
  */
197
- function getZipFileInfo(uint256 tokenId) external view onlyAuthorized(tokenId) returns (ZipFileInfo memory) {
198
- if (_ownerOf(tokenId) == address(0)) {
199
- revert TokenDoesNotExist(tokenId);
200
- }
159
+ function getZipFileInfo(uint256 tokenId) external view returns (ZipFileInfo memory) {
160
+ require(_ownerOf(tokenId) != address(0), "Token does not exist");
201
161
  return zipFileInfo[tokenId];
202
162
  }
203
163
 
204
164
  /**
205
- * @dev Get basic public information about a token (safe for public viewing)
206
- * @param tokenId The token ID to query
207
- * @return fileName The file name
208
- * @return creator The creator address
209
- * @return tokenizationTime When the token was minted
210
- * @return blockNumber Block number when minted
211
- */
212
- function getPublicTokenInfo(uint256 tokenId) external view returns (
213
- string memory fileName,
214
- address creator,
215
- uint256 tokenizationTime,
216
- uint256 blockNumber
217
- ) {
218
- if (_ownerOf(tokenId) == address(0)) {
219
- revert TokenDoesNotExist(tokenId);
220
- }
221
-
222
- ZipFileInfo memory info = zipFileInfo[tokenId];
223
- return (info.fileName, info.creator, info.tokenizationTime, info.blockNumber);
224
- }
225
-
226
- /**
227
- * @dev Check if a ZIP file is already tokenized (for minting validation)
165
+ * @dev Check if a ZIP file is already tokenized
228
166
  * @param merkleRootHash The merkle root hash to check
229
167
  * @param creationTimestamp The creation timestamp to check
230
168
  * @return exists Whether the combination exists
231
169
  * @return tokenId The token ID if it exists (0 if not)
232
- * Note: This is public for minting validation, but doesn't reveal token details
233
170
  */
234
171
  function isZipFileTokenized(
235
172
  string memory merkleRootHash,
@@ -241,62 +178,46 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
241
178
  }
242
179
 
243
180
  /**
244
- * @dev Verify that a token matches the provided merkle root - OWNER OR AUTHORIZED ONLY
245
- * @param tokenId The token ID to verify
246
- * @param providedMerkleRoot The merkle root to check against
247
- * @return isValid Whether the token matches the provided merkle root
181
+ * @dev Get all token IDs for a specific merkle root (across all timestamps)
182
+ * @param merkleRoot The merkle root to search for
183
+ * @return tokenIds Array of token IDs with this merkle root
248
184
  */
249
- function verifyZipFile(uint256 tokenId, string memory providedMerkleRoot)
250
- external view onlyAuthorized(tokenId) returns (bool isValid) {
251
- if (_ownerOf(tokenId) == address(0)) {
252
- revert TokenDoesNotExist(tokenId);
185
+ function getTokensByMerkleRoot(string memory merkleRoot) external view returns (uint256[] memory) {
186
+ // Create dynamic array to collect matching tokens
187
+ uint256[] memory tempTokens = new uint256[](_tokenIdCounter);
188
+ uint256 count = 0;
189
+
190
+ // Search through all tokens
191
+ for (uint256 i = 1; i <= _tokenIdCounter; i++) {
192
+ if (_ownerOf(i) != address(0)) { // Token exists
193
+ if (keccak256(abi.encodePacked(zipFileInfo[i].merkleRootHash)) ==
194
+ keccak256(abi.encodePacked(merkleRoot))) {
195
+ tempTokens[count] = i;
196
+ count++;
197
+ }
198
+ }
253
199
  }
254
200
 
255
- return keccak256(abi.encodePacked(zipFileInfo[tokenId].merkleRootHash)) ==
256
- keccak256(abi.encodePacked(providedMerkleRoot));
257
- }
258
-
259
- /**
260
- * @dev Authorize or revoke access for a specific address to verify this token
261
- * @param tokenId The token ID to manage access for
262
- * @param authorizedAddress The address to authorize or revoke
263
- * @param authorized Whether to grant or revoke access
264
- */
265
- function authorizeVerifier(
266
- uint256 tokenId,
267
- address authorizedAddress,
268
- bool authorized
269
- ) external onlyTokenOwner(tokenId) {
270
- authorizedVerifiers[tokenId][authorizedAddress] = authorized;
271
- emit VerifierAuthorized(tokenId, authorizedAddress, authorized);
272
- }
273
-
274
- /**
275
- * @dev Check if an address is authorized to verify a specific token
276
- * @param tokenId The token ID to check
277
- * @param verifierAddress The address to check authorization for
278
- * @return Whether the address is authorized
279
- */
280
- function isAuthorizedVerifier(uint256 tokenId, address verifierAddress)
281
- external view returns (bool) {
282
- return authorizedVerifiers[tokenId][verifierAddress];
201
+ // Create result array with exact size
202
+ uint256[] memory result = new uint256[](count);
203
+ for (uint256 i = 0; i < count; i++) {
204
+ result[i] = tempTokens[i];
205
+ }
206
+
207
+ return result;
283
208
  }
284
209
 
285
210
  /**
286
- * @dev Get blockchain metadata for a token - OWNER OR AUTHORIZED ONLY
287
- * @param tokenId The token ID to query
288
- * @return blockNumber Block number when token was minted
289
- * @return tokenizationTime Exact timestamp when token was minted
211
+ * @dev Verify that a token matches the provided merkle root
212
+ * @param tokenId The token ID to verify
213
+ * @param providedMerkleRoot The merkle root to check against
214
+ * @return isValid Whether the token matches the provided merkle root
290
215
  */
291
- function getBlockchainMetadata(uint256 tokenId) external view onlyAuthorized(tokenId) returns (
292
- uint256 blockNumber,
293
- uint256 tokenizationTime
294
- ) {
295
- if (_ownerOf(tokenId) == address(0)) {
296
- revert TokenDoesNotExist(tokenId);
297
- }
298
- ZipFileInfo memory info = zipFileInfo[tokenId];
299
- return (info.blockNumber, info.tokenizationTime);
216
+ function verifyZipFile(uint256 tokenId, string memory providedMerkleRoot) external view returns (bool isValid) {
217
+ require(_ownerOf(tokenId) != address(0), "Token does not exist");
218
+
219
+ return keccak256(abi.encodePacked(zipFileInfo[tokenId].merkleRootHash)) ==
220
+ keccak256(abi.encodePacked(providedMerkleRoot));
300
221
  }
301
222
 
302
223
  /**
@@ -318,24 +239,18 @@ contract ZipFileNFTPrivate is ERC721, ERC721URIStorage, Ownable {
318
239
  }
319
240
 
320
241
  /**
321
- * @dev Get all token IDs owned by a specific address (for owner's dashboard)
322
- * @param owner The address to get tokens for
323
- * @return tokenIds Array of token IDs owned by the address
242
+ * @dev Get blockchain metadata for a token
243
+ * @param tokenId The token ID to query
244
+ * @return blockNumber Block number when token was minted
245
+ * @return tokenizationTime Exact timestamp when token was minted
324
246
  */
325
- function getTokensByOwner(address owner) external view returns (uint256[] memory) {
326
- uint256 balance = balanceOf(owner);
327
- uint256[] memory result = new uint256[](balance);
328
-
329
- uint256 counter = 0;
330
- for (uint256 i = 1; i <= _tokenIdCounter; i++) {
331
- if (_ownerOf(i) == owner) {
332
- result[counter] = i;
333
- counter++;
334
- if (counter >= balance) break;
335
- }
336
- }
337
-
338
- return result;
247
+ function getBlockchainMetadata(uint256 tokenId) public view returns (
248
+ uint256 blockNumber,
249
+ uint256 tokenizationTime
250
+ ) {
251
+ require(_ownerOf(tokenId) != address(0), "Token does not exist");
252
+ ZipFileInfo memory info = zipFileInfo[tokenId];
253
+ return (info.blockNumber, info.tokenizationTime);
339
254
  }
340
255
 
341
256
  // Override required by Solidity