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.
- package/README.md +52 -105
- package/contracts/INTEGRATION.md +338 -0
- package/contracts/NETWORKS.md +156 -0
- package/contracts/README.md +152 -0
- package/{src/server/blockchain → contracts}/constants.ts +5 -22
- package/contracts/deploy-bytecode.mjs +94 -0
- package/dist/blockchain/ZipKitMinter.d.ts +106 -0
- package/dist/blockchain/ZipKitMinter.js +347 -0
- package/dist/blockchain/ZipKitNFT.d.ts +3 -0
- package/dist/blockchain/ZipKitNFT.js +7 -0
- package/dist/blockchain/ZipKitOTS.d.ts +135 -0
- package/dist/blockchain/ZipKitOTS.js +564 -0
- package/dist/blockchain/ZipKitVerifier.d.ts +69 -0
- package/dist/blockchain/ZipKitVerifier.js +289 -0
- package/dist/{server/blockchain/WalletAnalyzer.d.ts → blockchain/ZipKitWallet.d.ts} +31 -43
- package/dist/{server/blockchain/WalletAnalyzer.js → blockchain/ZipKitWallet.js} +193 -161
- package/dist/blockchain/contracts.d.ts +14 -0
- package/dist/blockchain/contracts.js +77 -0
- package/dist/blockchain/index.d.ts +7 -0
- package/dist/blockchain/index.js +50 -0
- package/dist/{server/blockchain → blockchain}/types.d.ts +12 -34
- package/dist/{server/blockchain → blockchain}/types.js +1 -22
- package/dist/browser-index.d.ts +0 -3
- package/dist/browser-index.js +4 -5
- package/dist/browser.d.ts +0 -3
- package/dist/browser.js +4 -5
- package/dist/index.d.ts +8 -15
- package/dist/index.js +12 -24
- package/dist/server/{platform/server/ZipKitServer.d.ts → ZipKitServer.d.ts} +4 -35
- package/dist/server/{platform/server/ZipKitServer.js → ZipKitServer.js} +55 -182
- package/dist/shared/ZipEntry.js +1 -1
- package/dist/shared/ZipKit.d.ts +0 -6
- package/dist/shared/ZipKit.js +1 -18
- package/dist/shared/types.js +2 -2
- package/dist/shared/version.d.ts +2 -4
- package/dist/shared/version.js +4 -5
- package/package.json +13 -3
- package/src/blockchain/README.md +229 -0
- package/src/blockchain/ZipKitMinter.ts +470 -0
- package/src/blockchain/ZipKitNFT.ts +12 -0
- package/src/blockchain/ZipKitOTS.ts +622 -0
- package/src/blockchain/ZipKitVerifier.ts +382 -0
- package/src/blockchain/ZipKitWallet.ts +338 -0
- package/src/blockchain/contracts.ts +88 -0
- package/src/blockchain/index.ts +61 -0
- package/src/blockchain/types.ts +91 -0
- package/src/browser/{TokenVerifierBrowser.ts → TokenVerifierBrowser.ts-remove} +1 -1
- package/src/browser-index.ts +3 -3
- package/src/index.ts +10 -17
- package/src/server/README.md +25 -0
- package/src/server/ZipKitServer.ts +305 -0
- package/src/shared/ZipEntry.ts +1 -1
- package/src/shared/ZipKit.ts +1 -19
- package/src/shared/types.ts +3 -3
- package/src/shared/version.ts +3 -4
- package/src/types/modules.d.ts +11 -1
- package/contracts/Lock.sol +0 -34
- package/contracts/compile-contract.js +0 -168
- package/contracts/deploy/deploy-both-contracts.js +0 -286
- package/contracts/deploy/deploy-enhanced-contract.js +0 -197
- package/contracts/deploy/deploy-private-contract.js +0 -190
- package/contracts/deploy/deploy-public-clean.js +0 -1063
- package/contracts/deploy/deploy-public-contract.js +0 -1107
- package/contracts/deployment.config.example.js +0 -25
- package/contracts/remix-compile.js +0 -222
- package/contracts/setup-deployment.js +0 -51
- package/contracts/src/ZipFileNFT-DEPRECATED-6field.sol +0 -260
- package/contracts/src/ZipFileNFT-DEPRECATED-Enhanced.sol +0 -289
- package/dist/browser/CertificateGeneratorBrowser.d.ts +0 -75
- package/dist/browser/CertificateGeneratorBrowser.js +0 -433
- package/dist/browser/TokenVerifierBrowser.d.ts +0 -76
- package/dist/browser/TokenVerifierBrowser.js +0 -299
- package/dist/server/blockchain/NFTMinter.d.ts +0 -41
- package/dist/server/blockchain/NFTMinter.js +0 -323
- package/dist/server/blockchain/TokenQuerier.d.ts +0 -31
- package/dist/server/blockchain/TokenQuerier.js +0 -259
- package/dist/server/blockchain/TokenVerifier.d.ts +0 -20
- package/dist/server/blockchain/TokenVerifier.js +0 -395
- package/dist/server/blockchain/WalletFormatter.d.ts +0 -39
- package/dist/server/blockchain/WalletFormatter.js +0 -196
- package/dist/server/blockchain/WalletManager.d.ts +0 -46
- package/dist/server/blockchain/WalletManager.js +0 -294
- package/dist/server/blockchain/ZipMetadata.d.ts +0 -27
- package/dist/server/blockchain/ZipMetadata.js +0 -131
- package/dist/server/blockchain/ZipTokenProcessor.d.ts +0 -44
- package/dist/server/blockchain/ZipTokenProcessor.js +0 -204
- package/dist/server/blockchain/constants.d.ts +0 -102
- package/dist/server/blockchain/constants.js +0 -968
- package/dist/server/blockchain/index.d.ts +0 -9
- package/dist/server/blockchain/index.js +0 -44
- package/dist/server/blockchain/test-certificate.d.ts +0 -8
- package/dist/server/blockchain/test-certificate.js +0 -100
- package/dist/server/platform/servercomponents/ZipKitOTS.d.ts +0 -91
- package/dist/server/platform/servercomponents/ZipKitOTS.js +0 -271
- package/examples/unzip-token.ts +0 -488
- package/examples/zip-token.ts +0 -604
- package/src/server/blockchain/NFTMinter.ts +0 -357
- package/src/server/blockchain/TokenQuerier.ts +0 -287
- package/src/server/blockchain/TokenVerifier.ts +0 -453
- package/src/server/blockchain/WalletAnalyzer.ts +0 -397
- package/src/server/blockchain/WalletFormatter.ts +0 -206
- package/src/server/blockchain/WalletManager.ts +0 -294
- package/src/server/blockchain/ZipMetadata.ts +0 -117
- package/src/server/blockchain/ZipTokenProcessor.ts +0 -234
- package/src/server/blockchain/index.ts +0 -42
- package/src/server/blockchain/test-certificate.ts +0 -137
- package/src/server/blockchain/types.ts +0 -134
- package/src/server/platform/server/ZipKitServer.ts +0 -459
- package/src/server/platform/servercomponents/ZipKitOTS.ts +0 -313
- package/src/server/platform/servercomponents/opentimestamps.d.ts +0 -23
- /package/contracts/{bytecode.txt → NZIP-NFT-bytecode.txt} +0 -0
- /package/dist/{server/blockchain → blockchain}/CertificateToken.d.ts +0 -0
- /package/dist/{server/blockchain → blockchain}/CertificateToken.js +0 -0
- /package/src/{server/blockchain → blockchain}/CertificateToken.ts +0 -0
- /package/src/browser/{CertificateGeneratorBrowser.ts → CertificateGeneratorBrowser.ts-remove} +0 -0
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// ======================================
|
|
3
|
-
// TokenVerifier.ts
|
|
4
|
-
// Blockchain token verification utilities for ZIP archives
|
|
5
|
-
// Copyright (c) 2024 NeoWare, Inc. All rights reserved.
|
|
6
|
-
// ======================================
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.checkForTokenization = checkForTokenization;
|
|
42
|
-
const Headers_1 = require("../../shared/constants/Headers");
|
|
43
|
-
const ZipMetadata_1 = require("./ZipMetadata");
|
|
44
|
-
const CertificateToken_1 = require("./CertificateToken");
|
|
45
|
-
// Network configuration for blockchain queries
|
|
46
|
-
const NETWORK_CONFIG = {
|
|
47
|
-
'Base Sepolia': {
|
|
48
|
-
rpcUrls: [
|
|
49
|
-
'https://sepolia.base.org',
|
|
50
|
-
'https://base-sepolia.g.alchemy.com/v2/demo',
|
|
51
|
-
'https://base-sepolia-rpc.publicnode.com',
|
|
52
|
-
'https://base-sepolia.blockpi.network/v1/rpc/public'
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
'Base Mainnet': {
|
|
56
|
-
rpcUrls: [
|
|
57
|
-
'https://mainnet.base.org',
|
|
58
|
-
'https://base-mainnet.g.alchemy.com/v2/demo',
|
|
59
|
-
'https://base-rpc.publicnode.com',
|
|
60
|
-
'https://base.blockpi.network/v1/rpc/public'
|
|
61
|
-
]
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Checks if the ZIP file contains NFT token metadata and verifies the merkle root
|
|
66
|
-
*/
|
|
67
|
-
async function checkForTokenization(zipKit, options = {}) {
|
|
68
|
-
const zipEntries = zipKit.getDirectory();
|
|
69
|
-
// Look for the tokenized metadata file
|
|
70
|
-
const tokenEntry = zipEntries.find(entry => entry.filename === Headers_1.TOKENIZED_METADATA);
|
|
71
|
-
if (tokenEntry) {
|
|
72
|
-
console.log('\n🔍 Tokenized ZIP detected!');
|
|
73
|
-
console.log('═'.repeat(60));
|
|
74
|
-
try {
|
|
75
|
-
// Extract the token metadata
|
|
76
|
-
console.log('📄 Reading token metadata...');
|
|
77
|
-
const tokenData = await zipKit.extract(tokenEntry);
|
|
78
|
-
if (tokenData) {
|
|
79
|
-
const tokenContent = tokenData.toString('utf8');
|
|
80
|
-
const tokenMetadata = JSON.parse(tokenContent);
|
|
81
|
-
// Validate token metadata structure - only accept full NFT tokens
|
|
82
|
-
if (ZipMetadata_1.ZipMetadata.validateTokenInfo(tokenMetadata) && tokenMetadata) {
|
|
83
|
-
console.log('✅ Valid NFT token metadata found');
|
|
84
|
-
// Display token information
|
|
85
|
-
console.log(ZipMetadata_1.ZipMetadata.createTokenSummary(tokenMetadata));
|
|
86
|
-
// Automatically verify token merkle root unless skipped or hash calculation is disabled
|
|
87
|
-
if (options.skipHash) {
|
|
88
|
-
console.log('\n⏭️ Token verification skipped (--skip-hash prevents merkle root calculation)');
|
|
89
|
-
console.log('💡 Use -H flag to enable hash calculation and token verification');
|
|
90
|
-
return {
|
|
91
|
-
isTokenized: true,
|
|
92
|
-
tokenMetadata,
|
|
93
|
-
calculatedMerkleRoot: null,
|
|
94
|
-
blockchainMerkleRoot: null,
|
|
95
|
-
verificationPassed: false
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
else if (options.skipToken) {
|
|
99
|
-
console.log('\n⏭️ Token verification skipped (--skip-token flag)');
|
|
100
|
-
console.log('⚠️ WARNING: Archive integrity cannot be verified without token validation');
|
|
101
|
-
return {
|
|
102
|
-
isTokenized: true,
|
|
103
|
-
tokenMetadata,
|
|
104
|
-
calculatedMerkleRoot: null,
|
|
105
|
-
blockchainMerkleRoot: null,
|
|
106
|
-
verificationPassed: false
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
console.log('\n🔒 Verifying archive integrity against blockchain...');
|
|
111
|
-
const calculatedMerkleRoot = calculateMerkleRootExcludingToken(zipKit);
|
|
112
|
-
if (calculatedMerkleRoot && tokenMetadata) {
|
|
113
|
-
// Query blockchain for the actual merkle root (full NFT tokens only)
|
|
114
|
-
console.log('🌐 Querying blockchain for stored merkle root...');
|
|
115
|
-
const blockchainMerkleRoot = await queryBlockchainMerkleRoot(tokenMetadata);
|
|
116
|
-
if (blockchainMerkleRoot) {
|
|
117
|
-
console.log(`Blockchain Merkle Root: ${blockchainMerkleRoot}`);
|
|
118
|
-
console.log(`Calculated Merkle Root: ${calculatedMerkleRoot}`);
|
|
119
|
-
if (blockchainMerkleRoot === calculatedMerkleRoot) {
|
|
120
|
-
console.log('✅ BLOCKCHAIN VERIFICATION: PASSED');
|
|
121
|
-
console.log(' Archive contents match the blockchain-recorded merkle root!');
|
|
122
|
-
// Generate certificate if requested
|
|
123
|
-
let certificatePath;
|
|
124
|
-
if (options.generateCertificate) {
|
|
125
|
-
certificatePath = await generateCertificate(tokenMetadata, options.zipFileName || 'unknown.zip', zipEntries, {
|
|
126
|
-
merkleRootMatches: true,
|
|
127
|
-
blockchainMerkleRoot,
|
|
128
|
-
calculatedMerkleRoot,
|
|
129
|
-
verificationStatus: 'PASSED',
|
|
130
|
-
verificationTime: Math.floor(Date.now() / 1000)
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
isTokenized: true,
|
|
135
|
-
tokenMetadata,
|
|
136
|
-
calculatedMerkleRoot,
|
|
137
|
-
blockchainMerkleRoot,
|
|
138
|
-
verificationPassed: true,
|
|
139
|
-
certificatePath
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
console.log('❌ BLOCKCHAIN VERIFICATION: FAILED');
|
|
144
|
-
console.log(' WARNING: Archive contents do not match the blockchain record!');
|
|
145
|
-
console.log(' This archive may have been tampered with or corrupted.');
|
|
146
|
-
// Generate certificate for failed verification if requested
|
|
147
|
-
let certificatePath;
|
|
148
|
-
if (options.generateCertificate) {
|
|
149
|
-
certificatePath = await generateCertificate(tokenMetadata, options.zipFileName || 'unknown.zip', zipEntries, {
|
|
150
|
-
merkleRootMatches: false,
|
|
151
|
-
blockchainMerkleRoot,
|
|
152
|
-
calculatedMerkleRoot,
|
|
153
|
-
verificationStatus: 'FAILED',
|
|
154
|
-
verificationTime: Math.floor(Date.now() / 1000)
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
isTokenized: true,
|
|
159
|
-
tokenMetadata,
|
|
160
|
-
calculatedMerkleRoot,
|
|
161
|
-
blockchainMerkleRoot,
|
|
162
|
-
verificationPassed: false,
|
|
163
|
-
certificatePath
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
console.log('❌ BLOCKCHAIN VERIFICATION: FAILED');
|
|
169
|
-
console.log(' Could not retrieve merkle root from blockchain');
|
|
170
|
-
console.log(' Token metadata may be invalid or network unreachable');
|
|
171
|
-
// Handle unavailable blockchain verification
|
|
172
|
-
let certificatePath;
|
|
173
|
-
if (options.generateCertificate && tokenMetadata) {
|
|
174
|
-
certificatePath = await generateCertificate(tokenMetadata, options.zipFileName || 'unknown.zip', zipEntries, {
|
|
175
|
-
merkleRootMatches: false,
|
|
176
|
-
blockchainMerkleRoot: "Unavailable",
|
|
177
|
-
calculatedMerkleRoot: zipKit.getMerkleRoot() || 'Unable to calculate',
|
|
178
|
-
verificationStatus: 'UNAVAILABLE',
|
|
179
|
-
verificationTime: Math.floor(Date.now() / 1000)
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
isTokenized: true,
|
|
184
|
-
tokenMetadata,
|
|
185
|
-
calculatedMerkleRoot,
|
|
186
|
-
blockchainMerkleRoot: null,
|
|
187
|
-
verificationPassed: false,
|
|
188
|
-
certificatePath
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
console.log('❌ Invalid token metadata structure');
|
|
196
|
-
console.log(' This archive contains invalid or unsupported token metadata');
|
|
197
|
-
console.log(' Only full NFT tokens with blockchain verification are supported');
|
|
198
|
-
return {
|
|
199
|
-
isTokenized: false,
|
|
200
|
-
tokenMetadata: null,
|
|
201
|
-
calculatedMerkleRoot: null,
|
|
202
|
-
blockchainMerkleRoot: null,
|
|
203
|
-
verificationPassed: false
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
console.log('❌ Could not read token metadata');
|
|
209
|
-
return {
|
|
210
|
-
isTokenized: false,
|
|
211
|
-
tokenMetadata: null,
|
|
212
|
-
calculatedMerkleRoot: null,
|
|
213
|
-
blockchainMerkleRoot: null,
|
|
214
|
-
verificationPassed: false
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
console.error('❌ Error reading token metadata:', error);
|
|
220
|
-
return {
|
|
221
|
-
isTokenized: false,
|
|
222
|
-
tokenMetadata: null,
|
|
223
|
-
calculatedMerkleRoot: null,
|
|
224
|
-
blockchainMerkleRoot: null,
|
|
225
|
-
verificationPassed: false
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
console.log('═'.repeat(60));
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
console.log('\n📦 Standard ZIP archive (not tokenized)');
|
|
232
|
-
if (options.skipHash) {
|
|
233
|
-
console.log('⏭️ SHA-256 hash validation disabled');
|
|
234
|
-
}
|
|
235
|
-
return {
|
|
236
|
-
isTokenized: false,
|
|
237
|
-
tokenMetadata: null,
|
|
238
|
-
calculatedMerkleRoot: null,
|
|
239
|
-
blockchainMerkleRoot: null,
|
|
240
|
-
verificationPassed: false
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
// Fallback return for cases where calculatedMerkleRoot is null
|
|
244
|
-
return {
|
|
245
|
-
isTokenized: true,
|
|
246
|
-
tokenMetadata: null,
|
|
247
|
-
calculatedMerkleRoot: null,
|
|
248
|
-
blockchainMerkleRoot: null,
|
|
249
|
-
verificationPassed: false
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Queries the blockchain to get the actual merkle root stored in the smart contract
|
|
254
|
-
*/
|
|
255
|
-
async function queryBlockchainMerkleRoot(tokenMetadata) {
|
|
256
|
-
try {
|
|
257
|
-
const { ethers } = await Promise.resolve().then(() => __importStar(require('ethers')));
|
|
258
|
-
const networkConfig = NETWORK_CONFIG[tokenMetadata.network];
|
|
259
|
-
if (!networkConfig) {
|
|
260
|
-
console.log(`⚠️ Unsupported network: ${tokenMetadata.network}`);
|
|
261
|
-
return null;
|
|
262
|
-
}
|
|
263
|
-
// Try multiple RPC endpoints
|
|
264
|
-
for (const rpcUrl of networkConfig.rpcUrls) {
|
|
265
|
-
try {
|
|
266
|
-
console.log(` Trying RPC: ${rpcUrl}`);
|
|
267
|
-
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
268
|
-
// Test connection
|
|
269
|
-
await provider.getBlockNumber();
|
|
270
|
-
// Use hardcoded ABI for NZIP NFT Contract v2.0
|
|
271
|
-
const CONTRACT_ABI = [
|
|
272
|
-
{
|
|
273
|
-
"inputs": [{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }],
|
|
274
|
-
"name": "getZipFileInfo",
|
|
275
|
-
"outputs": [
|
|
276
|
-
{
|
|
277
|
-
"components": [
|
|
278
|
-
{ "internalType": "string", "name": "fileName", "type": "string" },
|
|
279
|
-
{ "internalType": "string", "name": "merkleRootHash", "type": "string" },
|
|
280
|
-
{ "internalType": "string", "name": "ipfsHash", "type": "string" },
|
|
281
|
-
{ "internalType": "address", "name": "creator", "type": "address" },
|
|
282
|
-
{ "internalType": "uint256", "name": "creationTimestamp", "type": "uint256" },
|
|
283
|
-
{ "internalType": "uint256", "name": "tokenizationTime", "type": "uint256" },
|
|
284
|
-
{ "internalType": "uint256", "name": "blockNumber", "type": "uint256" }
|
|
285
|
-
],
|
|
286
|
-
"internalType": "struct ZipFileNFT.ZipFileInfo",
|
|
287
|
-
"name": "",
|
|
288
|
-
"type": "tuple"
|
|
289
|
-
}
|
|
290
|
-
],
|
|
291
|
-
"stateMutability": "view",
|
|
292
|
-
"type": "function"
|
|
293
|
-
}
|
|
294
|
-
];
|
|
295
|
-
// Create contract instance
|
|
296
|
-
const contract = new ethers.Contract(tokenMetadata.contractAddress, CONTRACT_ABI, provider);
|
|
297
|
-
// Call getZipFileInfo to get the blockchain-stored merkle root
|
|
298
|
-
const zipInfo = await contract.getZipFileInfo(tokenMetadata.tokenId);
|
|
299
|
-
console.log(` ✅ Connected to blockchain successfully`);
|
|
300
|
-
return zipInfo.merkleRootHash;
|
|
301
|
-
}
|
|
302
|
-
catch (error) {
|
|
303
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
304
|
-
console.log(` ❌ RPC failed: ${errorMessage.substring(0, 80)}...`);
|
|
305
|
-
continue;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
console.log(`⚠️ All RPC endpoints failed for network: ${tokenMetadata.network}`);
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
catch (error) {
|
|
312
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
313
|
-
console.log(`⚠️ Blockchain query error: ${errorMessage}`);
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Calculates the merkle root excluding the token metadata file
|
|
319
|
-
* This represents the original content that was tokenized
|
|
320
|
-
*/
|
|
321
|
-
function calculateMerkleRootExcludingToken(zipKit) {
|
|
322
|
-
try {
|
|
323
|
-
// Get all entries except the token file
|
|
324
|
-
const zipEntries = zipKit.getDirectory();
|
|
325
|
-
const contentEntries = zipEntries.filter(entry => entry.filename !== Headers_1.TOKENIZED_METADATA);
|
|
326
|
-
if (contentEntries.length === 0) {
|
|
327
|
-
console.log('⚠️ No content files found for merkle root calculation');
|
|
328
|
-
return null;
|
|
329
|
-
}
|
|
330
|
-
console.log(`📊 Calculating merkle root for ${contentEntries.length} content files...`);
|
|
331
|
-
// For each content entry, ensure we have SHA-256 hash calculated
|
|
332
|
-
for (const entry of contentEntries) {
|
|
333
|
-
if (!entry.sha256) {
|
|
334
|
-
// Extract the file to calculate its SHA-256 hash
|
|
335
|
-
try {
|
|
336
|
-
const fileData = zipKit.extract(entry);
|
|
337
|
-
// The extraction process should calculate and set the SHA-256 hash
|
|
338
|
-
console.log(` Calculated SHA-256 for: ${entry.filename}`);
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
console.log(` ⚠️ Could not process: ${entry.filename}`);
|
|
342
|
-
return null; // Cannot calculate merkle root without all hashes
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Now calculate the merkle root from the content files
|
|
347
|
-
const merkleRoot = zipKit.getMerkleRoot();
|
|
348
|
-
return merkleRoot;
|
|
349
|
-
}
|
|
350
|
-
catch (error) {
|
|
351
|
-
console.error('Error calculating merkle root:', error);
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Generates a token certificate
|
|
357
|
-
*/
|
|
358
|
-
async function generateCertificate(tokenMetadata, zipFileName, zipEntries, blockchainVerification) {
|
|
359
|
-
console.log('\n📜 Generating Token Certificate...');
|
|
360
|
-
try {
|
|
361
|
-
// Prepare token information
|
|
362
|
-
const tokenInfo = {
|
|
363
|
-
tokenId: tokenMetadata.tokenId,
|
|
364
|
-
contractAddress: tokenMetadata.contractAddress,
|
|
365
|
-
network: tokenMetadata.network,
|
|
366
|
-
transactionHash: tokenMetadata.transactionHash
|
|
367
|
-
};
|
|
368
|
-
// Prepare file information from ZIP entries
|
|
369
|
-
const zipFiles = [];
|
|
370
|
-
for (const entry of zipEntries) {
|
|
371
|
-
// Skip the token file itself and directories
|
|
372
|
-
if (entry.filename !== Headers_1.TOKENIZED_METADATA &&
|
|
373
|
-
!entry.isDirectory &&
|
|
374
|
-
entry.sha256) {
|
|
375
|
-
zipFiles.push({
|
|
376
|
-
filename: entry.filename,
|
|
377
|
-
size: entry.uncompressedSize,
|
|
378
|
-
date: entry.toFormattedUTCDateString(),
|
|
379
|
-
hash: entry.sha256
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
// Generate the certificate
|
|
384
|
-
const certificateHTML = (0, CertificateToken_1.createTokenCertificate)(tokenInfo, zipFileName, blockchainVerification, undefined, // walletInfo
|
|
385
|
-
zipFiles);
|
|
386
|
-
// Save the certificate
|
|
387
|
-
const certPath = (0, CertificateToken_1.saveCertificate)(zipFileName, certificateHTML);
|
|
388
|
-
console.log(`✅ Certificate generated: ${certPath}`);
|
|
389
|
-
return certPath;
|
|
390
|
-
}
|
|
391
|
-
catch (error) {
|
|
392
|
-
console.error('❌ Failed to generate certificate:', error);
|
|
393
|
-
throw error;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { WalletBasicInfo, NZipTokenDetails, TokenInfo, TokenScanResult } from './WalletAnalyzer';
|
|
2
|
-
export declare class WalletFormatter {
|
|
3
|
-
/**
|
|
4
|
-
* Display basic wallet information
|
|
5
|
-
*/
|
|
6
|
-
static displayWalletBasics(walletInfo: WalletBasicInfo): void;
|
|
7
|
-
/**
|
|
8
|
-
* Display contract information
|
|
9
|
-
*/
|
|
10
|
-
static displayContractInfo(contractInfo: {
|
|
11
|
-
name: string;
|
|
12
|
-
symbol: string;
|
|
13
|
-
totalSupply: string;
|
|
14
|
-
} | null, isLegacy?: boolean): void;
|
|
15
|
-
/**
|
|
16
|
-
* Display token scan progress
|
|
17
|
-
*/
|
|
18
|
-
static displayTokenScanProgress(scanResult: TokenScanResult): void;
|
|
19
|
-
/**
|
|
20
|
-
* Display detailed NZIP token information
|
|
21
|
-
*/
|
|
22
|
-
static displayNZipTokenDetails(tokenDetails: NZipTokenDetails[], scanResult: TokenScanResult, contractAddress: string): void;
|
|
23
|
-
/**
|
|
24
|
-
* Display ERC-20 token information
|
|
25
|
-
*/
|
|
26
|
-
static displayERC20Tokens(tokens: TokenInfo[]): void;
|
|
27
|
-
/**
|
|
28
|
-
* Display NFT collection information
|
|
29
|
-
*/
|
|
30
|
-
static displayNFTCollections(nfts: TokenInfo[]): void;
|
|
31
|
-
/**
|
|
32
|
-
* Display token scan summary
|
|
33
|
-
*/
|
|
34
|
-
static displayTokenScanSummary(erc20Count: number, totalScanned: number): void;
|
|
35
|
-
/**
|
|
36
|
-
* Display error messages for contract connection issues
|
|
37
|
-
*/
|
|
38
|
-
static displayContractError(error: any, contractAddress: string): void;
|
|
39
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WalletFormatter = void 0;
|
|
4
|
-
class WalletFormatter {
|
|
5
|
-
/**
|
|
6
|
-
* Display basic wallet information
|
|
7
|
-
*/
|
|
8
|
-
static displayWalletBasics(walletInfo) {
|
|
9
|
-
console.log('\n💰 Basic Wallet Information');
|
|
10
|
-
console.log('─'.repeat(50));
|
|
11
|
-
console.log(`ETH Balance: ${walletInfo.ethBalance} ETH`);
|
|
12
|
-
console.log(`Transaction Count: ${walletInfo.transactionCount}`);
|
|
13
|
-
console.log(`Network Name: ${walletInfo.networkName}`);
|
|
14
|
-
console.log(`Chain ID: ${walletInfo.chainId}`);
|
|
15
|
-
console.log(`Latest Block: ${walletInfo.latestBlock}`);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Display contract information
|
|
19
|
-
*/
|
|
20
|
-
static displayContractInfo(contractInfo, isLegacy = false) {
|
|
21
|
-
if (contractInfo) {
|
|
22
|
-
console.log(`Contract Name: ${contractInfo.name}`);
|
|
23
|
-
console.log(`Contract Symbol: ${contractInfo.symbol}`);
|
|
24
|
-
console.log(`Total Supply: ${contractInfo.totalSupply}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
console.log('Contract Info: Unable to fetch');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Display token scan progress
|
|
32
|
-
*/
|
|
33
|
-
static displayTokenScanProgress(scanResult) {
|
|
34
|
-
console.log('Searching for tokens owned by this address...');
|
|
35
|
-
if (scanResult.searchMethod === 'recent-events') {
|
|
36
|
-
console.log(' 🔍 Trying recent events (last 50k blocks)...');
|
|
37
|
-
console.log(` ✅ Found ${scanResult.foundTokens.length} tokens from recent events`);
|
|
38
|
-
}
|
|
39
|
-
else if (scanResult.searchMethod === 'iteration') {
|
|
40
|
-
console.log(' 🔍 Trying recent events (last 50k blocks)...');
|
|
41
|
-
console.log(' ❌ Recent events failed, trying alternative methods...');
|
|
42
|
-
console.log(' 🔍 Checking token ownership by iteration...');
|
|
43
|
-
console.log(` ✅ Found ${scanResult.foundTokens.length} tokens by iteration`);
|
|
44
|
-
}
|
|
45
|
-
else if (scanResult.searchMethod === 'common-ids') {
|
|
46
|
-
console.log(' 🔍 Trying recent events (last 50k blocks)...');
|
|
47
|
-
console.log(' ❌ Recent events failed, trying alternative methods...');
|
|
48
|
-
console.log(' 🔍 Checking token ownership by iteration...');
|
|
49
|
-
console.log(' ⚠️ No tokens found by iteration, checking common IDs...');
|
|
50
|
-
console.log(' 🔍 Checking common token IDs (0-19)...');
|
|
51
|
-
console.log(` ✅ Found ${scanResult.foundTokens.length} tokens from common IDs`);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
console.log(' 🔍 Trying recent events (last 50k blocks)...');
|
|
55
|
-
console.log(' ❌ Recent events failed, trying alternative methods...');
|
|
56
|
-
console.log(' 🔍 Checking token ownership by iteration...');
|
|
57
|
-
console.log(' ⚠️ No tokens found by iteration, checking common IDs...');
|
|
58
|
-
console.log(' 🔍 Checking common token IDs (0-19)...');
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Display detailed NZIP token information
|
|
63
|
-
*/
|
|
64
|
-
static displayNZipTokenDetails(tokenDetails, scanResult, contractAddress) {
|
|
65
|
-
if (tokenDetails.length > 0) {
|
|
66
|
-
console.log(`\n✅ Found ${tokenDetails.length} NZIP token(s) using ${scanResult.searchMethod}:`);
|
|
67
|
-
console.log('📋 Your NZIP Token Details:');
|
|
68
|
-
console.log('═'.repeat(80));
|
|
69
|
-
for (const token of tokenDetails.sort((a, b) => parseInt(a.tokenId) - parseInt(b.tokenId))) {
|
|
70
|
-
console.log(`\n🎯 Token ID ${token.tokenId}:`);
|
|
71
|
-
console.log(` File Name: ${token.fileName}`);
|
|
72
|
-
console.log(` Merkle Root: ${token.merkleRootHash}`);
|
|
73
|
-
// Convert timestamps to dates
|
|
74
|
-
const creationDate = new Date(token.creationTimestamp * 1000);
|
|
75
|
-
const tokenizationDate = new Date(token.tokenizationTime * 1000);
|
|
76
|
-
// Format dates in a more readable format
|
|
77
|
-
const formatOptions = {
|
|
78
|
-
year: 'numeric',
|
|
79
|
-
month: 'short',
|
|
80
|
-
day: '2-digit',
|
|
81
|
-
hour: '2-digit',
|
|
82
|
-
minute: '2-digit',
|
|
83
|
-
second: '2-digit',
|
|
84
|
-
timeZoneName: 'short'
|
|
85
|
-
};
|
|
86
|
-
console.log(` Created: ${creationDate.toLocaleDateString('en-US', formatOptions)}`);
|
|
87
|
-
console.log(` Tokenized: ${tokenizationDate.toLocaleDateString('en-US', formatOptions)}`);
|
|
88
|
-
// Show time difference between creation and tokenization
|
|
89
|
-
const timeDiffSeconds = token.tokenizationTime - token.creationTimestamp;
|
|
90
|
-
if (timeDiffSeconds > 0) {
|
|
91
|
-
if (timeDiffSeconds < 60) {
|
|
92
|
-
console.log(` Tokenization Delay: ${timeDiffSeconds} seconds`);
|
|
93
|
-
}
|
|
94
|
-
else if (timeDiffSeconds < 3600) {
|
|
95
|
-
console.log(` Tokenization Delay: ${Math.round(timeDiffSeconds / 60)} minutes`);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
console.log(` Tokenization Delay: ${Math.round(timeDiffSeconds / 3600)} hours`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (token.ipfsHash && token.ipfsHash !== '') {
|
|
102
|
-
console.log(` IPFS Hash: ${token.ipfsHash}`);
|
|
103
|
-
}
|
|
104
|
-
console.log(` Creator: ${token.creator}`);
|
|
105
|
-
// Calculate age since creation (using current time)
|
|
106
|
-
const now = Date.now();
|
|
107
|
-
const ageMs = now - (token.creationTimestamp * 1000);
|
|
108
|
-
const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
|
|
109
|
-
const ageHours = Math.floor((ageMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
110
|
-
const ageMinutes = Math.floor((ageMs % (1000 * 60 * 60)) / (1000 * 60));
|
|
111
|
-
if (ageDays > 0) {
|
|
112
|
-
console.log(` Age: ${ageDays} days, ${ageHours} hours`);
|
|
113
|
-
}
|
|
114
|
-
else if (ageHours > 0) {
|
|
115
|
-
console.log(` Age: ${ageHours} hours, ${ageMinutes} minutes`);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
console.log(` Age: ${ageMinutes} minutes`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
console.log('\n❌ No NZIP tokens found for this address');
|
|
124
|
-
console.log('\n💡 This could mean:');
|
|
125
|
-
console.log(' • You don\'t own any NZIP tokens on this network');
|
|
126
|
-
console.log(' • The tokens are on a different contract or network');
|
|
127
|
-
console.log(' • There are temporary RPC connectivity issues');
|
|
128
|
-
console.log('\n🔧 Try these troubleshooting steps:');
|
|
129
|
-
console.log(' • Verify you\'re on the correct network (--network flag)');
|
|
130
|
-
console.log(' • Check if you have tokens on a different contract (--contract flag)');
|
|
131
|
-
console.log(' • Try again in a few minutes if RPC is experiencing issues');
|
|
132
|
-
console.log(` • Verify the contract address: ${contractAddress}`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Display ERC-20 token information
|
|
137
|
-
*/
|
|
138
|
-
static displayERC20Tokens(tokens) {
|
|
139
|
-
if (tokens.length > 0) {
|
|
140
|
-
console.log(`\n💰 ERC-20 Token Balances:`);
|
|
141
|
-
for (const token of tokens) {
|
|
142
|
-
console.log(`\n 💎 ${token.symbol} (${token.name}):`);
|
|
143
|
-
console.log(` Contract: ${token.address}`);
|
|
144
|
-
console.log(` Balance: ${token.balance} ${token.symbol}`);
|
|
145
|
-
console.log(` Decimals: ${token.decimals}`);
|
|
146
|
-
// Add USD value estimation for major stablecoins
|
|
147
|
-
if (['USDC', 'USDT', 'DAI', 'USDbC'].includes(token.symbol)) {
|
|
148
|
-
console.log(` Est. USD Value: ~$${token.balance}`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Display NFT collection information
|
|
155
|
-
*/
|
|
156
|
-
static displayNFTCollections(nfts) {
|
|
157
|
-
console.log(`\n🖼️ Other NFT Collections:`);
|
|
158
|
-
if (nfts.length > 0) {
|
|
159
|
-
for (const nft of nfts) {
|
|
160
|
-
console.log(`\n 🖼️ ${nft.symbol} (${nft.name}):`);
|
|
161
|
-
console.log(` Contract: ${nft.address}`);
|
|
162
|
-
console.log(` NFTs Owned: ${nft.balance}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
console.log(` No other NFT collections found`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Display token scan summary
|
|
171
|
-
*/
|
|
172
|
-
static displayTokenScanSummary(erc20Count, totalScanned) {
|
|
173
|
-
console.log(`\n📊 Token Scan Summary:`);
|
|
174
|
-
console.log(` ERC-20 Tokens Found: ${erc20Count}`);
|
|
175
|
-
console.log(` Total Tokens Scanned: ${totalScanned}`);
|
|
176
|
-
if (erc20Count === 0) {
|
|
177
|
-
console.log(`\n💡 No tokens found. This could mean:`);
|
|
178
|
-
console.log(` • This is a new wallet with no token activity`);
|
|
179
|
-
console.log(` • Tokens are on a different network`);
|
|
180
|
-
console.log(` • You have tokens not in our common token list`);
|
|
181
|
-
console.log(` • There are temporary RPC connectivity issues`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Display error messages for contract connection issues
|
|
186
|
-
*/
|
|
187
|
-
static displayContractError(error, contractAddress) {
|
|
188
|
-
console.error('❌ Error connecting to NZIP contract:', error);
|
|
189
|
-
console.log('\n🔧 Troubleshooting suggestions:');
|
|
190
|
-
console.log(' • Check if the contract address is correct');
|
|
191
|
-
console.log(' • Verify you\'re on the right network');
|
|
192
|
-
console.log(' • Try again later if RPC is experiencing issues');
|
|
193
|
-
console.log(' • Use --contract flag to specify a different contract address');
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
exports.WalletFormatter = WalletFormatter;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
|
-
import { WalletSetupResult, MintingOptions } from './types';
|
|
3
|
-
export declare class WalletManager {
|
|
4
|
-
private wallet;
|
|
5
|
-
private provider;
|
|
6
|
-
/**
|
|
7
|
-
* Prompts the user for input
|
|
8
|
-
*/
|
|
9
|
-
private promptUser;
|
|
10
|
-
/**
|
|
11
|
-
* Looks for existing wallet files in the current directory and wallet subdirectory
|
|
12
|
-
*/
|
|
13
|
-
private findExistingWallets;
|
|
14
|
-
/**
|
|
15
|
-
* Loads wallet information from a file
|
|
16
|
-
*/
|
|
17
|
-
private loadWalletFromFile;
|
|
18
|
-
/**
|
|
19
|
-
* Sets up a Base wallet for token operations
|
|
20
|
-
*/
|
|
21
|
-
setupWallet(options: MintingOptions): Promise<WalletSetupResult>;
|
|
22
|
-
/**
|
|
23
|
-
* Creates a new wallet and saves it to file
|
|
24
|
-
*/
|
|
25
|
-
private createNewWallet;
|
|
26
|
-
/**
|
|
27
|
-
* Connects to the specified blockchain network
|
|
28
|
-
*/
|
|
29
|
-
private connectToNetwork;
|
|
30
|
-
/**
|
|
31
|
-
* Gets the current wallet instance
|
|
32
|
-
*/
|
|
33
|
-
getWallet(): ethers.Wallet | null;
|
|
34
|
-
/**
|
|
35
|
-
* Gets the current provider instance
|
|
36
|
-
*/
|
|
37
|
-
getProvider(): ethers.JsonRpcProvider | null;
|
|
38
|
-
/**
|
|
39
|
-
* Checks if wallet is connected and ready for transactions
|
|
40
|
-
*/
|
|
41
|
-
isReady(): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Checks if provider is connected
|
|
44
|
-
*/
|
|
45
|
-
isOnline(): boolean;
|
|
46
|
-
}
|