neozipkit 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +410 -186
- package/contracts/ABI.txt +889 -0
- package/contracts/Bytecode.txt +1 -0
- package/contracts/COMPILATION_NOTES.md +59 -0
- package/contracts/QUICK_DEPLOY.md +286 -0
- package/contracts/README.md +235 -131
- package/contracts/VERIFICATION.md +308 -0
- package/contracts/deploy-interactive.js +448 -0
- package/contracts/deployment-arbitrum-sepolia.json +12 -0
- package/contracts/deployment-arbitrum.json +12 -0
- package/contracts/deployment-eth-sepolia.json +12 -0
- package/contracts/hardhat.config.js +114 -0
- package/contracts/package.json +20 -0
- package/contracts/scripts/compile-and-extract.js +119 -0
- package/contracts/scripts/verify-contract.js +223 -0
- package/contracts/src/{NZIP-NFT-Private.sol → NZIP-NFT-v2.0.sol} +66 -151
- package/contracts/src/NZIP-NFT.sol +9 -15
- package/dist/blockchain/browser/TokenVerifierBrowser.d.ts +67 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.js +313 -0
- package/dist/blockchain/browser/TokenVerifierBrowser.js.map +1 -0
- package/dist/blockchain/browser/WalletManagerBrowser.d.ts +98 -0
- package/dist/blockchain/browser/WalletManagerBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/WalletManagerBrowser.js +434 -0
- package/dist/blockchain/browser/WalletManagerBrowser.js.map +1 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts +58 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts.map +1 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.js +317 -0
- package/dist/blockchain/browser/ZipkitMinterBrowser.js.map +1 -0
- package/dist/blockchain/browser/index.d.ts +11 -0
- package/dist/blockchain/browser/index.d.ts.map +1 -0
- package/dist/blockchain/browser/index.js +16 -0
- package/dist/blockchain/browser/index.js.map +1 -0
- package/dist/blockchain/core/WalletManager.d.ts +124 -0
- package/dist/blockchain/core/WalletManager.d.ts.map +1 -0
- package/dist/blockchain/{ZipKitWallet.js → core/WalletManager.js} +157 -177
- package/dist/blockchain/core/WalletManager.js.map +1 -0
- package/dist/blockchain/{ZipKitMinter.d.ts → core/ZipkitMinter.d.ts} +46 -11
- package/dist/blockchain/core/ZipkitMinter.d.ts.map +1 -0
- package/dist/blockchain/core/ZipkitMinter.js +548 -0
- package/dist/blockchain/core/ZipkitMinter.js.map +1 -0
- package/dist/blockchain/{ZipKitOTS.d.ts → core/ZipkitOTS.d.ts} +6 -15
- package/dist/blockchain/core/ZipkitOTS.d.ts.map +1 -0
- package/dist/blockchain/{ZipKitOTS.js → core/ZipkitOTS.js} +26 -84
- package/dist/blockchain/core/ZipkitOTS.js.map +1 -0
- package/dist/blockchain/core/ZipkitVerifier.d.ts +177 -0
- package/dist/blockchain/core/ZipkitVerifier.d.ts.map +1 -0
- package/dist/blockchain/core/ZipkitVerifier.js +632 -0
- package/dist/blockchain/core/ZipkitVerifier.js.map +1 -0
- package/dist/blockchain/core/contracts.d.ts +83 -0
- package/dist/blockchain/core/contracts.d.ts.map +1 -0
- package/dist/blockchain/core/contracts.js +341 -0
- package/dist/blockchain/core/contracts.js.map +1 -0
- package/dist/blockchain/core/index.d.ts +12 -0
- package/dist/blockchain/core/index.d.ts.map +1 -0
- package/dist/blockchain/core/index.js +59 -0
- package/dist/blockchain/core/index.js.map +1 -0
- package/dist/blockchain/index.d.ts +11 -7
- package/dist/blockchain/index.d.ts.map +1 -0
- package/dist/blockchain/index.js +18 -34
- package/dist/blockchain/index.js.map +1 -0
- package/dist/blockchain/node/WalletManagerNode.d.ts +47 -0
- package/dist/blockchain/node/WalletManagerNode.d.ts.map +1 -0
- package/dist/blockchain/node/WalletManagerNode.js +203 -0
- package/dist/blockchain/node/WalletManagerNode.js.map +1 -0
- package/dist/blockchain/node/index.d.ts +12 -0
- package/dist/blockchain/node/index.d.ts.map +1 -0
- package/dist/blockchain/node/index.js +24 -0
- package/dist/blockchain/node/index.js.map +1 -0
- package/dist/browser/ZipkitBrowser.d.ts +27 -0
- package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
- package/dist/browser/{ZipKitBrowser.js → ZipkitBrowser.js} +96 -43
- package/dist/browser/ZipkitBrowser.js.map +1 -0
- package/dist/browser/index.d.ts +12 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +42 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser-esm/index.d.ts +12 -0
- package/dist/browser-esm/index.js +59559 -0
- package/dist/browser-esm/index.js.map +7 -0
- package/dist/browser-umd/index.d.ts +12 -0
- package/dist/browser-umd/index.js +59576 -0
- package/dist/browser-umd/index.js.map +7 -0
- package/dist/browser-umd/index.min.js +63 -0
- package/dist/browser.d.ts +8 -14
- package/dist/browser.js +13 -28
- package/dist/core/ZipCompress.d.ts +99 -0
- package/dist/core/ZipCompress.d.ts.map +1 -0
- package/dist/core/ZipCompress.js +309 -0
- package/dist/core/ZipCompress.js.map +1 -0
- package/dist/core/ZipDecompress.d.ts +58 -0
- package/dist/core/ZipDecompress.d.ts.map +1 -0
- package/dist/core/ZipDecompress.js +172 -0
- package/dist/core/ZipDecompress.js.map +1 -0
- package/dist/{shared → core}/ZipEntry.d.ts +8 -1
- package/dist/core/ZipEntry.d.ts.map +1 -0
- package/dist/{shared → core}/ZipEntry.js +225 -82
- package/dist/core/ZipEntry.js.map +1 -0
- package/dist/core/Zipkit.d.ts +315 -0
- package/dist/core/Zipkit.d.ts.map +1 -0
- package/dist/core/Zipkit.js +647 -0
- package/dist/core/Zipkit.js.map +1 -0
- package/dist/core/components/HashCalculator.d.ts +138 -0
- package/dist/core/components/HashCalculator.d.ts.map +1 -0
- package/dist/core/components/HashCalculator.js +360 -0
- package/dist/core/components/HashCalculator.js.map +1 -0
- package/dist/core/components/Logger.d.ts +73 -0
- package/dist/core/components/Logger.d.ts.map +1 -0
- package/dist/core/components/Logger.js +156 -0
- package/dist/core/components/Logger.js.map +1 -0
- package/dist/core/components/ProgressTracker.d.ts +43 -0
- package/dist/core/components/ProgressTracker.d.ts.map +1 -0
- package/dist/core/components/ProgressTracker.js +112 -0
- package/dist/core/components/ProgressTracker.js.map +1 -0
- package/dist/{shared → core}/components/Support.d.ts +1 -0
- package/dist/core/components/Support.d.ts.map +1 -0
- package/dist/{shared → core}/components/Support.js +1 -0
- package/dist/core/components/Support.js.map +1 -0
- package/dist/{shared → core}/components/Util.d.ts +7 -2
- package/dist/core/components/Util.d.ts.map +1 -0
- package/dist/{shared → core}/components/Util.js +14 -34
- package/dist/core/components/Util.js.map +1 -0
- package/dist/{shared → core}/constants/Errors.d.ts +1 -2
- package/dist/core/constants/Errors.d.ts.map +1 -0
- package/dist/{shared → core}/constants/Errors.js +1 -3
- package/dist/core/constants/Errors.js.map +1 -0
- package/dist/{shared → core}/constants/Headers.d.ts +3 -0
- package/dist/core/constants/Headers.d.ts.map +1 -0
- package/dist/{shared → core}/constants/Headers.js +20 -17
- package/dist/core/constants/Headers.js.map +1 -0
- package/dist/core/encryption/Manager.d.ts +58 -0
- package/dist/core/encryption/Manager.d.ts.map +1 -0
- package/dist/core/encryption/Manager.js +121 -0
- package/dist/core/encryption/Manager.js.map +1 -0
- package/dist/core/encryption/ZipCrypto.d.ts +172 -0
- package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
- package/dist/core/encryption/ZipCrypto.js +554 -0
- package/dist/core/encryption/ZipCrypto.js.map +1 -0
- package/dist/core/encryption/index.d.ts +9 -0
- package/dist/core/encryption/index.d.ts.map +1 -0
- package/dist/core/encryption/index.js +17 -0
- package/dist/core/encryption/index.js.map +1 -0
- package/dist/core/encryption/types.d.ts +29 -0
- package/dist/core/encryption/types.d.ts.map +1 -0
- package/dist/core/encryption/types.js +12 -0
- package/dist/core/encryption/types.js.map +1 -0
- package/dist/core/index.d.ts +24 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +57 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +31 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +8 -18
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -35
- package/dist/index.js.map +1 -0
- package/dist/node/ZipCompressNode.d.ts +123 -0
- package/dist/node/ZipCompressNode.d.ts.map +1 -0
- package/dist/node/ZipCompressNode.js +576 -0
- package/dist/node/ZipCompressNode.js.map +1 -0
- package/dist/node/ZipDecompressNode.d.ts +120 -0
- package/dist/node/ZipDecompressNode.d.ts.map +1 -0
- package/dist/node/ZipDecompressNode.js +461 -0
- package/dist/node/ZipDecompressNode.js.map +1 -0
- package/dist/node/ZipkitNode.d.ts +406 -0
- package/dist/node/ZipkitNode.d.ts.map +1 -0
- package/dist/node/ZipkitNode.js +1305 -0
- package/dist/node/ZipkitNode.js.map +1 -0
- package/dist/node/index.d.ts +26 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +65 -0
- package/dist/node/index.js.map +1 -0
- package/dist/types/index.d.ts +59 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +36 -1
- package/dist/types/index.js.map +1 -0
- package/examples/README.md +269 -0
- package/examples/blockchain-tokenize.ts +354 -0
- package/examples/create-zip.ts +172 -0
- package/examples/extract-zip.ts +158 -0
- package/examples/list-zip.ts +161 -0
- package/examples/test-files/data.json +116 -0
- package/examples/test-files/document.md +80 -0
- package/examples/test-files/document.txt +2 -0
- package/examples/test-files/file1.txt +48 -0
- package/examples/test-files/file2.txt +80 -0
- package/examples/tsconfig.json +44 -0
- package/examples/unzip-token.ts +491 -0
- package/examples/verify-tokenized-zip.ts +305 -0
- package/examples/zip-token.ts +604 -0
- package/package.json +108 -24
- package/src/blockchain/README.md +59 -66
- package/src/{browser/TokenVerifierBrowser.ts-remove → blockchain/browser/TokenVerifierBrowser.ts} +125 -79
- package/src/blockchain/browser/WalletManagerBrowser.ts +486 -0
- package/src/blockchain/browser/ZipkitMinterBrowser.ts +400 -0
- package/src/blockchain/browser/index.ts +13 -0
- package/src/blockchain/{ZipKitWallet.ts → core/WalletManager.ts} +241 -143
- package/src/blockchain/core/ZipkitMinter.ts +716 -0
- package/src/blockchain/{ZipKitOTS.ts → core/ZipkitOTS.ts} +28 -62
- package/src/blockchain/core/ZipkitVerifier.ts +853 -0
- package/src/blockchain/core/contracts.ts +370 -0
- package/src/blockchain/core/index.ts +71 -0
- package/src/blockchain/index.ts +21 -55
- package/src/blockchain/node/WalletManagerNode.ts +171 -0
- package/src/blockchain/node/index.ts +40 -0
- package/src/browser/{ZipKitBrowser.ts → ZipkitBrowser.ts} +104 -41
- package/src/browser/index.esm.ts +37 -0
- package/src/browser/index.ts +25 -0
- package/src/core/ZipCompress.ts +398 -0
- package/src/core/ZipDecompress.ts +212 -0
- package/src/{shared → core}/ZipEntry.ts +240 -90
- package/src/core/Zipkit.ts +794 -0
- package/src/core/components/HashCalculator.ts +384 -0
- package/src/core/components/Logger.ts +180 -0
- package/src/core/components/ProgressTracker.ts +134 -0
- package/src/{shared → core}/components/Util.ts +12 -34
- package/src/{shared → core}/constants/Errors.ts +0 -4
- package/src/{shared → core}/constants/Headers.ts +19 -17
- package/src/core/encryption/Manager.ts +137 -0
- package/src/core/encryption/ZipCrypto.ts +650 -0
- package/src/core/encryption/index.ts +15 -0
- package/src/core/encryption/types.ts +33 -0
- package/src/core/index.ts +34 -0
- package/src/core/version.ts +33 -0
- package/src/index.ts +54 -25
- package/src/node/ZipCompressNode.ts +632 -0
- package/src/node/ZipDecompressNode.ts +508 -0
- package/src/node/ZipkitNode.ts +1559 -0
- package/src/node/index.ts +69 -0
- package/src/types/index.ts +131 -1
- package/src/types/modules.d.ts +1 -11
- package/src/types/opentimestamps.d.ts +1 -23
- package/contracts/INTEGRATION.md +0 -338
- package/contracts/NETWORKS.md +0 -156
- package/contracts/NZIP-NFT-bytecode.txt +0 -1
- package/contracts/constants.ts +0 -952
- package/contracts/deploy-bytecode.mjs +0 -94
- package/dist/blockchain/CertificateToken.d.ts +0 -48
- package/dist/blockchain/CertificateToken.js +0 -386
- package/dist/blockchain/ZipKitMinter.js +0 -347
- package/dist/blockchain/ZipKitNFT.d.ts +0 -3
- package/dist/blockchain/ZipKitNFT.js +0 -7
- package/dist/blockchain/ZipKitVerifier.d.ts +0 -69
- package/dist/blockchain/ZipKitVerifier.js +0 -289
- package/dist/blockchain/ZipKitWallet.d.ts +0 -69
- package/dist/blockchain/contracts.d.ts +0 -14
- package/dist/blockchain/contracts.js +0 -77
- package/dist/blockchain/types.d.ts +0 -47
- package/dist/blockchain/types.js +0 -30
- package/dist/browser/ZipKitBrowser.d.ts +0 -18
- package/dist/browser/ZipKitStampBrowser.d.ts +0 -2
- package/dist/browser/ZipKitStampBrowser.js +0 -12
- package/dist/browser-index.d.ts +0 -18
- package/dist/browser-index.js +0 -57
- package/dist/server/ZipKitServer.d.ts +0 -74
- package/dist/server/ZipKitServer.js +0 -310
- package/dist/shared/ZipKit.d.ts +0 -243
- package/dist/shared/ZipKit.js +0 -772
- package/dist/shared/components/CertificateOTS.d.ts +0 -15
- package/dist/shared/components/CertificateOTS.js +0 -116
- package/dist/shared/components/FileSys.d.ts +0 -2
- package/dist/shared/components/FileSys.js +0 -113
- package/dist/shared/components/HashAccumulator.d.ts +0 -55
- package/dist/shared/components/HashAccumulator.js +0 -100
- package/dist/shared/components/ZipCrypto.d.ts +0 -3
- package/dist/shared/components/ZipCrypto.js +0 -78
- package/dist/shared/components/merkleTree.d.ts +0 -66
- package/dist/shared/components/merkleTree.js +0 -136
- package/dist/shared/types/index.d.ts +0 -21
- package/dist/shared/types/index.js +0 -3
- package/dist/shared/types.d.ts +0 -33
- package/dist/shared/types.js +0 -8
- package/dist/shared/version.d.ts +0 -2
- package/dist/shared/version.js +0 -6
- package/src/blockchain/CertificateToken.ts +0 -444
- package/src/blockchain/ZipKitMinter.ts +0 -470
- package/src/blockchain/ZipKitNFT.ts +0 -12
- package/src/blockchain/ZipKitVerifier.ts +0 -382
- package/src/blockchain/contracts.ts +0 -88
- package/src/blockchain/types.ts +0 -91
- package/src/browser/CertificateGeneratorBrowser.ts-remove +0 -498
- package/src/browser/ZipKitStampBrowser.ts +0 -9
- package/src/browser-index.ts +0 -36
- package/src/server/README.md +0 -25
- package/src/server/ZipKitServer.ts +0 -305
- package/src/shared/ZipKit.ts +0 -881
- package/src/shared/components/CertificateOTS.ts +0 -132
- package/src/shared/components/FileSys.ts +0 -87
- package/src/shared/components/HashAccumulator.ts +0 -113
- package/src/shared/components/ZipCrypto.ts +0 -91
- package/src/shared/components/merkleTree.ts +0 -162
- package/src/shared/types/index.ts +0 -25
- package/src/shared/types/modules.d.ts +0 -22
- package/src/shared/types/opentimestamps.d.ts +0 -23
- package/src/shared/types.d.ts +0 -8
- package/src/shared/types.ts +0 -43
- package/src/shared/version.ts +0 -3
- /package/src/{shared → core}/components/Support.ts +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZipkitMinterBrowser - Browser-specific NFT minting for ZIP files
|
|
3
|
+
* Extends core minting functionality with browser-specific features
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { WalletManagerBrowser } from './WalletManagerBrowser';
|
|
7
|
+
import type { TokenMetadata } from '../../types';
|
|
8
|
+
|
|
9
|
+
export interface TokenizationResult {
|
|
10
|
+
success: boolean
|
|
11
|
+
tokenId?: string
|
|
12
|
+
transactionHash?: string
|
|
13
|
+
error?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ExistingToken {
|
|
17
|
+
tokenId: string
|
|
18
|
+
owner: string
|
|
19
|
+
creationTimestamp: number
|
|
20
|
+
mintedAt: string
|
|
21
|
+
transactionHash: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ZipkitMinterBrowser {
|
|
25
|
+
private walletManager: WalletManagerBrowser
|
|
26
|
+
private merkleRoot: string
|
|
27
|
+
|
|
28
|
+
constructor(merkleRoot: string, walletManager: WalletManagerBrowser) {
|
|
29
|
+
this.merkleRoot = merkleRoot
|
|
30
|
+
this.walletManager = walletManager
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Initialize the minter with wallet manager
|
|
35
|
+
*/
|
|
36
|
+
async initialize(): Promise<void> {
|
|
37
|
+
if (!this.walletManager.getContract() || !this.walletManager.getBrowserProvider()) {
|
|
38
|
+
throw new Error("Wallet manager not initialized")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Browser minter uses wallet manager directly, no core minter needed
|
|
42
|
+
console.log('ZipkitMinterBrowser initialized with wallet manager')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private getNetworkName(chainId: number): string {
|
|
46
|
+
const networkNames: Record<number, string> = {
|
|
47
|
+
1: "homestead",
|
|
48
|
+
11155111: "sepolia",
|
|
49
|
+
84532: "base-sepolia",
|
|
50
|
+
8453: "base"
|
|
51
|
+
}
|
|
52
|
+
return networkNames[chainId] || `chain-${chainId}`
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check for any existing tokens with the same Merkle Root
|
|
57
|
+
*/
|
|
58
|
+
async findTokensByMerkleRoot(): Promise<ExistingToken[]> {
|
|
59
|
+
const contract = this.walletManager.getContract()
|
|
60
|
+
if (!contract) {
|
|
61
|
+
throw new Error("Service not initialized")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const tokenIds = await contract.getFunction("getTokensByMerkleRoot")(this.merkleRoot)
|
|
66
|
+
|
|
67
|
+
if (tokenIds.length === 0) {
|
|
68
|
+
return []
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const existingTokens: ExistingToken[] = []
|
|
72
|
+
|
|
73
|
+
for (const tokenId of tokenIds) {
|
|
74
|
+
try {
|
|
75
|
+
const owner = await contract.getFunction("ownerOf")(tokenId)
|
|
76
|
+
const zipFileInfo = await contract.getFunction("getZipFileInfo")(tokenId)
|
|
77
|
+
|
|
78
|
+
existingTokens.push({
|
|
79
|
+
tokenId: tokenId.toString(),
|
|
80
|
+
owner: owner,
|
|
81
|
+
creationTimestamp: Number(zipFileInfo.tokenizationTime) || 0,
|
|
82
|
+
mintedAt: new Date(Number(zipFileInfo.tokenizationTime) * 1000).toISOString(),
|
|
83
|
+
transactionHash: ''
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.warn(`Could not get info for token ${tokenId}:`, error)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return existingTokens
|
|
92
|
+
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error("Error finding tokens by merkle root:", error)
|
|
95
|
+
return []
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Estimate gas cost for minting
|
|
101
|
+
*/
|
|
102
|
+
async estimateGasCost(): Promise<string> {
|
|
103
|
+
const contract = this.walletManager.getContract()
|
|
104
|
+
const provider = this.walletManager.getBrowserProvider()
|
|
105
|
+
|
|
106
|
+
if (!contract || !provider) {
|
|
107
|
+
throw new Error("Service not initialized")
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
console.log(`⛽ Estimating gas for ZIP archive (${this.merkleRoot.slice(0, 10)}...)`)
|
|
112
|
+
|
|
113
|
+
const signer = await provider.getSigner()
|
|
114
|
+
const contractWithSigner = contract.connect(signer)
|
|
115
|
+
|
|
116
|
+
// Create a timestamp for the archive (current time)
|
|
117
|
+
const creationTimestamp = Math.floor(Date.now() / 1000)
|
|
118
|
+
|
|
119
|
+
// Placeholder values for IPFS hash and token URI
|
|
120
|
+
const ipfsHash = "" // Empty for now, could be implemented later
|
|
121
|
+
const tokenURI = "" // Empty for now, could be implemented later
|
|
122
|
+
|
|
123
|
+
// Estimate gas for the mint function with timeout
|
|
124
|
+
const GAS_ESTIMATION_TIMEOUT = 30000 // 30 seconds
|
|
125
|
+
const gasEstimate = await Promise.race([
|
|
126
|
+
contractWithSigner.getFunction("publicMintZipFile").estimateGas(
|
|
127
|
+
this.merkleRoot,
|
|
128
|
+
creationTimestamp,
|
|
129
|
+
ipfsHash,
|
|
130
|
+
tokenURI
|
|
131
|
+
),
|
|
132
|
+
new Promise<never>((_, reject) =>
|
|
133
|
+
setTimeout(() => reject(new Error('Gas estimation timeout')), GAS_ESTIMATION_TIMEOUT)
|
|
134
|
+
)
|
|
135
|
+
])
|
|
136
|
+
|
|
137
|
+
// Get current gas price (use read provider if available) with timeout
|
|
138
|
+
const readProvider = this.walletManager.getReadProvider()
|
|
139
|
+
const providerForRead = readProvider || provider
|
|
140
|
+
const gasPrice = await Promise.race([
|
|
141
|
+
providerForRead.getFeeData(),
|
|
142
|
+
new Promise<never>((_, reject) =>
|
|
143
|
+
setTimeout(() => reject(new Error('Gas price fetch timeout')), 10000)
|
|
144
|
+
)
|
|
145
|
+
])
|
|
146
|
+
const gasCost = gasEstimate * (gasPrice.gasPrice || BigInt(0))
|
|
147
|
+
|
|
148
|
+
// Convert to ETH (18 decimals)
|
|
149
|
+
const costInEth = Number(gasCost) / 1e18
|
|
150
|
+
|
|
151
|
+
console.log(`⛽ Estimated gas: ${gasEstimate.toString()} units`)
|
|
152
|
+
console.log(`💰 Estimated cost: ${costInEth.toFixed(6)} ETH`)
|
|
153
|
+
|
|
154
|
+
return costInEth.toFixed(6)
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.warn('Gas estimation failed:', error)
|
|
157
|
+
|
|
158
|
+
// Provide fallback estimate based on error type
|
|
159
|
+
if (error instanceof Error) {
|
|
160
|
+
if (error.message.includes("not supported") || error.message.includes("method")) {
|
|
161
|
+
console.warn("RPC method not supported by wallet provider, using fallback estimate")
|
|
162
|
+
return "0.002" // Higher fallback estimate for complex contract calls
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return "0.001" // Default fallback estimate
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Mint a new token
|
|
172
|
+
*/
|
|
173
|
+
async mintToken(): Promise<TokenizationResult> {
|
|
174
|
+
const contract = this.walletManager.getContract()
|
|
175
|
+
const provider = this.walletManager.getBrowserProvider()
|
|
176
|
+
const config = this.walletManager.getCurrentConfig()
|
|
177
|
+
|
|
178
|
+
if (!contract || !provider || !config.address) {
|
|
179
|
+
throw new Error("Service not initialized")
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
console.log("🎯 Minting NFT token for ZIP archive...")
|
|
184
|
+
console.log(`📝 Minting token for ZIP archive (filename stored in ZIP metadata only for privacy)`)
|
|
185
|
+
console.log(`🔐 Merkle Root: ${this.merkleRoot}`)
|
|
186
|
+
console.log(`📍 Contract: ${config.address}`)
|
|
187
|
+
|
|
188
|
+
// Call the actual contract to mint the token
|
|
189
|
+
const signer = await provider.getSigner()
|
|
190
|
+
const contractWithSigner = contract.connect(signer)
|
|
191
|
+
|
|
192
|
+
// Create a timestamp for the archive (current time)
|
|
193
|
+
const creationTimestamp = Math.floor(Date.now() / 1000)
|
|
194
|
+
|
|
195
|
+
// Placeholder values for IPFS hash and token URI
|
|
196
|
+
const ipfsHash = "" // Empty for now, could be implemented later
|
|
197
|
+
const tokenURI = "" // Empty for now, could be implemented later
|
|
198
|
+
|
|
199
|
+
console.log("📡 Submitting transaction to blockchain...")
|
|
200
|
+
console.log(`🕐 Creation timestamp: ${creationTimestamp}`)
|
|
201
|
+
console.log("🔒 Note: Filename is not stored on blockchain for privacy")
|
|
202
|
+
|
|
203
|
+
// Get the function to call
|
|
204
|
+
const functionCall = contractWithSigner.getFunction("publicMintZipFile")
|
|
205
|
+
|
|
206
|
+
// Send the transaction (this will trigger wallet approval)
|
|
207
|
+
// Note: We don't populateTransaction first as it may trigger gas estimation
|
|
208
|
+
// which can hang on some networks. Let the wallet handle it directly.
|
|
209
|
+
// Add timeout to prevent hanging if wallet doesn't respond
|
|
210
|
+
const TX_SEND_TIMEOUT = 60000 // 60 seconds for user to approve
|
|
211
|
+
console.log("⏳ Waiting for wallet approval...")
|
|
212
|
+
const tx = await Promise.race([
|
|
213
|
+
functionCall(
|
|
214
|
+
this.merkleRoot,
|
|
215
|
+
creationTimestamp,
|
|
216
|
+
ipfsHash,
|
|
217
|
+
tokenURI
|
|
218
|
+
),
|
|
219
|
+
new Promise<never>((_, reject) =>
|
|
220
|
+
setTimeout(() => reject(new Error('Transaction send timeout - wallet approval dialog may not have appeared. Please check your wallet.')), TX_SEND_TIMEOUT)
|
|
221
|
+
)
|
|
222
|
+
])
|
|
223
|
+
|
|
224
|
+
console.log(`📜 Transaction submitted: ${tx.hash}`)
|
|
225
|
+
console.log("⏳ Waiting for confirmation...")
|
|
226
|
+
|
|
227
|
+
// Use read provider for waiting to avoid rate limiting with timeout
|
|
228
|
+
let receipt
|
|
229
|
+
const CONFIRMATION_TIMEOUT = 120000 // 2 minutes timeout
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
const readProvider = this.walletManager.getReadProvider()
|
|
233
|
+
if (readProvider) {
|
|
234
|
+
receipt = await Promise.race([
|
|
235
|
+
readProvider.waitForTransaction(tx.hash),
|
|
236
|
+
new Promise((_, reject) =>
|
|
237
|
+
setTimeout(() => reject(new Error('Transaction confirmation timeout')), CONFIRMATION_TIMEOUT)
|
|
238
|
+
)
|
|
239
|
+
])
|
|
240
|
+
} else {
|
|
241
|
+
receipt = await Promise.race([
|
|
242
|
+
tx.wait(),
|
|
243
|
+
new Promise((_, reject) =>
|
|
244
|
+
setTimeout(() => reject(new Error('Transaction confirmation timeout')), CONFIRMATION_TIMEOUT)
|
|
245
|
+
)
|
|
246
|
+
])
|
|
247
|
+
}
|
|
248
|
+
} catch (confirmationError: any) {
|
|
249
|
+
// If timeout, still try to get receipt manually
|
|
250
|
+
if (confirmationError?.message?.includes?.('timeout')) {
|
|
251
|
+
try {
|
|
252
|
+
const readProvider = this.walletManager.getReadProvider()
|
|
253
|
+
const providerForRead = readProvider || provider
|
|
254
|
+
receipt = await providerForRead.getTransactionReceipt(tx.hash)
|
|
255
|
+
if (!receipt) {
|
|
256
|
+
throw new Error(`Transaction ${tx.hash} not found after timeout. It may still be pending.`)
|
|
257
|
+
}
|
|
258
|
+
} catch (manualError: any) {
|
|
259
|
+
throw new Error(`Transaction confirmation failed: ${confirmationError?.message || 'Unknown error'}. Manual lookup also failed: ${manualError?.message || 'Unknown error'}`)
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
throw confirmationError
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
console.log(`✅ Transaction confirmed in block: ${receipt?.blockNumber}`)
|
|
266
|
+
|
|
267
|
+
// Extract token ID from the transaction logs
|
|
268
|
+
let tokenId: string | undefined
|
|
269
|
+
|
|
270
|
+
// Extract token ID from transaction logs
|
|
271
|
+
for (let i = 0; i < receipt.logs.length; i++) {
|
|
272
|
+
const log = receipt.logs[i]
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
const parsed = contract.interface.parseLog(log)
|
|
276
|
+
|
|
277
|
+
if (parsed) {
|
|
278
|
+
if (parsed.name === 'ZipFileTokenized') {
|
|
279
|
+
tokenId = parsed.args.tokenId.toString()
|
|
280
|
+
break
|
|
281
|
+
} else if (parsed.name === 'Transfer') {
|
|
282
|
+
// ERC721 Transfer event: Transfer(from, to, tokenId)
|
|
283
|
+
const from = parsed.args.from
|
|
284
|
+
const transferTokenId = parsed.args.tokenId
|
|
285
|
+
|
|
286
|
+
// Only use Transfer events that are minting (from zero address)
|
|
287
|
+
if (from === '0x0000000000000000000000000000000000000000') {
|
|
288
|
+
tokenId = transferTokenId.toString()
|
|
289
|
+
break
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} catch (parseError) {
|
|
294
|
+
console.warn(`⚠️ Could not parse log ${i}:`, parseError)
|
|
295
|
+
|
|
296
|
+
// Try manual parsing for standard ERC721 Transfer event
|
|
297
|
+
if (log.topics.length >= 4 && log.topics[0] === '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef') {
|
|
298
|
+
try {
|
|
299
|
+
// ERC721 Transfer event signature
|
|
300
|
+
const from = log.topics[1]
|
|
301
|
+
const to = log.topics[2]
|
|
302
|
+
const transferTokenId = log.topics[3]
|
|
303
|
+
|
|
304
|
+
console.log(`🔄 Manual Transfer parse: from=${from}, to=${to}, tokenId=${transferTokenId}`)
|
|
305
|
+
|
|
306
|
+
// Check if this is a mint (from zero address)
|
|
307
|
+
if (from === '0x0000000000000000000000000000000000000000000000000000000000000000') {
|
|
308
|
+
tokenId = parseInt(transferTokenId, 16).toString()
|
|
309
|
+
console.log(`🎯 Found minting via manual parse with token ID: ${tokenId}`)
|
|
310
|
+
break
|
|
311
|
+
}
|
|
312
|
+
} catch (manualParseError) {
|
|
313
|
+
console.warn(`⚠️ Manual parsing also failed:`, manualParseError)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (!tokenId) {
|
|
320
|
+
console.error("❌ Could not extract token ID from any logs")
|
|
321
|
+
console.error("📋 Full receipt for debugging:", JSON.stringify(receipt, null, 2))
|
|
322
|
+
throw new Error("Could not extract token ID from transaction receipt")
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
console.log(`✅ NFT token minted successfully!`)
|
|
326
|
+
console.log(`🎫 Token ID: ${tokenId}`)
|
|
327
|
+
console.log(`📜 Transaction: ${tx.hash}`)
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
success: true,
|
|
331
|
+
tokenId: tokenId,
|
|
332
|
+
transactionHash: tx.hash
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
} catch (error: any) {
|
|
336
|
+
console.error("Token minting failed:", error)
|
|
337
|
+
|
|
338
|
+
let errorMessage = "Unknown error occurred"
|
|
339
|
+
|
|
340
|
+
if (error.code === 'ACTION_REJECTED') {
|
|
341
|
+
errorMessage = "Transaction was rejected by user"
|
|
342
|
+
} else if (error.code === 'INSUFFICIENT_FUNDS') {
|
|
343
|
+
errorMessage = "Insufficient funds for transaction"
|
|
344
|
+
} else if (error.reason) {
|
|
345
|
+
errorMessage = error.reason
|
|
346
|
+
} else if (error.message) {
|
|
347
|
+
errorMessage = error.message
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
success: false,
|
|
352
|
+
error: errorMessage
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Create token metadata
|
|
359
|
+
*/
|
|
360
|
+
createTokenMetadata(
|
|
361
|
+
tokenId: string,
|
|
362
|
+
transactionHash: string
|
|
363
|
+
): TokenMetadata {
|
|
364
|
+
const now = new Date()
|
|
365
|
+
const config = this.walletManager.getCurrentConfig()
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
version: "1.0",
|
|
369
|
+
tokenId,
|
|
370
|
+
contractAddress: config.address,
|
|
371
|
+
network: config.network,
|
|
372
|
+
networkChainId: config.chainId,
|
|
373
|
+
transactionHash,
|
|
374
|
+
merkleRoot: this.merkleRoot,
|
|
375
|
+
mintedAt: now.toISOString(),
|
|
376
|
+
creationTimestamp: Math.floor(now.getTime() / 1000)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get explorer URL for transaction
|
|
382
|
+
*/
|
|
383
|
+
getExplorerUrl(transactionHash: string): string {
|
|
384
|
+
return this.walletManager.getExplorerUrl(transactionHash)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Get explorer URL for contract
|
|
389
|
+
*/
|
|
390
|
+
getContractExplorerUrl(): string {
|
|
391
|
+
return this.walletManager.getContractExplorerUrl()
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Get explorer URL for token
|
|
396
|
+
*/
|
|
397
|
+
getTokenExplorerUrl(tokenId: string): string {
|
|
398
|
+
return this.walletManager.getTokenExplorerUrl(tokenId)
|
|
399
|
+
}
|
|
400
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Blockchain Module Exports
|
|
3
|
+
* Browser-specific blockchain functionality for ZIP file tokenization
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { WalletManagerBrowser } from './WalletManagerBrowser';
|
|
7
|
+
export type { WalletConfigBrowser } from './WalletManagerBrowser';
|
|
8
|
+
|
|
9
|
+
export { ZipkitMinterBrowser } from './ZipkitMinterBrowser';
|
|
10
|
+
export type { TokenizationResult, ExistingToken } from './ZipkitMinterBrowser';
|
|
11
|
+
|
|
12
|
+
export { TokenVerifierBrowser, createTokenVerifier, checkForTokenization } from './TokenVerifierBrowser';
|
|
13
|
+
export type { TokenVerificationResult, TokenVerificationOptions, BlockchainVerification } from './TokenVerifierBrowser';
|