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
|
@@ -33,11 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.WalletAnalyzer = void 0;
|
|
37
|
-
const ethers_1 = require("ethers");
|
|
36
|
+
exports.WalletAnalyzer = exports.ZipKitWallet = void 0;
|
|
38
37
|
const fs = __importStar(require("fs"));
|
|
39
38
|
const path = __importStar(require("path"));
|
|
40
|
-
|
|
39
|
+
const readline = __importStar(require("readline"));
|
|
40
|
+
const ethers_1 = require("ethers");
|
|
41
|
+
const types_1 = require("./types");
|
|
41
42
|
const NZIP_CONTRACT_ABI = [
|
|
42
43
|
"function getZipFileInfo(uint256 tokenId) view returns (tuple(string fileName, string merkleRootHash, uint256 creationTimestamp, string ipfsHash, uint256 tokenizationTime, address creator))",
|
|
43
44
|
"function ownerOf(uint256 tokenId) view returns (address)",
|
|
@@ -47,58 +48,188 @@ const NZIP_CONTRACT_ABI = [
|
|
|
47
48
|
"function getTokensByMerkleRoot(string merkleRootHash) view returns (uint256[])",
|
|
48
49
|
"event ZipFileTokenized(uint256 indexed tokenId, address indexed creator, string fileName, string merkleRootHash, uint256 creationTimestamp, string ipfsHash)"
|
|
49
50
|
];
|
|
50
|
-
// ERC-20 token ABI for checking other tokens
|
|
51
51
|
const ERC20_ABI = [
|
|
52
52
|
"function balanceOf(address owner) view returns (uint256)",
|
|
53
53
|
"function name() view returns (string)",
|
|
54
54
|
"function symbol() view returns (string)",
|
|
55
55
|
"function decimals() view returns (uint8)"
|
|
56
56
|
];
|
|
57
|
-
// ERC-721 NFT ABI
|
|
58
57
|
const ERC721_ABI = [
|
|
59
58
|
"function balanceOf(address owner) view returns (uint256)",
|
|
60
59
|
"function name() view returns (string)",
|
|
61
60
|
"function symbol() view returns (string)",
|
|
62
61
|
"function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)"
|
|
63
62
|
];
|
|
64
|
-
class
|
|
65
|
-
constructor(
|
|
66
|
-
this.
|
|
63
|
+
class ZipKitWallet {
|
|
64
|
+
constructor() {
|
|
65
|
+
this.wallet = null;
|
|
66
|
+
this.provider = null;
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
async promptUser(question) {
|
|
69
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
70
|
+
return new Promise((resolve) => {
|
|
71
|
+
rl.question(question, (answer) => { rl.close(); resolve(answer.trim()); });
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
findExistingWallets() {
|
|
75
|
+
const walletFiles = [];
|
|
76
|
+
const currentDir = process.cwd();
|
|
77
|
+
const walletDir = path.join(currentDir, 'wallet');
|
|
78
|
+
const walletFileNames = ['neozip-wallet.json'];
|
|
79
|
+
for (const fileName of walletFileNames) {
|
|
80
|
+
const filePath = path.join(currentDir, fileName);
|
|
81
|
+
if (fs.existsSync(filePath))
|
|
82
|
+
walletFiles.push(filePath);
|
|
83
|
+
}
|
|
84
|
+
if (fs.existsSync(walletDir)) {
|
|
85
|
+
for (const fileName of walletFileNames) {
|
|
86
|
+
const filePath = path.join(walletDir, fileName);
|
|
87
|
+
if (fs.existsSync(filePath))
|
|
88
|
+
walletFiles.push(filePath);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return walletFiles;
|
|
92
|
+
}
|
|
93
|
+
loadWalletFromFile(filePath) {
|
|
72
94
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
const content = fs.readFileSync(filePath, 'utf8').trim();
|
|
96
|
+
try {
|
|
97
|
+
const walletData = JSON.parse(content);
|
|
98
|
+
if (walletData.privateKey) {
|
|
99
|
+
console.log(`Found wallet file: ${filePath}`);
|
|
100
|
+
console.log(`Wallet address: ${walletData.address}`);
|
|
101
|
+
return walletData.privateKey;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
if (content.startsWith('0x') && content.length === 66) {
|
|
106
|
+
console.log(`Found private key file: ${filePath}`);
|
|
107
|
+
return content;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
89
111
|
}
|
|
90
112
|
catch (error) {
|
|
91
|
-
|
|
113
|
+
console.warn(`Could not read wallet file ${filePath}:`, error);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async setupWallet(options) {
|
|
118
|
+
try {
|
|
119
|
+
const networkConfig = types_1.NETWORKS[options.network] || types_1.NETWORKS['base-sepolia'];
|
|
120
|
+
let privateKey;
|
|
121
|
+
if (options.wallet) {
|
|
122
|
+
const val = options.wallet;
|
|
123
|
+
if (fs.existsSync(val)) {
|
|
124
|
+
const loaded = this.loadWalletFromFile(val);
|
|
125
|
+
if (!loaded)
|
|
126
|
+
throw new Error(`Could not load valid private key from ${val}`);
|
|
127
|
+
privateKey = loaded;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
privateKey = val;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const existing = this.findExistingWallets();
|
|
135
|
+
if (existing.length > 0) {
|
|
136
|
+
const selected = existing[0];
|
|
137
|
+
const relativePath = path.relative(process.cwd(), selected);
|
|
138
|
+
console.log(`Using existing wallet: ${relativePath}`);
|
|
139
|
+
const loaded = this.loadWalletFromFile(selected);
|
|
140
|
+
if (!loaded)
|
|
141
|
+
throw new Error(`Could not load valid private key from ${selected}`);
|
|
142
|
+
privateKey = loaded;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log('No existing wallet found. Creating new wallet...');
|
|
146
|
+
privateKey = await this.createNewWallet();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
this.wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
150
|
+
console.log(`Using wallet: ${this.wallet.address}`);
|
|
151
|
+
const ok = await this.connectToNetwork(networkConfig, options.mintToken === true);
|
|
152
|
+
if (!ok) {
|
|
153
|
+
return { wallet: null, provider: null, success: false, message: `Failed to connect to ${networkConfig.name} network. Blockchain operations require network connectivity.` };
|
|
154
|
+
}
|
|
155
|
+
return { wallet: this.wallet, provider: this.provider, success: true, message: `Wallet setup successful for ${networkConfig.name}` };
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error('Error setting up wallet:', error);
|
|
159
|
+
return { wallet: null, provider: null, success: false, message: `Wallet setup failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async createNewWallet() {
|
|
163
|
+
console.log('Creating a new wallet...');
|
|
164
|
+
const newWallet = ethers_1.ethers.Wallet.createRandom();
|
|
165
|
+
const walletInfo = { address: newWallet.address, privateKey: newWallet.privateKey, mnemonic: newWallet.mnemonic?.phrase || "" };
|
|
166
|
+
const walletDir = path.join(process.cwd(), 'wallet');
|
|
167
|
+
if (!fs.existsSync(walletDir))
|
|
168
|
+
fs.mkdirSync(walletDir, { recursive: true });
|
|
169
|
+
const walletFilePath = path.join(walletDir, 'neozip-wallet.json');
|
|
170
|
+
fs.writeFileSync(walletFilePath, JSON.stringify(walletInfo, null, 2));
|
|
171
|
+
console.log(`New wallet created and saved to ${walletFilePath}`);
|
|
172
|
+
console.log(`Wallet address: ${newWallet.address}`);
|
|
173
|
+
console.log(`IMPORTANT: Please fund this wallet with BASE to use for minting NFTs!`);
|
|
174
|
+
return newWallet.privateKey;
|
|
175
|
+
}
|
|
176
|
+
async connectToNetwork(networkConfig, mintToken) {
|
|
177
|
+
try {
|
|
178
|
+
console.log(`Attempting to connect to ${networkConfig.name} network...`);
|
|
179
|
+
this.provider = new ethers_1.ethers.JsonRpcProvider(networkConfig.rpcUrl);
|
|
180
|
+
let networkTimedOut = false;
|
|
181
|
+
const networkTimeout = setTimeout(() => { networkTimedOut = true; console.error("Network connection timeout"); }, 5000);
|
|
182
|
+
await Promise.race([
|
|
183
|
+
this.provider.getNetwork(),
|
|
184
|
+
new Promise((_, reject) => setTimeout(() => { if (networkTimedOut)
|
|
185
|
+
reject(new Error("Network connection timeout")); }, 5100))
|
|
186
|
+
]);
|
|
187
|
+
clearTimeout(networkTimeout);
|
|
188
|
+
if (this.wallet) {
|
|
189
|
+
this.wallet = this.wallet.connect(this.provider);
|
|
190
|
+
const balance = await this.provider.getBalance(this.wallet.address);
|
|
191
|
+
const balanceEth = ethers_1.ethers.formatEther(balance);
|
|
192
|
+
console.log(`Wallet balance: ${balanceEth} ETH`);
|
|
193
|
+
const minBalance = 0.0001;
|
|
194
|
+
if (parseFloat(balanceEth) < minBalance && mintToken) {
|
|
195
|
+
console.error(`ERROR: Insufficient balance (${balanceEth} ETH). Minimum required: ${minBalance} ETH`);
|
|
196
|
+
console.error('Get testnet ETH from: https://www.coinbase.com/faucets/base-ethereum-sepolia-faucet');
|
|
197
|
+
throw new Error(`Insufficient balance for minting. Current: ${balanceEth} ETH, Required: ${minBalance} ETH`);
|
|
198
|
+
}
|
|
199
|
+
else if (mintToken) {
|
|
200
|
+
console.log(`✅ Sufficient balance for token minting`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
console.log(`✅ Successfully connected to ${networkConfig.name}`);
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
catch (networkError) {
|
|
207
|
+
const errorMessage = networkError instanceof Error ? networkError.message : String(networkError);
|
|
208
|
+
console.error(`Failed to connect to ${networkConfig.name} network: ${errorMessage}`);
|
|
209
|
+
this.provider = null;
|
|
210
|
+
return false;
|
|
92
211
|
}
|
|
93
212
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
213
|
+
getWallet() { return this.wallet; }
|
|
214
|
+
getProvider() { return this.provider; }
|
|
215
|
+
isReady() { return this.wallet !== null; }
|
|
216
|
+
isOnline() { return this.provider !== null; }
|
|
217
|
+
}
|
|
218
|
+
exports.ZipKitWallet = ZipKitWallet;
|
|
219
|
+
class WalletAnalyzer {
|
|
220
|
+
constructor(provider) { this.provider = provider; }
|
|
221
|
+
async getWalletBasics(address) {
|
|
222
|
+
const balance = await this.provider.getBalance(address);
|
|
223
|
+
const ethBalance = ethers_1.ethers.formatEther(balance);
|
|
224
|
+
const txCount = await this.provider.getTransactionCount(address);
|
|
225
|
+
const network = await this.provider.getNetwork();
|
|
226
|
+
const latestBlock = await this.provider.getBlockNumber();
|
|
227
|
+
return { ethBalance, transactionCount: txCount, networkName: network.name, chainId: network.chainId, latestBlock };
|
|
228
|
+
}
|
|
97
229
|
async scanForNZipTokens(contractAddress, ownerAddress) {
|
|
98
230
|
const contract = new ethers_1.ethers.Contract(contractAddress, NZIP_CONTRACT_ABI, this.provider);
|
|
99
231
|
let foundTokens = [];
|
|
100
232
|
let searchMethod = 'none';
|
|
101
|
-
// Method 1: Try events with recent blocks only
|
|
102
233
|
try {
|
|
103
234
|
const latestBlock = await this.provider.getBlockNumber();
|
|
104
235
|
const startBlock = Math.max(0, latestBlock - 50000);
|
|
@@ -107,63 +238,41 @@ class WalletAnalyzer {
|
|
|
107
238
|
for (const event of events) {
|
|
108
239
|
if ('args' in event && event.args && event.args.tokenId) {
|
|
109
240
|
const tokenId = Number(event.args.tokenId);
|
|
110
|
-
if (!foundTokens.includes(tokenId))
|
|
241
|
+
if (!foundTokens.includes(tokenId))
|
|
111
242
|
foundTokens.push(tokenId);
|
|
112
|
-
}
|
|
113
243
|
}
|
|
114
244
|
}
|
|
115
245
|
if (foundTokens.length > 0) {
|
|
116
|
-
searchMethod
|
|
117
|
-
return { foundTokens, searchMethod };
|
|
246
|
+
return { foundTokens, searchMethod: 'recent-events' };
|
|
118
247
|
}
|
|
119
248
|
}
|
|
120
|
-
catch
|
|
121
|
-
// Continue to next method
|
|
122
|
-
}
|
|
123
|
-
// Method 2: Direct token ID checking (brute force for small supply)
|
|
249
|
+
catch { }
|
|
124
250
|
try {
|
|
125
251
|
const totalSupply = await contract.totalSupply();
|
|
126
|
-
const maxCheck = Math.min(Number(totalSupply), 50);
|
|
252
|
+
const maxCheck = Math.min(Number(totalSupply), 50);
|
|
127
253
|
for (let tokenId = 0; tokenId < maxCheck; tokenId++) {
|
|
128
254
|
try {
|
|
129
255
|
const owner = await contract.ownerOf(tokenId);
|
|
130
|
-
if (owner.toLowerCase() === ownerAddress.toLowerCase())
|
|
256
|
+
if (owner.toLowerCase() === ownerAddress.toLowerCase())
|
|
131
257
|
foundTokens.push(tokenId);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
catch (ownerError) {
|
|
135
|
-
// Token doesn't exist or other error, skip
|
|
136
258
|
}
|
|
259
|
+
catch { }
|
|
137
260
|
}
|
|
138
|
-
if (foundTokens.length > 0)
|
|
139
|
-
searchMethod
|
|
140
|
-
return { foundTokens, searchMethod };
|
|
141
|
-
}
|
|
261
|
+
if (foundTokens.length > 0)
|
|
262
|
+
return { foundTokens, searchMethod: 'iteration' };
|
|
142
263
|
}
|
|
143
|
-
catch
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
// Method 3: Check specific token IDs that commonly exist
|
|
147
|
-
const commonTokenIds = Array.from({ length: 20 }, (_, i) => i); // 0-19
|
|
264
|
+
catch { }
|
|
265
|
+
const commonTokenIds = Array.from({ length: 20 }, (_, i) => i);
|
|
148
266
|
for (const tokenId of commonTokenIds) {
|
|
149
267
|
try {
|
|
150
268
|
const owner = await contract.ownerOf(tokenId);
|
|
151
|
-
if (owner.toLowerCase() === ownerAddress.toLowerCase())
|
|
269
|
+
if (owner.toLowerCase() === ownerAddress.toLowerCase())
|
|
152
270
|
foundTokens.push(tokenId);
|
|
153
|
-
}
|
|
154
271
|
}
|
|
155
|
-
catch
|
|
156
|
-
// Token doesn't exist, skip
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
if (foundTokens.length > 0) {
|
|
160
|
-
searchMethod = 'common-ids';
|
|
272
|
+
catch { }
|
|
161
273
|
}
|
|
162
|
-
return { foundTokens, searchMethod };
|
|
274
|
+
return { foundTokens, searchMethod: foundTokens.length > 0 ? 'common-ids' : 'none' };
|
|
163
275
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Get detailed information about NZIP tokens
|
|
166
|
-
*/
|
|
167
276
|
async getNZipTokenDetails(contractAddress, tokenIds) {
|
|
168
277
|
const contract = new ethers_1.ethers.Contract(contractAddress, NZIP_CONTRACT_ABI, this.provider);
|
|
169
278
|
const tokenDetails = [];
|
|
@@ -187,30 +296,16 @@ class WalletAnalyzer {
|
|
|
187
296
|
}
|
|
188
297
|
return tokenDetails;
|
|
189
298
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Get contract information (name, symbol, total supply)
|
|
192
|
-
*/
|
|
193
299
|
async getContractInfo(contractAddress) {
|
|
194
300
|
try {
|
|
195
301
|
const contract = new ethers_1.ethers.Contract(contractAddress, NZIP_CONTRACT_ABI, this.provider);
|
|
196
|
-
const [name, symbol, totalSupply] = await Promise.all([
|
|
197
|
-
|
|
198
|
-
contract.symbol(),
|
|
199
|
-
contract.totalSupply()
|
|
200
|
-
]);
|
|
201
|
-
return {
|
|
202
|
-
name,
|
|
203
|
-
symbol,
|
|
204
|
-
totalSupply: totalSupply.toString()
|
|
205
|
-
};
|
|
302
|
+
const [name, symbol, totalSupply] = await Promise.all([contract.name(), contract.symbol(), contract.totalSupply()]);
|
|
303
|
+
return { name, symbol, totalSupply: totalSupply.toString() };
|
|
206
304
|
}
|
|
207
|
-
catch
|
|
305
|
+
catch {
|
|
208
306
|
return null;
|
|
209
307
|
}
|
|
210
308
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Check ERC-20 token balances for common tokens
|
|
213
|
-
*/
|
|
214
309
|
async checkERC20Tokens(ownerAddress, tokenConfigs) {
|
|
215
310
|
const foundTokens = [];
|
|
216
311
|
for (const tokenConfig of tokenConfigs.filter(t => t.type === 'ERC20')) {
|
|
@@ -218,40 +313,19 @@ class WalletAnalyzer {
|
|
|
218
313
|
const contract = new ethers_1.ethers.Contract(tokenConfig.address, ERC20_ABI, this.provider);
|
|
219
314
|
const balance = await contract.balanceOf(ownerAddress);
|
|
220
315
|
if (balance > 0) {
|
|
221
|
-
let name, symbol, decimals;
|
|
316
|
+
let name = tokenConfig.name, symbol = tokenConfig.symbol, decimals = 18;
|
|
222
317
|
try {
|
|
223
|
-
[name, symbol, decimals] = await Promise.all([
|
|
224
|
-
contract.name(),
|
|
225
|
-
contract.symbol(),
|
|
226
|
-
contract.decimals()
|
|
227
|
-
]);
|
|
228
|
-
}
|
|
229
|
-
catch (metadataError) {
|
|
230
|
-
// Use fallback info if contract calls fail
|
|
231
|
-
name = tokenConfig.name;
|
|
232
|
-
symbol = tokenConfig.symbol;
|
|
233
|
-
decimals = 18; // Default decimals
|
|
318
|
+
[name, symbol, decimals] = await Promise.all([contract.name(), contract.symbol(), contract.decimals()]);
|
|
234
319
|
}
|
|
320
|
+
catch { }
|
|
235
321
|
const formattedBalance = ethers_1.ethers.formatUnits(balance, decimals);
|
|
236
|
-
foundTokens.push({
|
|
237
|
-
address: tokenConfig.address,
|
|
238
|
-
name,
|
|
239
|
-
symbol,
|
|
240
|
-
balance: formattedBalance,
|
|
241
|
-
decimals,
|
|
242
|
-
type: 'ERC20'
|
|
243
|
-
});
|
|
322
|
+
foundTokens.push({ address: tokenConfig.address, name, symbol, balance: formattedBalance, decimals, type: 'ERC20' });
|
|
244
323
|
}
|
|
245
324
|
}
|
|
246
|
-
catch
|
|
247
|
-
// Token might not exist or might not be ERC20, continue silently
|
|
248
|
-
}
|
|
325
|
+
catch { }
|
|
249
326
|
}
|
|
250
327
|
return foundTokens;
|
|
251
328
|
}
|
|
252
|
-
/**
|
|
253
|
-
* Check NFT collection balances
|
|
254
|
-
*/
|
|
255
329
|
async checkNFTCollections(ownerAddress, nftConfigs) {
|
|
256
330
|
const foundNFTs = [];
|
|
257
331
|
for (const nftConfig of nftConfigs) {
|
|
@@ -259,66 +333,30 @@ class WalletAnalyzer {
|
|
|
259
333
|
const contract = new ethers_1.ethers.Contract(nftConfig.address, ERC721_ABI, this.provider);
|
|
260
334
|
const balance = await contract.balanceOf(ownerAddress);
|
|
261
335
|
if (balance > 0) {
|
|
262
|
-
let name, symbol;
|
|
336
|
+
let name = nftConfig.name, symbol = nftConfig.symbol;
|
|
263
337
|
try {
|
|
264
|
-
[name, symbol] = await Promise.all([
|
|
265
|
-
contract.name(),
|
|
266
|
-
contract.symbol()
|
|
267
|
-
]);
|
|
268
|
-
}
|
|
269
|
-
catch (metadataError) {
|
|
270
|
-
name = nftConfig.name;
|
|
271
|
-
symbol = nftConfig.symbol;
|
|
338
|
+
[name, symbol] = await Promise.all([contract.name(), contract.symbol()]);
|
|
272
339
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (Number(balance) <= 5) {
|
|
276
|
-
try {
|
|
277
|
-
for (let i = 0; i < Number(balance); i++) {
|
|
278
|
-
const tokenId = await contract.tokenOfOwnerByIndex(ownerAddress, i);
|
|
279
|
-
tokenIds.push(tokenId.toString());
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch (enumError) {
|
|
283
|
-
// Unable to enumerate, that's okay
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
foundNFTs.push({
|
|
287
|
-
address: nftConfig.address,
|
|
288
|
-
name,
|
|
289
|
-
symbol,
|
|
290
|
-
balance: balance.toString(),
|
|
291
|
-
type: 'ERC721'
|
|
292
|
-
});
|
|
340
|
+
catch { }
|
|
341
|
+
foundNFTs.push({ address: nftConfig.address, name, symbol, balance: balance.toString(), type: 'ERC721' });
|
|
293
342
|
}
|
|
294
343
|
}
|
|
295
|
-
catch
|
|
296
|
-
// Contract might not exist or might not be ERC-721, continue silently
|
|
297
|
-
}
|
|
344
|
+
catch { }
|
|
298
345
|
}
|
|
299
346
|
return foundNFTs;
|
|
300
347
|
}
|
|
301
|
-
/**
|
|
302
|
-
* Detect NZIP contract from deployment file
|
|
303
|
-
*/
|
|
304
348
|
static detectNZipContract() {
|
|
305
349
|
const deploymentPath = path.join(process.cwd(), 'zipfile-nft-deployment.json');
|
|
306
350
|
if (fs.existsSync(deploymentPath)) {
|
|
307
351
|
try {
|
|
308
352
|
const deploymentInfo = JSON.parse(fs.readFileSync(deploymentPath, 'utf8'));
|
|
309
|
-
if (deploymentInfo.address)
|
|
353
|
+
if (deploymentInfo.address)
|
|
310
354
|
return deploymentInfo.address;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
// Could not read deployment file
|
|
315
355
|
}
|
|
356
|
+
catch { }
|
|
316
357
|
}
|
|
317
358
|
return undefined;
|
|
318
359
|
}
|
|
319
|
-
/**
|
|
320
|
-
* Get common token configurations for a network
|
|
321
|
-
*/
|
|
322
360
|
static getCommonTokens(network) {
|
|
323
361
|
const commonTokens = {
|
|
324
362
|
'base-sepolia': [
|
|
@@ -336,16 +374,10 @@ class WalletAnalyzer {
|
|
|
336
374
|
};
|
|
337
375
|
return commonTokens[network] || [];
|
|
338
376
|
}
|
|
339
|
-
/**
|
|
340
|
-
* Get common NFT configurations for a network
|
|
341
|
-
*/
|
|
342
377
|
static getCommonNFTs(network) {
|
|
343
378
|
const commonNFTs = {
|
|
344
|
-
'base-sepolia': [
|
|
345
|
-
// Add known testnet NFTs here when they become available
|
|
346
|
-
],
|
|
379
|
+
'base-sepolia': [],
|
|
347
380
|
'base': [
|
|
348
|
-
// Base mainnet NFTs - these are examples, real addresses would be different
|
|
349
381
|
{ address: '0x1234567890123456789012345678901234567890', name: 'Base Punks', symbol: 'BPUNK', type: 'ERC721' },
|
|
350
382
|
{ address: '0x0987654321098765432109876543210987654321', name: 'Base Bears', symbol: 'BBEAR', type: 'ERC721' },
|
|
351
383
|
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ContractConfig {
|
|
2
|
+
address: string;
|
|
3
|
+
network: string;
|
|
4
|
+
chainId: number;
|
|
5
|
+
explorerUrl: string;
|
|
6
|
+
rpcUrls: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare const CONTRACT_CONFIGS: Record<number, ContractConfig>;
|
|
9
|
+
export declare const NZIP_CONTRACT_ABI: string[];
|
|
10
|
+
export declare const DEFAULT_NETWORK = 84532;
|
|
11
|
+
export declare const CURRENT_DEPLOYMENT: ContractConfig;
|
|
12
|
+
export declare const getContractConfig: (chainId: number) => ContractConfig;
|
|
13
|
+
export declare const getSupportedNetworks: () => number[];
|
|
14
|
+
export declare const isNetworkSupported: (chainId: number) => boolean;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Contract addresses and configurations for different networks
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.isNetworkSupported = exports.getSupportedNetworks = exports.getContractConfig = exports.CURRENT_DEPLOYMENT = exports.DEFAULT_NETWORK = exports.NZIP_CONTRACT_ABI = exports.CONTRACT_CONFIGS = void 0;
|
|
5
|
+
// NZIP NFT Contract configurations by network
|
|
6
|
+
exports.CONTRACT_CONFIGS = {
|
|
7
|
+
// Base Sepolia (Primary testnet)
|
|
8
|
+
84532: {
|
|
9
|
+
address: '0xFD76a5d420704F34d84b0767961835c43D7b30a8', // Production contract v2.0
|
|
10
|
+
network: 'Base Sepolia',
|
|
11
|
+
chainId: 84532,
|
|
12
|
+
explorerUrl: 'https://sepolia.basescan.org',
|
|
13
|
+
rpcUrls: [
|
|
14
|
+
'https://sepolia.base.org',
|
|
15
|
+
'https://base-sepolia.g.alchemy.com/v2/demo',
|
|
16
|
+
'https://base-sepolia-rpc.publicnode.com'
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
// Base Mainnet (Production)
|
|
20
|
+
8453: {
|
|
21
|
+
address: '0x2716c4609fD97DaEdF429BC4B4Ec2faa81e2cC60',
|
|
22
|
+
network: 'Base Mainnet',
|
|
23
|
+
chainId: 8453,
|
|
24
|
+
explorerUrl: 'https://basescan.org',
|
|
25
|
+
rpcUrls: [
|
|
26
|
+
'https://mainnet.base.org',
|
|
27
|
+
'https://base.drpc.org',
|
|
28
|
+
'https://base.gateway.tenderly.co'
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
// Ethereum Sepolia (Testnet) - disabled until NZIP is deployed
|
|
32
|
+
// 11155111: {
|
|
33
|
+
// address: '0x0000000000000000000000000000000000000000',
|
|
34
|
+
// network: 'Sepolia Testnet',
|
|
35
|
+
// chainId: 11155111,
|
|
36
|
+
// explorerUrl: 'https://sepolia.etherscan.io',
|
|
37
|
+
// rpcUrls: []
|
|
38
|
+
// },
|
|
39
|
+
// Ethereum Mainnet (Production) - disabled until NZIP is deployed
|
|
40
|
+
// 1: {
|
|
41
|
+
// address: '0x0000000000000000000000000000000000000000',
|
|
42
|
+
// network: 'Ethereum Mainnet',
|
|
43
|
+
// chainId: 1,
|
|
44
|
+
// explorerUrl: 'https://etherscan.io',
|
|
45
|
+
// rpcUrls: []
|
|
46
|
+
// }
|
|
47
|
+
};
|
|
48
|
+
// Contract ABI (same for all networks)
|
|
49
|
+
exports.NZIP_CONTRACT_ABI = [
|
|
50
|
+
"function publicMintZipFile(string memory fileName, string memory merkleRootHash, uint256 creationTimestamp, string memory ipfsHash, string memory metadataURI) public returns (uint256)",
|
|
51
|
+
"function totalSupply() external view returns (uint256)",
|
|
52
|
+
"function getTokensByMerkleRoot(string memory merkleRoot) external view returns (uint256[])",
|
|
53
|
+
"function getZipFileInfo(uint256 tokenId) external view returns (tuple(string fileName, string merkleRootHash, string ipfsHash, address creator, uint256 creationTimestamp, uint256 tokenizationTime, uint256 blockNumber))",
|
|
54
|
+
"function ownerOf(uint256 tokenId) external view returns (address)",
|
|
55
|
+
"function balanceOf(address owner) external view returns (uint256)",
|
|
56
|
+
"function isZipFileTokenized(string memory merkleRootHash, uint256 creationTimestamp) external view returns (bool exists, uint256 tokenId)",
|
|
57
|
+
"function verifyZipFile(uint256 tokenId, string memory providedMerkleRoot) external view returns (bool isValid)",
|
|
58
|
+
"function getVersion() external pure returns (string memory)",
|
|
59
|
+
"event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)",
|
|
60
|
+
"event ZipFileTokenized(uint256 indexed tokenId, address indexed creator, string fileName, string merkleRootHash, uint256 creationTimestamp, string ipfsHash, uint256 tokenizationTime, uint256 blockNumber)"
|
|
61
|
+
];
|
|
62
|
+
// Default configuration (Base Sepolia for development)
|
|
63
|
+
exports.DEFAULT_NETWORK = 84532;
|
|
64
|
+
exports.CURRENT_DEPLOYMENT = exports.CONTRACT_CONFIGS[exports.DEFAULT_NETWORK];
|
|
65
|
+
// Helper functions
|
|
66
|
+
const getContractConfig = (chainId) => {
|
|
67
|
+
return exports.CONTRACT_CONFIGS[chainId] || exports.CURRENT_DEPLOYMENT;
|
|
68
|
+
};
|
|
69
|
+
exports.getContractConfig = getContractConfig;
|
|
70
|
+
const getSupportedNetworks = () => {
|
|
71
|
+
return Object.keys(exports.CONTRACT_CONFIGS).map(Number);
|
|
72
|
+
};
|
|
73
|
+
exports.getSupportedNetworks = getSupportedNetworks;
|
|
74
|
+
const isNetworkSupported = (chainId) => {
|
|
75
|
+
return chainId in exports.CONTRACT_CONFIGS;
|
|
76
|
+
};
|
|
77
|
+
exports.isNetworkSupported = isNetworkSupported;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export { ZipKitMinter, MintingOptions, MintingResult, DuplicateCheckResult, TokenInfo, WalletInfo, validatePrivateKey } from './ZipKitMinter';
|
|
3
|
+
export { ZipKitVerifier, VerificationOptions, VerificationResult } from './ZipKitVerifier';
|
|
4
|
+
export { TokenMetadata } from './types';
|
|
5
|
+
export { NZIP_CONTRACT_ABI, CONTRACT_CONFIGS, CURRENT_DEPLOYMENT, DEFAULT_NETWORK, getContractConfig, getSupportedNetworks, isNetworkSupported } from './contracts';
|
|
6
|
+
export { ZipKitWallet, WalletAnalyzer, NZipTokenDetails, WalletBasicInfo, TokenScanResult, CommonTokenConfig } from './ZipKitWallet';
|
|
7
|
+
export { createTimestamp, deserializeOts, parseVerifyResult, createCertificateOts, upgradeOTS, createOtsMetadataEntry, bufferToArrayBuffer, getOtsEntry, getOtsBuffer, getMerkleRootSafe, verifyOts, verifyOtsZip, TimestampResult, TimestampInfo, DeserializeOtsResult, OtsVerifyResult } from './ZipKitOTS';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.verifyOtsZip = exports.verifyOts = exports.getMerkleRootSafe = exports.getOtsBuffer = exports.getOtsEntry = exports.bufferToArrayBuffer = exports.createOtsMetadataEntry = exports.upgradeOTS = exports.createCertificateOts = exports.parseVerifyResult = exports.deserializeOts = exports.createTimestamp = exports.WalletAnalyzer = exports.ZipKitWallet = exports.isNetworkSupported = exports.getSupportedNetworks = exports.getContractConfig = exports.DEFAULT_NETWORK = exports.CURRENT_DEPLOYMENT = exports.CONTRACT_CONFIGS = exports.NZIP_CONTRACT_ABI = exports.ZipKitVerifier = exports.validatePrivateKey = exports.ZipKitMinter = void 0;
|
|
18
|
+
// Export all types
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
var ZipKitMinter_1 = require("./ZipKitMinter");
|
|
21
|
+
Object.defineProperty(exports, "ZipKitMinter", { enumerable: true, get: function () { return ZipKitMinter_1.ZipKitMinter; } });
|
|
22
|
+
Object.defineProperty(exports, "validatePrivateKey", { enumerable: true, get: function () { return ZipKitMinter_1.validatePrivateKey; } });
|
|
23
|
+
var ZipKitVerifier_1 = require("./ZipKitVerifier");
|
|
24
|
+
Object.defineProperty(exports, "ZipKitVerifier", { enumerable: true, get: function () { return ZipKitVerifier_1.ZipKitVerifier; } });
|
|
25
|
+
var contracts_1 = require("./contracts");
|
|
26
|
+
Object.defineProperty(exports, "NZIP_CONTRACT_ABI", { enumerable: true, get: function () { return contracts_1.NZIP_CONTRACT_ABI; } });
|
|
27
|
+
Object.defineProperty(exports, "CONTRACT_CONFIGS", { enumerable: true, get: function () { return contracts_1.CONTRACT_CONFIGS; } });
|
|
28
|
+
Object.defineProperty(exports, "CURRENT_DEPLOYMENT", { enumerable: true, get: function () { return contracts_1.CURRENT_DEPLOYMENT; } });
|
|
29
|
+
Object.defineProperty(exports, "DEFAULT_NETWORK", { enumerable: true, get: function () { return contracts_1.DEFAULT_NETWORK; } });
|
|
30
|
+
Object.defineProperty(exports, "getContractConfig", { enumerable: true, get: function () { return contracts_1.getContractConfig; } });
|
|
31
|
+
Object.defineProperty(exports, "getSupportedNetworks", { enumerable: true, get: function () { return contracts_1.getSupportedNetworks; } });
|
|
32
|
+
Object.defineProperty(exports, "isNetworkSupported", { enumerable: true, get: function () { return contracts_1.isNetworkSupported; } });
|
|
33
|
+
// Export wallet management and analysis (combined under ZipKitWallet)
|
|
34
|
+
var ZipKitWallet_1 = require("./ZipKitWallet");
|
|
35
|
+
Object.defineProperty(exports, "ZipKitWallet", { enumerable: true, get: function () { return ZipKitWallet_1.ZipKitWallet; } });
|
|
36
|
+
Object.defineProperty(exports, "WalletAnalyzer", { enumerable: true, get: function () { return ZipKitWallet_1.WalletAnalyzer; } });
|
|
37
|
+
// Export OpenTimestamps utilities
|
|
38
|
+
var ZipKitOTS_1 = require("./ZipKitOTS");
|
|
39
|
+
Object.defineProperty(exports, "createTimestamp", { enumerable: true, get: function () { return ZipKitOTS_1.createTimestamp; } });
|
|
40
|
+
Object.defineProperty(exports, "deserializeOts", { enumerable: true, get: function () { return ZipKitOTS_1.deserializeOts; } });
|
|
41
|
+
Object.defineProperty(exports, "parseVerifyResult", { enumerable: true, get: function () { return ZipKitOTS_1.parseVerifyResult; } });
|
|
42
|
+
Object.defineProperty(exports, "createCertificateOts", { enumerable: true, get: function () { return ZipKitOTS_1.createCertificateOts; } });
|
|
43
|
+
Object.defineProperty(exports, "upgradeOTS", { enumerable: true, get: function () { return ZipKitOTS_1.upgradeOTS; } });
|
|
44
|
+
Object.defineProperty(exports, "createOtsMetadataEntry", { enumerable: true, get: function () { return ZipKitOTS_1.createOtsMetadataEntry; } });
|
|
45
|
+
Object.defineProperty(exports, "bufferToArrayBuffer", { enumerable: true, get: function () { return ZipKitOTS_1.bufferToArrayBuffer; } });
|
|
46
|
+
Object.defineProperty(exports, "getOtsEntry", { enumerable: true, get: function () { return ZipKitOTS_1.getOtsEntry; } });
|
|
47
|
+
Object.defineProperty(exports, "getOtsBuffer", { enumerable: true, get: function () { return ZipKitOTS_1.getOtsBuffer; } });
|
|
48
|
+
Object.defineProperty(exports, "getMerkleRootSafe", { enumerable: true, get: function () { return ZipKitOTS_1.getMerkleRootSafe; } });
|
|
49
|
+
Object.defineProperty(exports, "verifyOts", { enumerable: true, get: function () { return ZipKitOTS_1.verifyOts; } });
|
|
50
|
+
Object.defineProperty(exports, "verifyOtsZip", { enumerable: true, get: function () { return ZipKitOTS_1.verifyOtsZip; } });
|