neozipkit 0.1.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.
- package/README.md +400 -0
- package/contracts/Lock.sol +34 -0
- package/contracts/bytecode.txt +1 -0
- package/contracts/compile-contract.js +168 -0
- package/contracts/deploy/deploy-both-contracts.js +286 -0
- package/contracts/deploy/deploy-enhanced-contract.js +197 -0
- package/contracts/deploy/deploy-private-contract.js +190 -0
- package/contracts/deploy/deploy-public-clean.js +1063 -0
- package/contracts/deploy/deploy-public-contract.js +1107 -0
- package/contracts/deployment.config.example.js +25 -0
- package/contracts/remix-compile.js +222 -0
- package/contracts/setup-deployment.js +51 -0
- package/contracts/src/NZIP-NFT-Private.sol +350 -0
- package/contracts/src/NZIP-NFT.sol +265 -0
- package/contracts/src/ZipFileNFT-DEPRECATED-6field.sol +260 -0
- package/contracts/src/ZipFileNFT-DEPRECATED-Enhanced.sol +289 -0
- package/dist/browser/CertificateGeneratorBrowser.d.ts +75 -0
- package/dist/browser/CertificateGeneratorBrowser.js +433 -0
- package/dist/browser/TokenVerifierBrowser.d.ts +76 -0
- package/dist/browser/TokenVerifierBrowser.js +299 -0
- package/dist/browser/ZipKitBrowser.d.ts +18 -0
- package/dist/browser/ZipKitBrowser.js +250 -0
- package/dist/browser/ZipKitStampBrowser.d.ts +2 -0
- package/dist/browser/ZipKitStampBrowser.js +12 -0
- package/dist/browser-index.d.ts +21 -0
- package/dist/browser-index.js +58 -0
- package/dist/browser.d.ts +21 -0
- package/dist/browser.js +58 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +76 -0
- package/dist/server/blockchain/CertificateToken.d.ts +48 -0
- package/dist/server/blockchain/CertificateToken.js +386 -0
- package/dist/server/blockchain/NFTMinter.d.ts +41 -0
- package/dist/server/blockchain/NFTMinter.js +323 -0
- package/dist/server/blockchain/TokenQuerier.d.ts +31 -0
- package/dist/server/blockchain/TokenQuerier.js +259 -0
- package/dist/server/blockchain/TokenVerifier.d.ts +20 -0
- package/dist/server/blockchain/TokenVerifier.js +395 -0
- package/dist/server/blockchain/WalletAnalyzer.d.ts +81 -0
- package/dist/server/blockchain/WalletAnalyzer.js +356 -0
- package/dist/server/blockchain/WalletFormatter.d.ts +39 -0
- package/dist/server/blockchain/WalletFormatter.js +196 -0
- package/dist/server/blockchain/WalletManager.d.ts +46 -0
- package/dist/server/blockchain/WalletManager.js +294 -0
- package/dist/server/blockchain/ZipMetadata.d.ts +27 -0
- package/dist/server/blockchain/ZipMetadata.js +131 -0
- package/dist/server/blockchain/ZipTokenProcessor.d.ts +44 -0
- package/dist/server/blockchain/ZipTokenProcessor.js +204 -0
- package/dist/server/blockchain/constants.d.ts +102 -0
- package/dist/server/blockchain/constants.js +968 -0
- package/dist/server/blockchain/index.d.ts +9 -0
- package/dist/server/blockchain/index.js +44 -0
- package/dist/server/blockchain/test-certificate.d.ts +8 -0
- package/dist/server/blockchain/test-certificate.js +100 -0
- package/dist/server/blockchain/types.d.ts +69 -0
- package/dist/server/blockchain/types.js +51 -0
- package/dist/server/platform/server/ZipKitServer.d.ts +105 -0
- package/dist/server/platform/server/ZipKitServer.js +437 -0
- package/dist/server/platform/servercomponents/ZipKitOTS.d.ts +91 -0
- package/dist/server/platform/servercomponents/ZipKitOTS.js +271 -0
- package/dist/shared/ZipEntry.d.ts +131 -0
- package/dist/shared/ZipEntry.js +686 -0
- package/dist/shared/ZipKit.d.ts +249 -0
- package/dist/shared/ZipKit.js +789 -0
- package/dist/shared/components/CertificateOTS.d.ts +15 -0
- package/dist/shared/components/CertificateOTS.js +116 -0
- package/dist/shared/components/FileSys.d.ts +2 -0
- package/dist/shared/components/FileSys.js +113 -0
- package/dist/shared/components/HashAccumulator.d.ts +55 -0
- package/dist/shared/components/HashAccumulator.js +100 -0
- package/dist/shared/components/Support.d.ts +63 -0
- package/dist/shared/components/Support.js +70 -0
- package/dist/shared/components/Util.d.ts +21 -0
- package/dist/shared/components/Util.js +115 -0
- package/dist/shared/components/ZipCrypto.d.ts +3 -0
- package/dist/shared/components/ZipCrypto.js +78 -0
- package/dist/shared/components/merkleTree.d.ts +66 -0
- package/dist/shared/components/merkleTree.js +136 -0
- package/dist/shared/constants/Errors.d.ts +53 -0
- package/dist/shared/constants/Errors.js +69 -0
- package/dist/shared/constants/Headers.d.ts +167 -0
- package/dist/shared/constants/Headers.js +191 -0
- package/dist/shared/types/index.d.ts +21 -0
- package/dist/shared/types/index.js +3 -0
- package/dist/shared/types.d.ts +33 -0
- package/dist/shared/types.js +8 -0
- package/dist/shared/version.d.ts +4 -0
- package/dist/shared/version.js +7 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.js +3 -0
- package/examples/unzip-token.ts +488 -0
- package/examples/zip-token.ts +604 -0
- package/package.json +117 -0
- package/src/browser/CertificateGeneratorBrowser.ts +498 -0
- package/src/browser/TokenVerifierBrowser.ts +344 -0
- package/src/browser/ZipKitBrowser.ts +242 -0
- package/src/browser/ZipKitStampBrowser.ts +9 -0
- package/src/browser-index.ts +36 -0
- package/src/index.ts +48 -0
- package/src/server/blockchain/CertificateToken.ts +444 -0
- package/src/server/blockchain/NFTMinter.ts +357 -0
- package/src/server/blockchain/TokenQuerier.ts +287 -0
- package/src/server/blockchain/TokenVerifier.ts +453 -0
- package/src/server/blockchain/WalletAnalyzer.ts +397 -0
- package/src/server/blockchain/WalletFormatter.ts +206 -0
- package/src/server/blockchain/WalletManager.ts +294 -0
- package/src/server/blockchain/ZipMetadata.ts +117 -0
- package/src/server/blockchain/ZipTokenProcessor.ts +234 -0
- package/src/server/blockchain/constants.ts +969 -0
- package/src/server/blockchain/index.ts +42 -0
- package/src/server/blockchain/test-certificate.ts +137 -0
- package/src/server/blockchain/types.ts +134 -0
- package/src/server/platform/server/ZipKitServer.ts +459 -0
- package/src/server/platform/servercomponents/ZipKitOTS.ts +313 -0
- package/src/server/platform/servercomponents/opentimestamps.d.ts +23 -0
- package/src/shared/ZipEntry.ts +767 -0
- package/src/shared/ZipKit.ts +899 -0
- package/src/shared/components/CertificateOTS.ts +132 -0
- package/src/shared/components/FileSys.ts +87 -0
- package/src/shared/components/HashAccumulator.ts +113 -0
- package/src/shared/components/Support.ts +77 -0
- package/src/shared/components/Util.ts +113 -0
- package/src/shared/components/ZipCrypto.ts +91 -0
- package/src/shared/components/merkleTree.ts +162 -0
- package/src/shared/constants/Errors.ts +82 -0
- package/src/shared/constants/Headers.ts +203 -0
- package/src/shared/types/index.ts +25 -0
- package/src/shared/types/modules.d.ts +22 -0
- package/src/shared/types/opentimestamps.d.ts +23 -0
- package/src/shared/types.d.ts +8 -0
- package/src/shared/types.ts +43 -0
- package/src/shared/version.ts +4 -0
- package/src/types/index.ts +25 -0
- package/src/types/modules.d.ts +22 -0
- package/src/types/opentimestamps.d.ts +23 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import ZipEntry from '../ZipEntry';
|
|
2
|
+
import type { AttestationValue } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a certificate HTML document based on timestamp information
|
|
5
|
+
*
|
|
6
|
+
* @param attestStr - Attestation message
|
|
7
|
+
* @param zipFile - Name of the zip file
|
|
8
|
+
* @param hashDigest - Hash digest of the zip file
|
|
9
|
+
* @param needsUpdateMsg - Message indicating if update is needed
|
|
10
|
+
* @param attestationValues - Array of attestation values
|
|
11
|
+
* @param zipEntries - Array of ZipEntry objects
|
|
12
|
+
* @param narrow - Whether to use narrow layout
|
|
13
|
+
* @returns Generated HTML certificate as string
|
|
14
|
+
*/
|
|
15
|
+
export default function CertificateTemplate(attestStr: string | null, zipFile: string, hashDigest: string, needsUpdateMsg: string, attestationValues: AttestationValue[], zipEntries: ZipEntry[], narrow?: boolean): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// CertificateOTS.ts
|
|
4
|
+
// Copyright (c) 2025 NeoWare, Inc. All rights reserved.
|
|
5
|
+
// ======================================
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.default = CertificateTemplate;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const Headers_1 = require("../constants/Headers");
|
|
14
|
+
/**
|
|
15
|
+
* Generates a certificate HTML document based on timestamp information
|
|
16
|
+
*
|
|
17
|
+
* @param attestStr - Attestation message
|
|
18
|
+
* @param zipFile - Name of the zip file
|
|
19
|
+
* @param hashDigest - Hash digest of the zip file
|
|
20
|
+
* @param needsUpdateMsg - Message indicating if update is needed
|
|
21
|
+
* @param attestationValues - Array of attestation values
|
|
22
|
+
* @param zipEntries - Array of ZipEntry objects
|
|
23
|
+
* @param narrow - Whether to use narrow layout
|
|
24
|
+
* @returns Generated HTML certificate as string
|
|
25
|
+
*/
|
|
26
|
+
function CertificateTemplate(attestStr, zipFile, hashDigest, needsUpdateMsg, attestationValues, zipEntries, narrow) {
|
|
27
|
+
// Load the HTML template
|
|
28
|
+
let templatePath;
|
|
29
|
+
try {
|
|
30
|
+
// Try to find the template from the package root
|
|
31
|
+
templatePath = path_1.default.resolve(process.cwd(), 'assets/templates/certificate.html');
|
|
32
|
+
if (!fs_1.default.existsSync(templatePath)) {
|
|
33
|
+
// If not found in current working directory, try relative to this file
|
|
34
|
+
templatePath = path_1.default.resolve(__dirname, '../../assets/templates/certificate.html');
|
|
35
|
+
}
|
|
36
|
+
if (!fs_1.default.existsSync(templatePath)) {
|
|
37
|
+
throw new Error('Certificate template not found');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('Error resolving template path:', error);
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
// Read the template file
|
|
45
|
+
let htmlTemplate;
|
|
46
|
+
try {
|
|
47
|
+
htmlTemplate = fs_1.default.readFileSync(templatePath, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('Error reading template file:', error);
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
const updateWarning = needsUpdateMsg || '';
|
|
54
|
+
// Generate attestation HTML
|
|
55
|
+
let attestHTML = '';
|
|
56
|
+
if (attestationValues && attestationValues.length > 0) {
|
|
57
|
+
attestationValues.forEach((attest) => {
|
|
58
|
+
attestHTML += `
|
|
59
|
+
<div class="key-value-pair">
|
|
60
|
+
<div class="key">Block Height:</div>
|
|
61
|
+
<div class="value">${attest['blockHeight']}</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="key-value-pair">
|
|
64
|
+
<div class="key">Transaction:</div>
|
|
65
|
+
<div class="value">${attest['transactionId']}</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="key-value-pair">
|
|
68
|
+
<div class="key">Merkle Root:</div>
|
|
69
|
+
<div class="value">${attest['merkleRoot']}</div>
|
|
70
|
+
</div>
|
|
71
|
+
<br/>
|
|
72
|
+
`;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Generate files table HTML
|
|
76
|
+
let stampEntry = null;
|
|
77
|
+
let files = [];
|
|
78
|
+
for (const entry of zipEntries) {
|
|
79
|
+
if (entry.filename === Headers_1.TIMESTAMP_METADATA) {
|
|
80
|
+
stampEntry = entry;
|
|
81
|
+
}
|
|
82
|
+
else if (entry.filename === Headers_1.TIMESTAMP_SUBMITTED) {
|
|
83
|
+
if (stampEntry == null)
|
|
84
|
+
stampEntry = entry;
|
|
85
|
+
}
|
|
86
|
+
else if (entry.sha256) {
|
|
87
|
+
let file = {
|
|
88
|
+
name: entry.filename,
|
|
89
|
+
size: entry.uncompressedSize.toString(),
|
|
90
|
+
date: entry.toFormattedUTCDateString(),
|
|
91
|
+
hash: entry.sha256,
|
|
92
|
+
};
|
|
93
|
+
files.push(file);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
let filesTableHTML = '';
|
|
97
|
+
files.forEach((file) => {
|
|
98
|
+
filesTableHTML += `
|
|
99
|
+
<tr>
|
|
100
|
+
<td class="table-data1">${file.name}</td>
|
|
101
|
+
<td class="table-data">${file.size}</td>
|
|
102
|
+
<td class="table-data">${file.date}</td>
|
|
103
|
+
<td class="table-data">${file.hash}</td>
|
|
104
|
+
</tr>
|
|
105
|
+
`;
|
|
106
|
+
});
|
|
107
|
+
// Replace placeholders in the template
|
|
108
|
+
let html = htmlTemplate
|
|
109
|
+
.replace(/{{ATTEST_STR}}/g, attestStr || '')
|
|
110
|
+
.replace(/{{UPDATE_WARNING}}/g, needsUpdateMsg ? `<div class="warning">${needsUpdateMsg}</div>` : '')
|
|
111
|
+
.replace(/{{ZIP_FILE}}/g, zipFile)
|
|
112
|
+
.replace(/{{HASH_DIGEST}}/g, hashDigest)
|
|
113
|
+
.replace(/{{ATTESTATION_HTML}}/g, attestHTML)
|
|
114
|
+
.replace(/{{FILES_TABLE_HTML}}/g, filesTableHTML);
|
|
115
|
+
return html;
|
|
116
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// FileSys.ts
|
|
4
|
+
// Copyright (c) 2024 NeoWare, Inc. All rights reserved.
|
|
5
|
+
// ======================================
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.outputToFile = outputToFile;
|
|
44
|
+
exports.makeDir = makeDir;
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const pth = __importStar(require("path"));
|
|
47
|
+
const Errors_1 = __importDefault(require("../constants/Errors"));
|
|
48
|
+
// Output a buffer to a file
|
|
49
|
+
function outputToFile(fileName, buffer, dirPath, overwrite, never, fileAttr) {
|
|
50
|
+
// get Unix file permissions
|
|
51
|
+
const _fattr = fileAttr ? (((fileAttr >>> 0) | 0) >> 16) & 0xfff : 0;
|
|
52
|
+
const _path = dirPath ? dirPath + pth.sep + fileName : fileName;
|
|
53
|
+
if (fs.existsSync(_path)) {
|
|
54
|
+
console.log('File exists: ', _path);
|
|
55
|
+
if (never)
|
|
56
|
+
return false;
|
|
57
|
+
if (!overwrite) {
|
|
58
|
+
console.log('Overwrite file: ', _path);
|
|
59
|
+
return false; // cannot overwrite
|
|
60
|
+
}
|
|
61
|
+
const stat = fs.statSync(_path);
|
|
62
|
+
if (stat.isDirectory())
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
// Check if we need to create a new folder
|
|
66
|
+
const _folder = pth.dirname(_path);
|
|
67
|
+
if (!fs.existsSync(_folder)) {
|
|
68
|
+
makeDir(_folder);
|
|
69
|
+
}
|
|
70
|
+
var fd;
|
|
71
|
+
try {
|
|
72
|
+
fd = fs.openSync(_path, "w", 438); // 0666
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
fs.chmodSync(_path, 438);
|
|
76
|
+
fd = fs.openSync(_path, "w", 438);
|
|
77
|
+
}
|
|
78
|
+
if (fd) {
|
|
79
|
+
try {
|
|
80
|
+
fs.writeSync(fd, buffer, 0, buffer.length, 0);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
fs.closeSync(fd);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (_fattr)
|
|
87
|
+
fs.chmodSync(_path, _fattr);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// Make directories tree for a given path
|
|
91
|
+
function makeDir(folder) {
|
|
92
|
+
console.log('mkDir: ', folder);
|
|
93
|
+
// Sync - make directories tree
|
|
94
|
+
function mkdirSync(fpath) {
|
|
95
|
+
let resolvedPath = fpath.split(pth.sep)[0];
|
|
96
|
+
fpath.split(pth.sep).forEach(function (name) {
|
|
97
|
+
if (!name || name.endsWith(":"))
|
|
98
|
+
return;
|
|
99
|
+
resolvedPath += pth.sep + name;
|
|
100
|
+
var stat;
|
|
101
|
+
try {
|
|
102
|
+
stat = fs.statSync(resolvedPath);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
fs.mkdirSync(resolvedPath);
|
|
106
|
+
}
|
|
107
|
+
if (stat && stat.isFile())
|
|
108
|
+
throw Errors_1.default.FILE_IN_THE_WAY.replace("%s", resolvedPath);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
mkdirSync(folder);
|
|
112
|
+
}
|
|
113
|
+
;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class for accumulating and combining SHA-256 hashes using both XOR and Merkle tree methods
|
|
3
|
+
*
|
|
4
|
+
* Usage example:
|
|
5
|
+
* ```typescript
|
|
6
|
+
* const accumulator = new HashAccumulator();
|
|
7
|
+
* accumulator.addHash('a1b2c3d4');
|
|
8
|
+
* accumulator.addHash('12345678');
|
|
9
|
+
* console.log(accumulator.xorHash()); // Outputs the accumulated XOR result
|
|
10
|
+
* console.log(accumulator.merkleRoot()); // Outputs the accumulated Merkle root
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export default class HashAccumulator {
|
|
14
|
+
private hashes;
|
|
15
|
+
private xorResult;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new HashAccumulator instance
|
|
18
|
+
* Initializes empty hash array and zero-filled XOR buffer
|
|
19
|
+
*/
|
|
20
|
+
constructor();
|
|
21
|
+
/**
|
|
22
|
+
* Adds a hash to both the XOR accumulation and hash array
|
|
23
|
+
* @param hash - Hash value as hex string or Buffer
|
|
24
|
+
* The hash must be 32 bytes (SHA-256)
|
|
25
|
+
*/
|
|
26
|
+
addHash(hash: string | Buffer): void;
|
|
27
|
+
/**
|
|
28
|
+
* Gets the accumulated XOR of all added hashes
|
|
29
|
+
* @returns Hex string of XOR result
|
|
30
|
+
*/
|
|
31
|
+
xorHash(): string;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a Merkle tree from accumulated hashes and returns the root
|
|
34
|
+
* @returns Hex string of Merkle root, or null if no hashes added
|
|
35
|
+
*/
|
|
36
|
+
merkleRoot(): string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Gets the number of hashes accumulated
|
|
39
|
+
* @returns Number of accumulated hashes
|
|
40
|
+
*/
|
|
41
|
+
leafCount(): number;
|
|
42
|
+
/**
|
|
43
|
+
* Resets the accumulator to initial state
|
|
44
|
+
* Clears hash array and zeroes XOR buffer
|
|
45
|
+
*/
|
|
46
|
+
clear(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Combines multiple hash results into a single Merkle root
|
|
49
|
+
* @param results - Array of objects containing merkleRoot properties
|
|
50
|
+
* @returns Combined Merkle root as hex string, or null if no valid roots
|
|
51
|
+
*/
|
|
52
|
+
static combineResults(results: {
|
|
53
|
+
merkleRoot?: string;
|
|
54
|
+
}[]): string | null;
|
|
55
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// HashAccumulator.ts
|
|
4
|
+
// ======================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const merkleTree_1 = require("./merkleTree");
|
|
7
|
+
/**
|
|
8
|
+
* Class for accumulating and combining SHA-256 hashes using both XOR and Merkle tree methods
|
|
9
|
+
*
|
|
10
|
+
* Usage example:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const accumulator = new HashAccumulator();
|
|
13
|
+
* accumulator.addHash('a1b2c3d4');
|
|
14
|
+
* accumulator.addHash('12345678');
|
|
15
|
+
* console.log(accumulator.xorHash()); // Outputs the accumulated XOR result
|
|
16
|
+
* console.log(accumulator.merkleRoot()); // Outputs the accumulated Merkle root
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class HashAccumulator {
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new HashAccumulator instance
|
|
22
|
+
* Initializes empty hash array and zero-filled XOR buffer
|
|
23
|
+
*/
|
|
24
|
+
constructor() {
|
|
25
|
+
this.hashes = [];
|
|
26
|
+
this.xorResult = Buffer.alloc(32, 0);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Adds a hash to both the XOR accumulation and hash array
|
|
30
|
+
* @param hash - Hash value as hex string or Buffer
|
|
31
|
+
* The hash must be 32 bytes (SHA-256)
|
|
32
|
+
*/
|
|
33
|
+
addHash(hash) {
|
|
34
|
+
// Convert hash to Buffer if it's a string
|
|
35
|
+
const hashBuffer = typeof hash === 'string'
|
|
36
|
+
? Buffer.from(hash, 'hex')
|
|
37
|
+
: hash;
|
|
38
|
+
// Add to array for Merkle tree
|
|
39
|
+
this.hashes.push(hashBuffer);
|
|
40
|
+
// XOR accumulation
|
|
41
|
+
for (let i = 0; i < 32; i++) {
|
|
42
|
+
this.xorResult[i] ^= hashBuffer[i];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gets the accumulated XOR of all added hashes
|
|
47
|
+
* @returns Hex string of XOR result
|
|
48
|
+
*/
|
|
49
|
+
xorHash() {
|
|
50
|
+
return this.xorResult.toString('hex');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a Merkle tree from accumulated hashes and returns the root
|
|
54
|
+
* @returns Hex string of Merkle root, or null if no hashes added
|
|
55
|
+
*/
|
|
56
|
+
merkleRoot() {
|
|
57
|
+
let merkleRoot = null;
|
|
58
|
+
if (this.hashes.length > 0) {
|
|
59
|
+
const tree = new merkleTree_1.MerkleTree(this.hashes, {
|
|
60
|
+
hashLeaves: false, // Leaves are already hashed
|
|
61
|
+
sortLeaves: true, // Sort leaves for consistent results
|
|
62
|
+
sortPairs: true, // Sort pairs for consistent results
|
|
63
|
+
duplicateOdd: true // Duplicate odd leaf for balanced tree
|
|
64
|
+
});
|
|
65
|
+
merkleRoot = tree.getRoot().toString('hex');
|
|
66
|
+
}
|
|
67
|
+
return merkleRoot;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Gets the number of hashes accumulated
|
|
71
|
+
* @returns Number of accumulated hashes
|
|
72
|
+
*/
|
|
73
|
+
leafCount() {
|
|
74
|
+
return this.hashes.length;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resets the accumulator to initial state
|
|
78
|
+
* Clears hash array and zeroes XOR buffer
|
|
79
|
+
*/
|
|
80
|
+
clear() {
|
|
81
|
+
this.hashes = [];
|
|
82
|
+
this.xorResult = Buffer.alloc(32, 0);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Combines multiple hash results into a single Merkle root
|
|
86
|
+
* @param results - Array of objects containing merkleRoot properties
|
|
87
|
+
* @returns Combined Merkle root as hex string, or null if no valid roots
|
|
88
|
+
*/
|
|
89
|
+
static combineResults(results) {
|
|
90
|
+
const accumulator = new HashAccumulator();
|
|
91
|
+
// Combine all hashes
|
|
92
|
+
for (const result of results) {
|
|
93
|
+
if (result.merkleRoot) {
|
|
94
|
+
accumulator.addHash(result.merkleRoot);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return accumulator.merkleRoot();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.default = HashAccumulator;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform and environment feature detection utility
|
|
3
|
+
* Provides boolean flags indicating support for various features needed by NeoZip
|
|
4
|
+
*
|
|
5
|
+
* @namespace Support
|
|
6
|
+
* @property {boolean} base64 - Always true, indicates base64 encoding support
|
|
7
|
+
* @property {boolean} array - Always true, indicates Array support
|
|
8
|
+
* @property {boolean} string - Always true, indicates String support
|
|
9
|
+
* @property {boolean} isNode - True if running in Node.js environment
|
|
10
|
+
* @property {boolean} buffer - True if Node.js Buffer is available
|
|
11
|
+
* @property {boolean} uint8array - True if Uint8Array is supported
|
|
12
|
+
* @property {boolean} arrayBuffer - True if both ArrayBuffer and Uint8Array are supported
|
|
13
|
+
* @property {boolean} blob - True if Blob creation with ArrayBuffer is supported
|
|
14
|
+
* @property {boolean} streams - True if ReadableStream and WritableStream are supported
|
|
15
|
+
* @property {boolean} fileReader - True if FileReader is supported
|
|
16
|
+
*/
|
|
17
|
+
declare const Support: {
|
|
18
|
+
/** Base64 encoding support (always true) */
|
|
19
|
+
base64: boolean;
|
|
20
|
+
/** Array support (always true) */
|
|
21
|
+
array: boolean;
|
|
22
|
+
/** String support (always true) */
|
|
23
|
+
string: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Detects if code is running in Node.js environment
|
|
26
|
+
* True if process.versions.node exists, undefined in browser
|
|
27
|
+
*/
|
|
28
|
+
isNode: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Detects if Node.js Buffer is available
|
|
31
|
+
* True in Node.js, undefined in browser
|
|
32
|
+
*/
|
|
33
|
+
buffer: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Detects support for Uint8Array typed array
|
|
36
|
+
* Used for binary data handling
|
|
37
|
+
*/
|
|
38
|
+
uint8array: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Detects support for both ArrayBuffer and Uint8Array
|
|
41
|
+
* Required for binary data operations
|
|
42
|
+
*/
|
|
43
|
+
arrayBuffer: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Detects support for Blob with ArrayBuffer
|
|
46
|
+
* Tests by attempting to create an empty ZIP Blob
|
|
47
|
+
* @returns {boolean} True if Blob creation succeeds
|
|
48
|
+
*/
|
|
49
|
+
blob: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Detects support for Streams API
|
|
52
|
+
* Checks for ReadableStream/WritableStream in browser
|
|
53
|
+
* or 'stream' module in Node.js
|
|
54
|
+
* @returns {boolean} True if streams are supported in current environment
|
|
55
|
+
*/
|
|
56
|
+
streams: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Detects support for FileReader
|
|
59
|
+
* @returns {boolean} True if FileReader is supported
|
|
60
|
+
*/
|
|
61
|
+
fileReader: boolean;
|
|
62
|
+
};
|
|
63
|
+
export default Support;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// Support.ts
|
|
4
|
+
// A utility module for detecting platform capabilities and features
|
|
5
|
+
// Copyright (c) 2024 NeoWare, Inc. All rights reserved.
|
|
6
|
+
// ======================================
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
/**
|
|
9
|
+
* Platform and environment feature detection utility
|
|
10
|
+
* Provides boolean flags indicating support for various features needed by NeoZip
|
|
11
|
+
*
|
|
12
|
+
* @namespace Support
|
|
13
|
+
* @property {boolean} base64 - Always true, indicates base64 encoding support
|
|
14
|
+
* @property {boolean} array - Always true, indicates Array support
|
|
15
|
+
* @property {boolean} string - Always true, indicates String support
|
|
16
|
+
* @property {boolean} isNode - True if running in Node.js environment
|
|
17
|
+
* @property {boolean} buffer - True if Node.js Buffer is available
|
|
18
|
+
* @property {boolean} uint8array - True if Uint8Array is supported
|
|
19
|
+
* @property {boolean} arrayBuffer - True if both ArrayBuffer and Uint8Array are supported
|
|
20
|
+
* @property {boolean} blob - True if Blob creation with ArrayBuffer is supported
|
|
21
|
+
* @property {boolean} streams - True if ReadableStream and WritableStream are supported
|
|
22
|
+
* @property {boolean} fileReader - True if FileReader is supported
|
|
23
|
+
*/
|
|
24
|
+
const Support = {
|
|
25
|
+
/** Base64 encoding support (always true) */
|
|
26
|
+
base64: true,
|
|
27
|
+
/** Array support (always true) */
|
|
28
|
+
array: true,
|
|
29
|
+
/** String support (always true) */
|
|
30
|
+
string: true,
|
|
31
|
+
/**
|
|
32
|
+
* Detects if code is running in Node.js environment
|
|
33
|
+
* True if process.versions.node exists, undefined in browser
|
|
34
|
+
*/
|
|
35
|
+
isNode: true,
|
|
36
|
+
/**
|
|
37
|
+
* Detects if Node.js Buffer is available
|
|
38
|
+
* True in Node.js, undefined in browser
|
|
39
|
+
*/
|
|
40
|
+
buffer: true,
|
|
41
|
+
/**
|
|
42
|
+
* Detects support for Uint8Array typed array
|
|
43
|
+
* Used for binary data handling
|
|
44
|
+
*/
|
|
45
|
+
uint8array: true,
|
|
46
|
+
/**
|
|
47
|
+
* Detects support for both ArrayBuffer and Uint8Array
|
|
48
|
+
* Required for binary data operations
|
|
49
|
+
*/
|
|
50
|
+
arrayBuffer: typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined",
|
|
51
|
+
/**
|
|
52
|
+
* Detects support for Blob with ArrayBuffer
|
|
53
|
+
* Tests by attempting to create an empty ZIP Blob
|
|
54
|
+
* @returns {boolean} True if Blob creation succeeds
|
|
55
|
+
*/
|
|
56
|
+
blob: true,
|
|
57
|
+
/**
|
|
58
|
+
* Detects support for Streams API
|
|
59
|
+
* Checks for ReadableStream/WritableStream in browser
|
|
60
|
+
* or 'stream' module in Node.js
|
|
61
|
+
* @returns {boolean} True if streams are supported in current environment
|
|
62
|
+
*/
|
|
63
|
+
streams: true,
|
|
64
|
+
/**
|
|
65
|
+
* Detects support for FileReader
|
|
66
|
+
* @returns {boolean} True if FileReader is supported
|
|
67
|
+
*/
|
|
68
|
+
fileReader: false
|
|
69
|
+
};
|
|
70
|
+
exports.default = Support;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const DATATYPE: {
|
|
2
|
+
STRING: string;
|
|
3
|
+
BUFFER: string;
|
|
4
|
+
ARRAY: string;
|
|
5
|
+
ARRAYBUFFER: string;
|
|
6
|
+
U8ARRAY: string;
|
|
7
|
+
BLOB: string;
|
|
8
|
+
STREAM: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const crc32update: (pCrc32: number, bval: number) => number;
|
|
11
|
+
export declare function crc32(buf: Buffer): number;
|
|
12
|
+
export declare function readBigUInt64LE(buffer: Buffer, index: number): number;
|
|
13
|
+
export declare const uMul: (a: number, b: number) => number;
|
|
14
|
+
interface StreamLike {
|
|
15
|
+
on: Function;
|
|
16
|
+
pause: Function;
|
|
17
|
+
resume: Function;
|
|
18
|
+
}
|
|
19
|
+
export declare function isStream(obj: unknown): obj is StreamLike;
|
|
20
|
+
export declare function getTypeOf(input: string | Buffer | Blob | Array<any> | ArrayBuffer | Uint8Array): string;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// Util.ts
|
|
4
|
+
// Copyright (c) 2024 NeoWare, Inc. All rights reserved.
|
|
5
|
+
// ======================================
|
|
6
|
+
// Utility functions
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.uMul = exports.crc32update = exports.DATATYPE = void 0;
|
|
12
|
+
exports.crc32 = crc32;
|
|
13
|
+
exports.readBigUInt64LE = readBigUInt64LE;
|
|
14
|
+
exports.isStream = isStream;
|
|
15
|
+
exports.getTypeOf = getTypeOf;
|
|
16
|
+
const Support_1 = __importDefault(require("./Support"));
|
|
17
|
+
const Errors_1 = __importDefault(require("../constants/Errors"));
|
|
18
|
+
exports.DATATYPE = {
|
|
19
|
+
STRING: "string",
|
|
20
|
+
BUFFER: "buffer",
|
|
21
|
+
ARRAY: "array",
|
|
22
|
+
ARRAYBUFFER: "arraybuffer",
|
|
23
|
+
U8ARRAY: "uint8array",
|
|
24
|
+
BLOB: "blob",
|
|
25
|
+
STREAM: "stream",
|
|
26
|
+
};
|
|
27
|
+
// Generate the CRC32 table
|
|
28
|
+
const crcTable = new Uint32Array(256).map((t, crc) => {
|
|
29
|
+
for (let j = 0; j < 8; j++) {
|
|
30
|
+
if (0 !== (crc & 1)) {
|
|
31
|
+
crc = (crc >>> 1) ^ 0xedb88320;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
crc >>>= 1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return crc >>> 0;
|
|
38
|
+
});
|
|
39
|
+
// crc32 byte single update (actually same function is part of utils.crc32 function :) )
|
|
40
|
+
const crc32update = (pCrc32, bval) => {
|
|
41
|
+
return crcTable[(pCrc32 ^ bval) & 0xff] ^ (pCrc32 >>> 8);
|
|
42
|
+
};
|
|
43
|
+
exports.crc32update = crc32update;
|
|
44
|
+
// Return the CRC32 of a buffer
|
|
45
|
+
function crc32(buf) {
|
|
46
|
+
if (typeof buf === "string") {
|
|
47
|
+
buf = Buffer.from(buf, "utf8");
|
|
48
|
+
}
|
|
49
|
+
// Generate crcTable
|
|
50
|
+
// if (!crcTable.length) genCRCTable();
|
|
51
|
+
let len = buf.length;
|
|
52
|
+
let crc = ~0;
|
|
53
|
+
for (let off = 0; off < len;)
|
|
54
|
+
crc = crcTable[(crc ^ buf[off++]) & 0xff] ^ (crc >>> 8);
|
|
55
|
+
// xor and cast as uint32 number
|
|
56
|
+
return ~crc >>> 0;
|
|
57
|
+
}
|
|
58
|
+
;
|
|
59
|
+
// Parse a 64-bit unsigned integer from a buffer
|
|
60
|
+
function readBigUInt64LE(buffer, index) {
|
|
61
|
+
var buf = Buffer.from(buffer.subarray(index, index + 8));
|
|
62
|
+
buf.swap64();
|
|
63
|
+
return parseInt(`0x${buf.toString("hex")}`);
|
|
64
|
+
}
|
|
65
|
+
;
|
|
66
|
+
// C-style uInt32 Multiply (discards higher bits, when JS multiply discards lower bits)
|
|
67
|
+
const uMul = (a, b) => Math.imul(a, b) >>> 0;
|
|
68
|
+
exports.uMul = uMul;
|
|
69
|
+
function isStream(obj) {
|
|
70
|
+
if (!obj || typeof obj !== 'object')
|
|
71
|
+
return false;
|
|
72
|
+
const streamLike = obj;
|
|
73
|
+
return typeof streamLike.on === "function" &&
|
|
74
|
+
typeof streamLike.pause === "function" &&
|
|
75
|
+
typeof streamLike.resume === "function";
|
|
76
|
+
}
|
|
77
|
+
// Return the type of the input.
|
|
78
|
+
// The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
|
|
79
|
+
// If the type is not supported, throw an exception.
|
|
80
|
+
function getTypeOf(input) {
|
|
81
|
+
if (typeof input === "string") {
|
|
82
|
+
if (!Support_1.default.string)
|
|
83
|
+
throw new Error(Errors_1.default.DATATYPE_STRING_UNSUPPORTED);
|
|
84
|
+
return exports.DATATYPE.STRING;
|
|
85
|
+
}
|
|
86
|
+
else if (Object.prototype.toString.call(input) === "[object Array]") {
|
|
87
|
+
if (!Support_1.default.array)
|
|
88
|
+
throw new Error(Errors_1.default.DATATYPE_ARRAY_UNSUPPORTED);
|
|
89
|
+
return exports.DATATYPE.ARRAY;
|
|
90
|
+
}
|
|
91
|
+
else if (Buffer.isBuffer(input)) {
|
|
92
|
+
if (!Support_1.default.buffer)
|
|
93
|
+
throw new Error(Errors_1.default.DATATYPE_BUFFER_UNSUPPORTED);
|
|
94
|
+
return exports.DATATYPE.BUFFER;
|
|
95
|
+
}
|
|
96
|
+
else if (input instanceof Blob) {
|
|
97
|
+
if (!Support_1.default.blob)
|
|
98
|
+
throw new Error(Errors_1.default.DATATYPE_BLOB_UNSUPPORTED);
|
|
99
|
+
return exports.DATATYPE.BLOB;
|
|
100
|
+
}
|
|
101
|
+
else if (input instanceof Uint8Array) {
|
|
102
|
+
if (!Support_1.default.uint8array)
|
|
103
|
+
throw new Error(Errors_1.default.DATATYPE_U8ARRAY_UNSUPPORTED);
|
|
104
|
+
return exports.DATATYPE.U8ARRAY;
|
|
105
|
+
}
|
|
106
|
+
else if (input instanceof ArrayBuffer) {
|
|
107
|
+
if (!Support_1.default.arrayBuffer)
|
|
108
|
+
throw new Error(Errors_1.default.DATATYPE_ARRAYBUFFER_UNSUPPORTED);
|
|
109
|
+
return exports.DATATYPE.ARRAYBUFFER;
|
|
110
|
+
}
|
|
111
|
+
else { // Add an else block to handle unsupported types
|
|
112
|
+
throw new Error(Errors_1.default.DATATYPE_UNSUPPORTED);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
;
|