neozipkit 0.1.1 → 0.2.1

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 (115) hide show
  1. package/README.md +52 -105
  2. package/contracts/INTEGRATION.md +338 -0
  3. package/contracts/NETWORKS.md +156 -0
  4. package/contracts/README.md +152 -0
  5. package/{src/server/blockchain → contracts}/constants.ts +5 -22
  6. package/contracts/deploy-bytecode.mjs +94 -0
  7. package/dist/blockchain/ZipKitMinter.d.ts +106 -0
  8. package/dist/blockchain/ZipKitMinter.js +347 -0
  9. package/dist/blockchain/ZipKitNFT.d.ts +3 -0
  10. package/dist/blockchain/ZipKitNFT.js +7 -0
  11. package/dist/blockchain/ZipKitOTS.d.ts +135 -0
  12. package/dist/blockchain/ZipKitOTS.js +564 -0
  13. package/dist/blockchain/ZipKitVerifier.d.ts +69 -0
  14. package/dist/blockchain/ZipKitVerifier.js +289 -0
  15. package/dist/{server/blockchain/WalletAnalyzer.d.ts → blockchain/ZipKitWallet.d.ts} +31 -43
  16. package/dist/{server/blockchain/WalletAnalyzer.js → blockchain/ZipKitWallet.js} +193 -161
  17. package/dist/blockchain/contracts.d.ts +14 -0
  18. package/dist/blockchain/contracts.js +77 -0
  19. package/dist/blockchain/index.d.ts +7 -0
  20. package/dist/blockchain/index.js +50 -0
  21. package/dist/{server/blockchain → blockchain}/types.d.ts +12 -34
  22. package/dist/{server/blockchain → blockchain}/types.js +1 -22
  23. package/dist/browser-index.d.ts +0 -3
  24. package/dist/browser-index.js +4 -5
  25. package/dist/browser.d.ts +0 -3
  26. package/dist/browser.js +4 -5
  27. package/dist/index.d.ts +8 -15
  28. package/dist/index.js +12 -24
  29. package/dist/server/{platform/server/ZipKitServer.d.ts → ZipKitServer.d.ts} +4 -35
  30. package/dist/server/{platform/server/ZipKitServer.js → ZipKitServer.js} +55 -182
  31. package/dist/shared/ZipEntry.js +1 -1
  32. package/dist/shared/ZipKit.d.ts +0 -6
  33. package/dist/shared/ZipKit.js +1 -18
  34. package/dist/shared/types.js +2 -2
  35. package/dist/shared/version.d.ts +2 -4
  36. package/dist/shared/version.js +4 -5
  37. package/package.json +13 -3
  38. package/src/blockchain/README.md +229 -0
  39. package/src/blockchain/ZipKitMinter.ts +470 -0
  40. package/src/blockchain/ZipKitNFT.ts +12 -0
  41. package/src/blockchain/ZipKitOTS.ts +622 -0
  42. package/src/blockchain/ZipKitVerifier.ts +382 -0
  43. package/src/blockchain/ZipKitWallet.ts +338 -0
  44. package/src/blockchain/contracts.ts +88 -0
  45. package/src/blockchain/index.ts +61 -0
  46. package/src/blockchain/types.ts +91 -0
  47. package/src/browser/{TokenVerifierBrowser.ts → TokenVerifierBrowser.ts-remove} +1 -1
  48. package/src/browser-index.ts +3 -3
  49. package/src/index.ts +10 -17
  50. package/src/server/README.md +25 -0
  51. package/src/server/ZipKitServer.ts +305 -0
  52. package/src/shared/ZipEntry.ts +1 -1
  53. package/src/shared/ZipKit.ts +1 -19
  54. package/src/shared/types.ts +3 -3
  55. package/src/shared/version.ts +3 -4
  56. package/src/types/modules.d.ts +11 -1
  57. package/contracts/Lock.sol +0 -34
  58. package/contracts/compile-contract.js +0 -168
  59. package/contracts/deploy/deploy-both-contracts.js +0 -286
  60. package/contracts/deploy/deploy-enhanced-contract.js +0 -197
  61. package/contracts/deploy/deploy-private-contract.js +0 -190
  62. package/contracts/deploy/deploy-public-clean.js +0 -1063
  63. package/contracts/deploy/deploy-public-contract.js +0 -1107
  64. package/contracts/deployment.config.example.js +0 -25
  65. package/contracts/remix-compile.js +0 -222
  66. package/contracts/setup-deployment.js +0 -51
  67. package/contracts/src/ZipFileNFT-DEPRECATED-6field.sol +0 -260
  68. package/contracts/src/ZipFileNFT-DEPRECATED-Enhanced.sol +0 -289
  69. package/dist/browser/CertificateGeneratorBrowser.d.ts +0 -75
  70. package/dist/browser/CertificateGeneratorBrowser.js +0 -433
  71. package/dist/browser/TokenVerifierBrowser.d.ts +0 -76
  72. package/dist/browser/TokenVerifierBrowser.js +0 -299
  73. package/dist/server/blockchain/NFTMinter.d.ts +0 -41
  74. package/dist/server/blockchain/NFTMinter.js +0 -323
  75. package/dist/server/blockchain/TokenQuerier.d.ts +0 -31
  76. package/dist/server/blockchain/TokenQuerier.js +0 -259
  77. package/dist/server/blockchain/TokenVerifier.d.ts +0 -20
  78. package/dist/server/blockchain/TokenVerifier.js +0 -395
  79. package/dist/server/blockchain/WalletFormatter.d.ts +0 -39
  80. package/dist/server/blockchain/WalletFormatter.js +0 -196
  81. package/dist/server/blockchain/WalletManager.d.ts +0 -46
  82. package/dist/server/blockchain/WalletManager.js +0 -294
  83. package/dist/server/blockchain/ZipMetadata.d.ts +0 -27
  84. package/dist/server/blockchain/ZipMetadata.js +0 -131
  85. package/dist/server/blockchain/ZipTokenProcessor.d.ts +0 -44
  86. package/dist/server/blockchain/ZipTokenProcessor.js +0 -204
  87. package/dist/server/blockchain/constants.d.ts +0 -102
  88. package/dist/server/blockchain/constants.js +0 -968
  89. package/dist/server/blockchain/index.d.ts +0 -9
  90. package/dist/server/blockchain/index.js +0 -44
  91. package/dist/server/blockchain/test-certificate.d.ts +0 -8
  92. package/dist/server/blockchain/test-certificate.js +0 -100
  93. package/dist/server/platform/servercomponents/ZipKitOTS.d.ts +0 -91
  94. package/dist/server/platform/servercomponents/ZipKitOTS.js +0 -271
  95. package/examples/unzip-token.ts +0 -488
  96. package/examples/zip-token.ts +0 -604
  97. package/src/server/blockchain/NFTMinter.ts +0 -357
  98. package/src/server/blockchain/TokenQuerier.ts +0 -287
  99. package/src/server/blockchain/TokenVerifier.ts +0 -453
  100. package/src/server/blockchain/WalletAnalyzer.ts +0 -397
  101. package/src/server/blockchain/WalletFormatter.ts +0 -206
  102. package/src/server/blockchain/WalletManager.ts +0 -294
  103. package/src/server/blockchain/ZipMetadata.ts +0 -117
  104. package/src/server/blockchain/ZipTokenProcessor.ts +0 -234
  105. package/src/server/blockchain/index.ts +0 -42
  106. package/src/server/blockchain/test-certificate.ts +0 -137
  107. package/src/server/blockchain/types.ts +0 -134
  108. package/src/server/platform/server/ZipKitServer.ts +0 -459
  109. package/src/server/platform/servercomponents/ZipKitOTS.ts +0 -313
  110. package/src/server/platform/servercomponents/opentimestamps.d.ts +0 -23
  111. /package/contracts/{bytecode.txt → NZIP-NFT-bytecode.txt} +0 -0
  112. /package/dist/{server/blockchain → blockchain}/CertificateToken.d.ts +0 -0
  113. /package/dist/{server/blockchain → blockchain}/CertificateToken.js +0 -0
  114. /package/src/{server/blockchain → blockchain}/CertificateToken.ts +0 -0
  115. /package/src/browser/{CertificateGeneratorBrowser.ts → CertificateGeneratorBrowser.ts-remove} +0 -0
@@ -0,0 +1,305 @@
1
+ /**
2
+ * ZipKitServer
3
+ * Copyright (c) 2025 NeoWare, Inc. All rights reserved.
4
+ *
5
+ * Server-side implementation of ZipKit that passes through all functions
6
+ * directly to the parent ZipKit class. This class provides a consistent interface
7
+ * for server environments and ensures all ZipKit functionality is available.
8
+ */
9
+
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { v4 as uuidv4 } from 'uuid';
13
+ import { exit } from 'process';
14
+
15
+ import ZipKit,{ CompressOptions, ZipEntry, TIMESTAMP_METADATA, TIMESTAMP_SUBMITTED, CMP_METHOD } from '../shared/ZipKit';
16
+ import * as Headers from '../shared/constants/Headers';
17
+ import { upgradeOTS as upgradeZipOts, createCertificateOts as createCertificateOtsFile, createOtsMetadataEntry } from '../blockchain/ZipKitOTS';
18
+
19
+ // Re-export everything from ZipKit
20
+ export * from '../shared/ZipKit';
21
+ export { Headers };
22
+
23
+ /**
24
+ * This implementation is optimized for server environments and handles all
25
+ * ZIP operations including compression, extraction, encryption, and file management.
26
+ */
27
+ export default class ZipKitServer extends ZipKit {
28
+ /**
29
+ * Creates a new ZipKitServer instance
30
+ *
31
+ * Initializes the parent ZipKit class and logs environment support information
32
+ * for diagnostic purposes.
33
+ */
34
+ constructor() {
35
+ super(); // Call the parent constructor
36
+ }
37
+
38
+ /**
39
+ * Loads a ZIP file from the filesystem for updating/creating operations
40
+ *
41
+ * Attempts to read an existing ZIP file, but creates a new empty archive if
42
+ * the file doesn't exist. This method is used when adding or updating entries
43
+ * in an archive, handling both new and existing ZIP files gracefully.
44
+ *
45
+ * @param zipFile - Path to the ZIP file to load or create
46
+ */
47
+ loadZipFile(zipFile: string): void {
48
+ let inBuffer: Buffer | null = null;
49
+ let fdIn: number | null = null;
50
+
51
+ try {
52
+ if (fs.existsSync(zipFile)) {
53
+ fdIn = fs.openSync(zipFile, 'r');
54
+ const stats = fs.fstatSync(fdIn);
55
+ inBuffer = Buffer.alloc(stats.size);
56
+ // inBuffer is allocated above; ensure non-null for readSync
57
+ fs.readSync(fdIn, inBuffer as Buffer, 0, stats.size, 0);
58
+ } else {
59
+ // File doesn't exist, use an empty buffer
60
+ inBuffer = Buffer.alloc(0);
61
+ }
62
+ } catch (error) {
63
+ console.log('Warning: Could not open existing file. Creating new archive.');
64
+ inBuffer = Buffer.alloc(0);
65
+ } finally {
66
+ if (fdIn !== null) {
67
+ fs.closeSync(fdIn);
68
+ }
69
+ }
70
+
71
+ // Initialize empty buffer if null
72
+ const buffer: Buffer = inBuffer ?? Buffer.alloc(0);
73
+ super.loadZip(buffer);
74
+ }
75
+
76
+ /**
77
+ * Loads a ZIP file from the filesystem for extraction and listing operations
78
+ *
79
+ * Reads an existing ZIP file and throws an error if the file doesn't exist.
80
+ * Use this method when working with existing archives that need to be extracted.
81
+ *
82
+ * @param zipFile - Path to the ZIP file to load
83
+ * @throws Error if the file doesn't exist or can't be read
84
+ */
85
+ loadUnzipFile(zipFile: string): void {
86
+ try {
87
+ // Check if the file exists before trying to read it
88
+ if (!fs.existsSync(zipFile)) {
89
+ console.error(`Error: Zip file "${zipFile}" does not exist`);
90
+ exit(1);
91
+ }
92
+
93
+ const inBuffer = fs.readFileSync(zipFile);
94
+ super.loadZip(inBuffer);
95
+ } catch (error) {
96
+ console.error(`Error: Failed to read zip file "${zipFile}"`);
97
+ exit(1);
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Adds a single file to the ZIP archive
103
+ * @param filename - Path to the file to be added
104
+ * @param comment - Optional comment for the file entry
105
+ *
106
+ * Handles:
107
+ * - Creating/updating ZipEntry objects
108
+ * - Setting file attributes and timestamps
109
+ * - Respecting freshen (-f) and update (-u) flags
110
+ * - Setting compression method
111
+ */
112
+ addFile(filename: string, freshen: boolean = false, update: boolean = false): void {
113
+ let entry = super.getZipEntry(filename);
114
+ if (!entry) {
115
+ // Check for Freshen option
116
+ if (freshen) return;
117
+ entry = super.createZipEntry(filename);
118
+ } else if (!update) {
119
+ // Mark this entry as not being updated
120
+ entry.isUpdated = false;
121
+ return;
122
+ }
123
+ entry.platform = process.platform;
124
+
125
+ // Correctly retrieve file stats
126
+ let attr = fs.statSync(filename); // Synchronously get the stats of the file
127
+
128
+ entry.uncompressedSize = attr.size;
129
+
130
+ // Set the DOS file time/date based on the Date stamp of the file.
131
+ const utcDate = new Date(attr.mtime.getTime());
132
+ entry.timeDateDOS = entry.setDateTime(utcDate);
133
+ entry.universalTime = Math.floor(attr.mtime.getTime() / 1000); // Store Unix timestamp
134
+
135
+ // Set Unix UID/GID if on Unix-like system
136
+ if (process.platform !== 'win32') {
137
+ entry.uid = attr.uid;
138
+ entry.gid = attr.gid;
139
+ }
140
+
141
+ // Use attr.mode for file permissions
142
+ entry.isDirectory = attr.isDirectory();
143
+ let _fattr = (attr.mode & 0xfff) | (entry.isDirectory ? 0x4000 : 0x8000);
144
+ entry.extFileAttr = ((_fattr << 16) | (entry.isDirectory ? 0x10 : 0)) >>> 0;
145
+ }
146
+
147
+ /**
148
+ * Processes files to be added to the ZIP archive
149
+ * Creates ZipEntry objects for each file and initiates the compression process
150
+ */
151
+ addFiles(files: string[], freshen: boolean = false, update: boolean = false) {
152
+ let filesAdded = 0;
153
+ for (var i=0; files[i] != undefined; i++) {
154
+ const filename = String(files[i]);
155
+ // Skip arguments that look like options (start with hyphen but aren't files)
156
+ if (filename.startsWith('-') && !fs.existsSync(filename)) {
157
+ console.warn(`Warning: Skipping '${filename}' which appears to be an option, not a file.`);
158
+ continue;
159
+ }
160
+
161
+ this.addFile(filename, freshen, update);
162
+ filesAdded++;
163
+ }
164
+
165
+ return filesAdded;
166
+ }
167
+
168
+ /**
169
+ * Creates a ZIP file
170
+ */
171
+ async createZip(zipFile: string, compressOptions: CompressOptions) {
172
+
173
+ // Ensure the directory structure for the output file exists
174
+ const outputDir = path.dirname(zipFile);
175
+ if (!fs.existsSync(outputDir)) {
176
+ fs.mkdirSync(outputDir, { recursive: true });
177
+ }
178
+
179
+ // Generate a unique temporary file name in the output directory
180
+ const _tempZipFile = path.join(outputDir, `neozip-${uuidv4()}.zip`);
181
+
182
+ // Open or create the .zip file for writing
183
+ const fd = fs.openSync(_tempZipFile, 'w');
184
+
185
+ let offset = await super.createZipFileData(compressOptions, {
186
+ onReadEntryData: (entry: ZipEntry) => {
187
+ try {
188
+ return fs.readFileSync(entry.filename);
189
+ } catch (error) {
190
+ throw new Error(`Failed to read file: ${entry.filename}`);
191
+ }
192
+ },
193
+ onOutputBuffer: (buffer: Buffer) => {
194
+ fs.writeSync(fd, buffer);
195
+ },
196
+ onEntryDone: (entry: ZipEntry, status: string) => {
197
+ console.log(`${status} ${entry.filename} to ${zipFile}`);
198
+ }
199
+ });
200
+
201
+ // Write the metadata entry to the .zip fi
202
+ await super.finishZipFileData(
203
+ offset,
204
+ function onOutputBuffer(buffer: Buffer) {
205
+ fs.writeSync(fd, buffer);
206
+ },
207
+ undefined
208
+ );
209
+
210
+ // Close the .zip file
211
+ fs.closeSync(fd);
212
+
213
+ // Delete the existing .zip file if it exists
214
+ if (fs.existsSync(zipFile)) {
215
+ fs.unlinkSync(zipFile);
216
+ }
217
+
218
+ // Replace the existing .zip file with the temporary file
219
+ fs.renameSync(_tempZipFile, zipFile);
220
+ }
221
+
222
+ /**
223
+ * Creates a ZIP file with OpenTimestamps (OTS) metadata
224
+ */
225
+ // async createZipOTS(zipFile: string, compressOptions: CompressOptions) {
226
+
227
+ // // Ensure the directory structure for the output file exists
228
+ // const outputDir = path.dirname(zipFile);
229
+ // if (!fs.existsSync(outputDir)) {
230
+ // fs.mkdirSync(outputDir, { recursive: true });
231
+ // }
232
+
233
+ // // Generate a unique temporary file name in the output directory
234
+ // const _tempZipFile = path.join(outputDir, `neozip-${uuidv4()}.zip`);
235
+
236
+ // // Open or create the .zip file for writing
237
+ // const fd = fs.openSync(_tempZipFile, 'w');
238
+
239
+ // let offset = await super.createZipFileData(compressOptions, {
240
+ // onReadEntryData: (entry: ZipEntry) => {
241
+ // try {
242
+ // return fs.readFileSync(entry.filename);
243
+ // } catch (error) {
244
+ // throw new Error(`Failed to read file: ${entry.filename}`);
245
+ // }
246
+ // },
247
+ // onOutputBuffer: (buffer: Buffer) => {
248
+ // fs.writeSync(fd, buffer);
249
+ // },
250
+ // onEntryDone: (entry: ZipEntry, status: string) => {
251
+ // console.log(`${status} ${entry.filename} to ${zipFile}`);
252
+ // }
253
+ // });
254
+
255
+ // // Timestamp the zip file to the Bitcoin blockchain
256
+ // let _metadataEntry = null;
257
+
258
+ // console.log('Timestamping to Bitcoin blockchain...');
259
+ // const _merkleRoot = super.getMerkleRoot();
260
+ // console.log('Merkle Root: ' + _merkleRoot);
261
+ // const _ots = await createTimestamp(_merkleRoot);
262
+ // _metadataEntry = super.createTimestampMetadataEntry(_ots);
263
+
264
+ // // Write the metadata entry to the .zip fi
265
+ // await super.finishZipFileData(
266
+ // offset,
267
+ // function onOutputBuffer(buffer: Buffer) {
268
+ // fs.writeSync(fd, buffer);
269
+ // },
270
+ // _metadataEntry || undefined
271
+ // );
272
+
273
+ // // Close the .zip file
274
+ // fs.closeSync(fd);
275
+
276
+ // // Delete the existing .zip file if it exists
277
+ // if (fs.existsSync(zipFile)) {
278
+ // fs.unlinkSync(zipFile);
279
+ // }
280
+
281
+ // // Replace the existing .zip file with the temporary file
282
+ // fs.renameSync(_tempZipFile, zipFile);
283
+ // }
284
+
285
+ /**
286
+ * Removes specified files from the ZIP archive
287
+ * Deletes matching ZipEntry objects and rebuilds the archive if any files were removed
288
+ */
289
+ deleteFiles(delFiles: string[]): number {
290
+
291
+ super.getDirectory();
292
+ let filesDel = 0;
293
+ delFiles.forEach(fname => {
294
+ const deleted = super.deleteFile(fname);
295
+ if (deleted) {
296
+ console.log(' deleting: ' + fname + "\n");
297
+ ++filesDel;
298
+ } else {
299
+ console.log(' warning: name not found: ' + fname + "\n");
300
+ }
301
+ })
302
+
303
+ return filesDel;
304
+ }
305
+ }
@@ -27,7 +27,7 @@ const VER_EXTRACT = 10; // Version needed to extract
27
27
  * Class representing a single entry (file or directory) within a ZIP archive
28
28
  */
29
29
  export default class ZipEntry implements ZipFileEntry {
30
- debug = true;
30
+ debug = false;
31
31
 
32
32
  verMadeBy: number = 0; // Read Version Made By
33
33
  verExtract: number = 0; // Read Version Needed to Extract
@@ -459,7 +459,7 @@ export default class ZipKit {
459
459
 
460
460
  if (options?.useSHA256) {
461
461
  entry.sha256 = sha256(data);
462
- console.log('SHA256: ', entry.sha256);
462
+ // console.log('SHA256: ', entry.sha256);
463
463
  };
464
464
 
465
465
  if (options?.password) {
@@ -827,24 +827,6 @@ export default class ZipKit {
827
827
  return ots;
828
828
  }
829
829
 
830
- /**
831
- * Creates a new timestamp metadata entry for the ZIP file
832
- * Calculates merkle root from file hashes and obtains blockchain timestamp
833
- * @returns Promise<ZipEntry | null> The created timestamp metadata entry or null if failed
834
- */
835
- createTimestampMetadataEntry(ots: Buffer | null): ZipEntry | null {
836
- if (!ots) return null;
837
- const tsEntry = this.createZipEntry(TIMESTAMP_SUBMITTED);
838
- tsEntry.crc = crc32(ots);
839
- tsEntry.uncompressedSize = ots.length;
840
- tsEntry.compressedSize = ots.length;
841
- tsEntry.cmpMethod = CMP_METHOD.STORED;
842
- tsEntry.fileBuffer = ots;
843
- tsEntry.isMetaData = true;
844
-
845
- return tsEntry;
846
- }
847
-
848
830
  /**
849
831
  * Sets the ZIP file comment
850
832
  * @param msg - Comment to set
@@ -1,4 +1,4 @@
1
- import { VERSION } from './version';
1
+ import { NEOZIPKIT_VERSION, NEOZIPKIT_RELEASE_DATE } from './version';
2
2
 
3
3
  export interface FileData {
4
4
  name: string;
@@ -38,6 +38,6 @@ export interface NeoZipKitInfo {
38
38
  }
39
39
 
40
40
  export const NEOZIPKIT_INFO: NeoZipKitInfo = {
41
- version: VERSION.number,
42
- releaseDate: VERSION.date
41
+ version: NEOZIPKIT_VERSION,
42
+ releaseDate: NEOZIPKIT_RELEASE_DATE
43
43
  };
@@ -1,4 +1,3 @@
1
- export const VERSION = {
2
- number: '0.1.51',
3
- date: '04-17-2025'
4
- };
1
+ // Global-style constants for easy import across the package
2
+ export const NEOZIPKIT_VERSION = '0.1.2';
3
+ export const NEOZIPKIT_RELEASE_DATE = '08-12-2025';
@@ -3,6 +3,16 @@ declare module 'pako' {
3
3
  export function inflateRaw(data: Uint8Array | Buffer): Buffer;
4
4
  }
5
5
 
6
+ // Minimal typings to satisfy TS in environments without @types/moment-timezone
7
+ declare module 'moment' {
8
+ const moment: any;
9
+ export default moment;
10
+ }
11
+ declare module 'moment-timezone' {
12
+ const momentTz: any;
13
+ export default momentTz;
14
+ }
15
+
6
16
  declare module 'opentimestamps' {
7
17
  export class Ops {
8
18
  static OpSHA256: any;
@@ -19,4 +29,4 @@ declare module 'opentimestamps' {
19
29
  export function upgrade(ots: DetachedTimestampFile): Promise<boolean>;
20
30
  export function verify(ots: DetachedTimestampFile, hash: DetachedTimestampFile, options?: any): Promise<any>;
21
31
  export function info(detached: DetachedTimestampFile): string;
22
- }
32
+ }
@@ -1,34 +0,0 @@
1
- // SPDX-License-Identifier: UNLICENSED
2
- pragma solidity ^0.8.28;
3
-
4
- // Uncomment this line to use console.log
5
- // import "hardhat/console.sol";
6
-
7
- contract Lock {
8
- uint public unlockTime;
9
- address payable public owner;
10
-
11
- event Withdrawal(uint amount, uint when);
12
-
13
- constructor(uint _unlockTime) payable {
14
- require(
15
- block.timestamp < _unlockTime,
16
- "Unlock time should be in the future"
17
- );
18
-
19
- unlockTime = _unlockTime;
20
- owner = payable(msg.sender);
21
- }
22
-
23
- function withdraw() public {
24
- // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
25
- // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
26
-
27
- require(block.timestamp >= unlockTime, "You can't withdraw yet");
28
- require(msg.sender == owner, "You aren't the owner");
29
-
30
- emit Withdrawal(address(this).balance, block.timestamp);
31
-
32
- owner.transfer(address(this).balance);
33
- }
34
- }
@@ -1,168 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Contract Compilation Helper for NZIP
5
- *
6
- * This script helps compile the NZIP-NFT.sol contract
7
- * Usage: node compile-contract.js
8
- */
9
-
10
- const fs = require('fs');
11
- const path = require('path');
12
-
13
- const readline = require('readline');
14
-
15
- const rl = readline.createInterface({
16
- input: process.stdin,
17
- output: process.stdout
18
- });
19
-
20
- console.log('🔧 NZIP Contract Compilation Helper');
21
- console.log('===================================\n');
22
-
23
- const contractPath = path.join(__dirname, 'src/NZIP-NFT.sol');
24
- const deployPath = path.join(__dirname, 'deploy/deploy-public-contract.js');
25
-
26
- if (!fs.existsSync(contractPath)) {
27
- console.log('❌ Contract file not found:', contractPath);
28
- process.exit(1);
29
- }
30
-
31
- console.log('📋 Choose your compilation method:\n');
32
- console.log('1️⃣ Remix IDE (Online) - RECOMMENDED');
33
- console.log('2️⃣ Remix IDE (Step-by-Step Guide) - NEW!');
34
- console.log('3️⃣ Local Hardhat (Advanced)');
35
- console.log('4️⃣ View Deprecated Contract Info');
36
- console.log('5️⃣ View Contract Source Code');
37
- console.log('6️⃣ Exit\n');
38
-
39
- rl.question('Enter your choice (1-6): ', (choice) => {
40
- console.log('');
41
-
42
- switch(choice.trim()) {
43
- case '1':
44
- showRemixInstructions();
45
- break;
46
- case '2':
47
- showRemixGuide();
48
- break;
49
- case '3':
50
- showHardhatInstructions();
51
- break;
52
- case '4':
53
- showDeprecatedInfo();
54
- break;
55
- case '5':
56
- showContractSource();
57
- break;
58
- case '6':
59
- console.log('👋 Goodbye!');
60
- rl.close();
61
- return;
62
- default:
63
- console.log('❌ Invalid choice. Please run the script again and choose 1-6.');
64
- rl.close();
65
- return;
66
- }
67
-
68
- rl.close();
69
- });
70
-
71
- function showRemixInstructions() {
72
- console.log('🌐 Remix IDE Compilation (RECOMMENDED)');
73
- console.log('======================================\n');
74
- console.log('📋 Steps:');
75
- console.log('1. Go to https://remix.ethereum.org');
76
- console.log('2. Create new file: NZIP-NFT.sol');
77
- console.log('3. Copy contract content (run with option 5 to see source)');
78
- console.log('4. Install OpenZeppelin dependencies');
79
- console.log('5. Compile with Solidity 0.8.19+');
80
- console.log('6. Copy bytecode and ABI from compilation artifacts');
81
- console.log('7. Update deployment script with compiled data\n');
82
-
83
- console.log('🎯 After compilation:');
84
- console.log('• Update CONTRACT_BYTECODE in deploy-public-contract.js');
85
- console.log('• Update CONTRACT_ABI in deploy-public-contract.js');
86
- console.log('• Run: npm run deploy:public');
87
- }
88
-
89
- function showRemixGuide() {
90
- console.log('📋 Remix IDE Step-by-Step Guide');
91
- console.log('===============================\n');
92
- console.log('For a detailed, interactive walkthrough of the entire Remix compilation process:');
93
- console.log('');
94
- console.log('🎯 Run this command:');
95
- console.log('npm run remix-compile\n');
96
-
97
- console.log('✨ This dedicated guide will:');
98
- console.log('• Walk you through each step interactively');
99
- console.log('• Show you exactly what to do in Remix');
100
- console.log('• Display the contract source when needed');
101
- console.log('• Guide you through extracting bytecode and ABI');
102
- console.log('• Help you update the deployment script');
103
- console.log('• Prepare you for deployment\n');
104
-
105
- console.log('💡 Perfect for first-time users or when you need detailed guidance!');
106
- }
107
-
108
- function showHardhatInstructions() {
109
- console.log('💻 Local Hardhat Compilation (Advanced)');
110
- console.log('=======================================\n');
111
- console.log('📋 Setup Steps:');
112
- console.log('1. npm install --save-dev hardhat @nomiclabs/hardhat-ethers ethers @openzeppelin/contracts');
113
- console.log('2. npx hardhat init');
114
- console.log('3. Copy contract to contracts/ folder');
115
- console.log('4. npx hardhat compile');
116
- console.log('5. Extract bytecode and ABI from artifacts/\n');
117
-
118
- console.log('📁 Artifact Location:');
119
- console.log('• Bytecode: artifacts/contracts/NZIP-NFT.sol/ZipFileNFT.json');
120
- console.log('• Look for "bytecode" and "abi" fields in the JSON file\n');
121
-
122
- console.log('🎯 After compilation:');
123
- console.log('• Update CONTRACT_BYTECODE in deploy-public-contract.js');
124
- console.log('• Update CONTRACT_ABI in deploy-public-contract.js');
125
- console.log('• Run: npm run deploy:public');
126
- }
127
-
128
- function showDeprecatedInfo() {
129
- console.log('⚠️ Deprecated Contract Notice');
130
- console.log('=============================\n');
131
- console.log('Previous contract is now DEPRECATED:');
132
- console.log('Address: 0xb78CB3bcC788fca38c731b1E9D70CF60b04CA015');
133
- console.log('Network: Base Sepolia');
134
- console.log('Status: ❌ DEPRECATED - Do not use\n');
135
-
136
- console.log('🚨 Why it\'s deprecated:');
137
- console.log('• Had broken block hash storage (always returned 0)');
138
- console.log('• Missing input validation');
139
- console.log('• Lacked proper version tracking\n');
140
-
141
- console.log('✅ New contract fixes:');
142
- console.log('• Removed unreliable block hash storage');
143
- console.log('• Added comprehensive input validation');
144
- console.log('• Version 2.0 with proper documentation');
145
- console.log('• Improved error handling\n');
146
-
147
- console.log('📋 Action Required:');
148
- console.log('You MUST compile and deploy a new contract!');
149
- }
150
-
151
- function showContractSource() {
152
- console.log('📄 NZIP NFT Contract v2.0 Source Code');
153
- console.log('=====================================\n');
154
- console.log('Copy this code to your compilation environment:\n');
155
-
156
- try {
157
- const contractContent = fs.readFileSync(contractPath, 'utf8');
158
- console.log(contractContent);
159
- } catch (err) {
160
- console.log('❌ Error reading contract:', err.message);
161
- }
162
-
163
- console.log('\n🎯 Next Steps:');
164
- console.log('1. Copy the contract code above');
165
- console.log('2. Use Remix IDE or Hardhat to compile');
166
- console.log('3. Update deployment script with compiled bytecode/ABI');
167
- console.log('4. Deploy with: npm run deploy:public');
168
- }