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.
Files changed (301) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +410 -186
  3. package/contracts/ABI.txt +889 -0
  4. package/contracts/Bytecode.txt +1 -0
  5. package/contracts/COMPILATION_NOTES.md +59 -0
  6. package/contracts/QUICK_DEPLOY.md +286 -0
  7. package/contracts/README.md +235 -131
  8. package/contracts/VERIFICATION.md +308 -0
  9. package/contracts/deploy-interactive.js +448 -0
  10. package/contracts/deployment-arbitrum-sepolia.json +12 -0
  11. package/contracts/deployment-arbitrum.json +12 -0
  12. package/contracts/deployment-eth-sepolia.json +12 -0
  13. package/contracts/hardhat.config.js +114 -0
  14. package/contracts/package.json +20 -0
  15. package/contracts/scripts/compile-and-extract.js +119 -0
  16. package/contracts/scripts/verify-contract.js +223 -0
  17. package/contracts/src/{NZIP-NFT-Private.sol → NZIP-NFT-v2.0.sol} +66 -151
  18. package/contracts/src/NZIP-NFT.sol +9 -15
  19. package/dist/blockchain/browser/TokenVerifierBrowser.d.ts +67 -0
  20. package/dist/blockchain/browser/TokenVerifierBrowser.d.ts.map +1 -0
  21. package/dist/blockchain/browser/TokenVerifierBrowser.js +313 -0
  22. package/dist/blockchain/browser/TokenVerifierBrowser.js.map +1 -0
  23. package/dist/blockchain/browser/WalletManagerBrowser.d.ts +98 -0
  24. package/dist/blockchain/browser/WalletManagerBrowser.d.ts.map +1 -0
  25. package/dist/blockchain/browser/WalletManagerBrowser.js +434 -0
  26. package/dist/blockchain/browser/WalletManagerBrowser.js.map +1 -0
  27. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts +58 -0
  28. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts.map +1 -0
  29. package/dist/blockchain/browser/ZipkitMinterBrowser.js +317 -0
  30. package/dist/blockchain/browser/ZipkitMinterBrowser.js.map +1 -0
  31. package/dist/blockchain/browser/index.d.ts +11 -0
  32. package/dist/blockchain/browser/index.d.ts.map +1 -0
  33. package/dist/blockchain/browser/index.js +16 -0
  34. package/dist/blockchain/browser/index.js.map +1 -0
  35. package/dist/blockchain/core/WalletManager.d.ts +124 -0
  36. package/dist/blockchain/core/WalletManager.d.ts.map +1 -0
  37. package/dist/blockchain/{ZipKitWallet.js → core/WalletManager.js} +157 -177
  38. package/dist/blockchain/core/WalletManager.js.map +1 -0
  39. package/dist/blockchain/{ZipKitMinter.d.ts → core/ZipkitMinter.d.ts} +46 -11
  40. package/dist/blockchain/core/ZipkitMinter.d.ts.map +1 -0
  41. package/dist/blockchain/core/ZipkitMinter.js +548 -0
  42. package/dist/blockchain/core/ZipkitMinter.js.map +1 -0
  43. package/dist/blockchain/{ZipKitOTS.d.ts → core/ZipkitOTS.d.ts} +6 -15
  44. package/dist/blockchain/core/ZipkitOTS.d.ts.map +1 -0
  45. package/dist/blockchain/{ZipKitOTS.js → core/ZipkitOTS.js} +26 -84
  46. package/dist/blockchain/core/ZipkitOTS.js.map +1 -0
  47. package/dist/blockchain/core/ZipkitVerifier.d.ts +177 -0
  48. package/dist/blockchain/core/ZipkitVerifier.d.ts.map +1 -0
  49. package/dist/blockchain/core/ZipkitVerifier.js +632 -0
  50. package/dist/blockchain/core/ZipkitVerifier.js.map +1 -0
  51. package/dist/blockchain/core/contracts.d.ts +83 -0
  52. package/dist/blockchain/core/contracts.d.ts.map +1 -0
  53. package/dist/blockchain/core/contracts.js +341 -0
  54. package/dist/blockchain/core/contracts.js.map +1 -0
  55. package/dist/blockchain/core/index.d.ts +12 -0
  56. package/dist/blockchain/core/index.d.ts.map +1 -0
  57. package/dist/blockchain/core/index.js +59 -0
  58. package/dist/blockchain/core/index.js.map +1 -0
  59. package/dist/blockchain/index.d.ts +11 -7
  60. package/dist/blockchain/index.d.ts.map +1 -0
  61. package/dist/blockchain/index.js +18 -34
  62. package/dist/blockchain/index.js.map +1 -0
  63. package/dist/blockchain/node/WalletManagerNode.d.ts +47 -0
  64. package/dist/blockchain/node/WalletManagerNode.d.ts.map +1 -0
  65. package/dist/blockchain/node/WalletManagerNode.js +203 -0
  66. package/dist/blockchain/node/WalletManagerNode.js.map +1 -0
  67. package/dist/blockchain/node/index.d.ts +12 -0
  68. package/dist/blockchain/node/index.d.ts.map +1 -0
  69. package/dist/blockchain/node/index.js +24 -0
  70. package/dist/blockchain/node/index.js.map +1 -0
  71. package/dist/browser/ZipkitBrowser.d.ts +27 -0
  72. package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
  73. package/dist/browser/{ZipKitBrowser.js → ZipkitBrowser.js} +96 -43
  74. package/dist/browser/ZipkitBrowser.js.map +1 -0
  75. package/dist/browser/index.d.ts +12 -0
  76. package/dist/browser/index.d.ts.map +1 -0
  77. package/dist/browser/index.js +42 -0
  78. package/dist/browser/index.js.map +1 -0
  79. package/dist/browser-esm/index.d.ts +12 -0
  80. package/dist/browser-esm/index.js +59559 -0
  81. package/dist/browser-esm/index.js.map +7 -0
  82. package/dist/browser-umd/index.d.ts +12 -0
  83. package/dist/browser-umd/index.js +59576 -0
  84. package/dist/browser-umd/index.js.map +7 -0
  85. package/dist/browser-umd/index.min.js +63 -0
  86. package/dist/browser.d.ts +8 -14
  87. package/dist/browser.js +13 -28
  88. package/dist/core/ZipCompress.d.ts +99 -0
  89. package/dist/core/ZipCompress.d.ts.map +1 -0
  90. package/dist/core/ZipCompress.js +309 -0
  91. package/dist/core/ZipCompress.js.map +1 -0
  92. package/dist/core/ZipDecompress.d.ts +58 -0
  93. package/dist/core/ZipDecompress.d.ts.map +1 -0
  94. package/dist/core/ZipDecompress.js +172 -0
  95. package/dist/core/ZipDecompress.js.map +1 -0
  96. package/dist/{shared → core}/ZipEntry.d.ts +8 -1
  97. package/dist/core/ZipEntry.d.ts.map +1 -0
  98. package/dist/{shared → core}/ZipEntry.js +225 -82
  99. package/dist/core/ZipEntry.js.map +1 -0
  100. package/dist/core/Zipkit.d.ts +315 -0
  101. package/dist/core/Zipkit.d.ts.map +1 -0
  102. package/dist/core/Zipkit.js +647 -0
  103. package/dist/core/Zipkit.js.map +1 -0
  104. package/dist/core/components/HashCalculator.d.ts +138 -0
  105. package/dist/core/components/HashCalculator.d.ts.map +1 -0
  106. package/dist/core/components/HashCalculator.js +360 -0
  107. package/dist/core/components/HashCalculator.js.map +1 -0
  108. package/dist/core/components/Logger.d.ts +73 -0
  109. package/dist/core/components/Logger.d.ts.map +1 -0
  110. package/dist/core/components/Logger.js +156 -0
  111. package/dist/core/components/Logger.js.map +1 -0
  112. package/dist/core/components/ProgressTracker.d.ts +43 -0
  113. package/dist/core/components/ProgressTracker.d.ts.map +1 -0
  114. package/dist/core/components/ProgressTracker.js +112 -0
  115. package/dist/core/components/ProgressTracker.js.map +1 -0
  116. package/dist/{shared → core}/components/Support.d.ts +1 -0
  117. package/dist/core/components/Support.d.ts.map +1 -0
  118. package/dist/{shared → core}/components/Support.js +1 -0
  119. package/dist/core/components/Support.js.map +1 -0
  120. package/dist/{shared → core}/components/Util.d.ts +7 -2
  121. package/dist/core/components/Util.d.ts.map +1 -0
  122. package/dist/{shared → core}/components/Util.js +14 -34
  123. package/dist/core/components/Util.js.map +1 -0
  124. package/dist/{shared → core}/constants/Errors.d.ts +1 -2
  125. package/dist/core/constants/Errors.d.ts.map +1 -0
  126. package/dist/{shared → core}/constants/Errors.js +1 -3
  127. package/dist/core/constants/Errors.js.map +1 -0
  128. package/dist/{shared → core}/constants/Headers.d.ts +3 -0
  129. package/dist/core/constants/Headers.d.ts.map +1 -0
  130. package/dist/{shared → core}/constants/Headers.js +20 -17
  131. package/dist/core/constants/Headers.js.map +1 -0
  132. package/dist/core/encryption/Manager.d.ts +58 -0
  133. package/dist/core/encryption/Manager.d.ts.map +1 -0
  134. package/dist/core/encryption/Manager.js +121 -0
  135. package/dist/core/encryption/Manager.js.map +1 -0
  136. package/dist/core/encryption/ZipCrypto.d.ts +172 -0
  137. package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
  138. package/dist/core/encryption/ZipCrypto.js +554 -0
  139. package/dist/core/encryption/ZipCrypto.js.map +1 -0
  140. package/dist/core/encryption/index.d.ts +9 -0
  141. package/dist/core/encryption/index.d.ts.map +1 -0
  142. package/dist/core/encryption/index.js +17 -0
  143. package/dist/core/encryption/index.js.map +1 -0
  144. package/dist/core/encryption/types.d.ts +29 -0
  145. package/dist/core/encryption/types.d.ts.map +1 -0
  146. package/dist/core/encryption/types.js +12 -0
  147. package/dist/core/encryption/types.js.map +1 -0
  148. package/dist/core/index.d.ts +24 -0
  149. package/dist/core/index.d.ts.map +1 -0
  150. package/dist/core/index.js +57 -0
  151. package/dist/core/index.js.map +1 -0
  152. package/dist/core/version.d.ts +5 -0
  153. package/dist/core/version.d.ts.map +1 -0
  154. package/dist/core/version.js +31 -0
  155. package/dist/core/version.js.map +1 -0
  156. package/dist/index.d.ts +8 -18
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +29 -35
  159. package/dist/index.js.map +1 -0
  160. package/dist/node/ZipCompressNode.d.ts +123 -0
  161. package/dist/node/ZipCompressNode.d.ts.map +1 -0
  162. package/dist/node/ZipCompressNode.js +576 -0
  163. package/dist/node/ZipCompressNode.js.map +1 -0
  164. package/dist/node/ZipDecompressNode.d.ts +120 -0
  165. package/dist/node/ZipDecompressNode.d.ts.map +1 -0
  166. package/dist/node/ZipDecompressNode.js +461 -0
  167. package/dist/node/ZipDecompressNode.js.map +1 -0
  168. package/dist/node/ZipkitNode.d.ts +406 -0
  169. package/dist/node/ZipkitNode.d.ts.map +1 -0
  170. package/dist/node/ZipkitNode.js +1305 -0
  171. package/dist/node/ZipkitNode.js.map +1 -0
  172. package/dist/node/index.d.ts +26 -0
  173. package/dist/node/index.d.ts.map +1 -0
  174. package/dist/node/index.js +65 -0
  175. package/dist/node/index.js.map +1 -0
  176. package/dist/types/index.d.ts +59 -0
  177. package/dist/types/index.d.ts.map +1 -0
  178. package/dist/types/index.js +36 -1
  179. package/dist/types/index.js.map +1 -0
  180. package/examples/README.md +269 -0
  181. package/examples/blockchain-tokenize.ts +354 -0
  182. package/examples/create-zip.ts +172 -0
  183. package/examples/extract-zip.ts +158 -0
  184. package/examples/list-zip.ts +161 -0
  185. package/examples/test-files/data.json +116 -0
  186. package/examples/test-files/document.md +80 -0
  187. package/examples/test-files/document.txt +2 -0
  188. package/examples/test-files/file1.txt +48 -0
  189. package/examples/test-files/file2.txt +80 -0
  190. package/examples/tsconfig.json +44 -0
  191. package/examples/unzip-token.ts +491 -0
  192. package/examples/verify-tokenized-zip.ts +305 -0
  193. package/examples/zip-token.ts +604 -0
  194. package/package.json +108 -24
  195. package/src/blockchain/README.md +59 -66
  196. package/src/{browser/TokenVerifierBrowser.ts-remove → blockchain/browser/TokenVerifierBrowser.ts} +125 -79
  197. package/src/blockchain/browser/WalletManagerBrowser.ts +486 -0
  198. package/src/blockchain/browser/ZipkitMinterBrowser.ts +400 -0
  199. package/src/blockchain/browser/index.ts +13 -0
  200. package/src/blockchain/{ZipKitWallet.ts → core/WalletManager.ts} +241 -143
  201. package/src/blockchain/core/ZipkitMinter.ts +716 -0
  202. package/src/blockchain/{ZipKitOTS.ts → core/ZipkitOTS.ts} +28 -62
  203. package/src/blockchain/core/ZipkitVerifier.ts +853 -0
  204. package/src/blockchain/core/contracts.ts +370 -0
  205. package/src/blockchain/core/index.ts +71 -0
  206. package/src/blockchain/index.ts +21 -55
  207. package/src/blockchain/node/WalletManagerNode.ts +171 -0
  208. package/src/blockchain/node/index.ts +40 -0
  209. package/src/browser/{ZipKitBrowser.ts → ZipkitBrowser.ts} +104 -41
  210. package/src/browser/index.esm.ts +37 -0
  211. package/src/browser/index.ts +25 -0
  212. package/src/core/ZipCompress.ts +398 -0
  213. package/src/core/ZipDecompress.ts +212 -0
  214. package/src/{shared → core}/ZipEntry.ts +240 -90
  215. package/src/core/Zipkit.ts +794 -0
  216. package/src/core/components/HashCalculator.ts +384 -0
  217. package/src/core/components/Logger.ts +180 -0
  218. package/src/core/components/ProgressTracker.ts +134 -0
  219. package/src/{shared → core}/components/Util.ts +12 -34
  220. package/src/{shared → core}/constants/Errors.ts +0 -4
  221. package/src/{shared → core}/constants/Headers.ts +19 -17
  222. package/src/core/encryption/Manager.ts +137 -0
  223. package/src/core/encryption/ZipCrypto.ts +650 -0
  224. package/src/core/encryption/index.ts +15 -0
  225. package/src/core/encryption/types.ts +33 -0
  226. package/src/core/index.ts +34 -0
  227. package/src/core/version.ts +33 -0
  228. package/src/index.ts +54 -25
  229. package/src/node/ZipCompressNode.ts +632 -0
  230. package/src/node/ZipDecompressNode.ts +508 -0
  231. package/src/node/ZipkitNode.ts +1559 -0
  232. package/src/node/index.ts +69 -0
  233. package/src/types/index.ts +131 -1
  234. package/src/types/modules.d.ts +1 -11
  235. package/src/types/opentimestamps.d.ts +1 -23
  236. package/contracts/INTEGRATION.md +0 -338
  237. package/contracts/NETWORKS.md +0 -156
  238. package/contracts/NZIP-NFT-bytecode.txt +0 -1
  239. package/contracts/constants.ts +0 -952
  240. package/contracts/deploy-bytecode.mjs +0 -94
  241. package/dist/blockchain/CertificateToken.d.ts +0 -48
  242. package/dist/blockchain/CertificateToken.js +0 -386
  243. package/dist/blockchain/ZipKitMinter.js +0 -347
  244. package/dist/blockchain/ZipKitNFT.d.ts +0 -3
  245. package/dist/blockchain/ZipKitNFT.js +0 -7
  246. package/dist/blockchain/ZipKitVerifier.d.ts +0 -69
  247. package/dist/blockchain/ZipKitVerifier.js +0 -289
  248. package/dist/blockchain/ZipKitWallet.d.ts +0 -69
  249. package/dist/blockchain/contracts.d.ts +0 -14
  250. package/dist/blockchain/contracts.js +0 -77
  251. package/dist/blockchain/types.d.ts +0 -47
  252. package/dist/blockchain/types.js +0 -30
  253. package/dist/browser/ZipKitBrowser.d.ts +0 -18
  254. package/dist/browser/ZipKitStampBrowser.d.ts +0 -2
  255. package/dist/browser/ZipKitStampBrowser.js +0 -12
  256. package/dist/browser-index.d.ts +0 -18
  257. package/dist/browser-index.js +0 -57
  258. package/dist/server/ZipKitServer.d.ts +0 -74
  259. package/dist/server/ZipKitServer.js +0 -310
  260. package/dist/shared/ZipKit.d.ts +0 -243
  261. package/dist/shared/ZipKit.js +0 -772
  262. package/dist/shared/components/CertificateOTS.d.ts +0 -15
  263. package/dist/shared/components/CertificateOTS.js +0 -116
  264. package/dist/shared/components/FileSys.d.ts +0 -2
  265. package/dist/shared/components/FileSys.js +0 -113
  266. package/dist/shared/components/HashAccumulator.d.ts +0 -55
  267. package/dist/shared/components/HashAccumulator.js +0 -100
  268. package/dist/shared/components/ZipCrypto.d.ts +0 -3
  269. package/dist/shared/components/ZipCrypto.js +0 -78
  270. package/dist/shared/components/merkleTree.d.ts +0 -66
  271. package/dist/shared/components/merkleTree.js +0 -136
  272. package/dist/shared/types/index.d.ts +0 -21
  273. package/dist/shared/types/index.js +0 -3
  274. package/dist/shared/types.d.ts +0 -33
  275. package/dist/shared/types.js +0 -8
  276. package/dist/shared/version.d.ts +0 -2
  277. package/dist/shared/version.js +0 -6
  278. package/src/blockchain/CertificateToken.ts +0 -444
  279. package/src/blockchain/ZipKitMinter.ts +0 -470
  280. package/src/blockchain/ZipKitNFT.ts +0 -12
  281. package/src/blockchain/ZipKitVerifier.ts +0 -382
  282. package/src/blockchain/contracts.ts +0 -88
  283. package/src/blockchain/types.ts +0 -91
  284. package/src/browser/CertificateGeneratorBrowser.ts-remove +0 -498
  285. package/src/browser/ZipKitStampBrowser.ts +0 -9
  286. package/src/browser-index.ts +0 -36
  287. package/src/server/README.md +0 -25
  288. package/src/server/ZipKitServer.ts +0 -305
  289. package/src/shared/ZipKit.ts +0 -881
  290. package/src/shared/components/CertificateOTS.ts +0 -132
  291. package/src/shared/components/FileSys.ts +0 -87
  292. package/src/shared/components/HashAccumulator.ts +0 -113
  293. package/src/shared/components/ZipCrypto.ts +0 -91
  294. package/src/shared/components/merkleTree.ts +0 -162
  295. package/src/shared/types/index.ts +0 -25
  296. package/src/shared/types/modules.d.ts +0 -22
  297. package/src/shared/types/opentimestamps.d.ts +0 -23
  298. package/src/shared/types.d.ts +0 -8
  299. package/src/shared/types.ts +0 -43
  300. package/src/shared/version.ts +0 -3
  301. /package/src/{shared → core}/components/Support.ts +0 -0
@@ -4,23 +4,12 @@
4
4
  // Copyright (c) 2025 NeoWare, Inc. All rights reserved.
5
5
  // ======================================
6
6
 
7
- import ZipKitBrowser from './ZipKitBrowser';
8
- import { ZipEntry } from '../shared/ZipKit';
9
- import { TOKENIZED_METADATA } from '../shared/constants/Headers';
10
- import { NZIP_CONTRACT_ABI, CURRENT_DEPLOYMENT } from '../blockchain/constants';
11
-
12
- // Token types (adapted for browser)
13
- export interface NZipTokenInfo {
14
- version: string;
15
- tokenId: string;
16
- contractAddress: string;
17
- network: string;
18
- networkChainId: number;
19
- transactionHash: string;
20
- merkleRoot: string;
21
- fileName: string;
22
- mintedAt: string;
23
- }
7
+ import ZipkitBrowser from '../../browser/ZipkitBrowser';
8
+ import { ZipEntry } from '../../core';
9
+ import { TOKENIZED_METADATA } from '../../core/constants/Headers';
10
+ import { TokenMetadata } from '../../types';
11
+ import { NZIP_CONTRACT_ABI, getContractConfig } from '../core/contracts';
12
+ import { ethers } from 'ethers';
24
13
 
25
14
  export interface TokenVerificationOptions {
26
15
  skipHash?: boolean;
@@ -31,7 +20,7 @@ export interface TokenVerificationOptions {
31
20
 
32
21
  export interface TokenVerificationResult {
33
22
  isTokenized: boolean;
34
- tokenMetadata: NZipTokenInfo | null;
23
+ tokenMetadata: TokenMetadata | null;
35
24
  calculatedMerkleRoot: string | null;
36
25
  blockchainMerkleRoot: string | null;
37
26
  blockchainTimestamp?: number; // Actual blockchain timestamp from tokenizationTime
@@ -49,28 +38,6 @@ export interface BlockchainVerification {
49
38
  blockNumber?: number;
50
39
  }
51
40
 
52
- // Network configuration for blockchain queries
53
- const NETWORK_CONFIG: Record<string, any> = {
54
- 'Base Sepolia': {
55
- chainId: 84532,
56
- rpcUrls: [
57
- 'https://sepolia.base.org',
58
- 'https://base-sepolia.g.alchemy.com/v2/demo',
59
- 'https://base-sepolia-rpc.publicnode.com',
60
- 'https://base-sepolia.blockpi.network/v1/rpc/public'
61
- ]
62
- },
63
- 'Base Mainnet': {
64
- chainId: 8453,
65
- rpcUrls: [
66
- 'https://mainnet.base.org',
67
- 'https://base-mainnet.g.alchemy.com/v2/demo',
68
- 'https://base-rpc.publicnode.com',
69
- 'https://base.blockpi.network/v1/rpc/public'
70
- ]
71
- }
72
- };
73
-
74
41
  // Use the complete contract ABI from constants
75
42
  const CONTRACT_ABI = NZIP_CONTRACT_ABI;
76
43
 
@@ -78,10 +45,10 @@ const CONTRACT_ABI = NZIP_CONTRACT_ABI;
78
45
  * Browser-compatible token verification class
79
46
  */
80
47
  export class TokenVerifierBrowser {
81
- private zipKit: ZipKitBrowser;
48
+ private zipkit: ZipkitBrowser;
82
49
 
83
- constructor(zipKit: ZipKitBrowser) {
84
- this.zipKit = zipKit;
50
+ constructor(zipkit: ZipkitBrowser) {
51
+ this.zipkit = zipkit;
85
52
  }
86
53
 
87
54
  /**
@@ -106,7 +73,7 @@ export class TokenVerifierBrowser {
106
73
 
107
74
  try {
108
75
  // Extract the token metadata
109
- const tokenData = await this.zipKit.extractBlob(tokenEntry);
76
+ const tokenData = await this.zipkit.extractBlob(tokenEntry);
110
77
 
111
78
  if (!tokenData) {
112
79
  return {
@@ -164,9 +131,15 @@ export class TokenVerifierBrowser {
164
131
  const blockchainData = await this.queryBlockchainData(tokenMetadata);
165
132
 
166
133
  if (!blockchainData.merkleRoot) {
134
+ // Add owner information to tokenMetadata even if merkle root is not available
135
+ const enhancedTokenMetadata = {
136
+ ...tokenMetadata,
137
+ owner: blockchainData.owner || undefined
138
+ };
139
+
167
140
  return {
168
141
  isTokenized: true,
169
- tokenMetadata,
142
+ tokenMetadata: enhancedTokenMetadata,
170
143
  calculatedMerkleRoot,
171
144
  blockchainMerkleRoot: null,
172
145
  blockchainTimestamp: blockchainData.timestamp ?? undefined,
@@ -175,16 +148,30 @@ export class TokenVerifierBrowser {
175
148
  };
176
149
  }
177
150
 
178
- const verificationPassed = blockchainData.merkleRoot === calculatedMerkleRoot;
151
+ // Normalize both merkle roots for comparison (trim whitespace, lowercase)
152
+ const normalizedBlockchain = blockchainData.merkleRoot?.toLowerCase().trim() || '';
153
+ const normalizedCalculated = calculatedMerkleRoot?.toLowerCase().trim() || '';
154
+ const verificationPassed = normalizedBlockchain === normalizedCalculated;
155
+
156
+ // Log mismatch only (success is silent)
157
+ if (!verificationPassed) {
158
+ console.warn(`[TokenVerifier] ⚠️ Merkle root mismatch - Calculated: ${calculatedMerkleRoot}, Blockchain: ${blockchainData.merkleRoot}`);
159
+ }
160
+
161
+ // Add owner information to tokenMetadata
162
+ const enhancedTokenMetadata = {
163
+ ...tokenMetadata,
164
+ owner: blockchainData.owner || undefined
165
+ };
179
166
 
180
167
  return {
181
168
  isTokenized: true,
182
- tokenMetadata,
169
+ tokenMetadata: enhancedTokenMetadata,
183
170
  calculatedMerkleRoot,
184
171
  blockchainMerkleRoot: blockchainData.merkleRoot,
185
172
  blockchainTimestamp: blockchainData.timestamp ?? undefined,
186
173
  verificationPassed,
187
- errorMessage: verificationPassed ? undefined : 'Merkle root mismatch - archive may be tampered'
174
+ errorMessage: verificationPassed ? undefined : `Merkle root mismatch - Calculated: ${calculatedMerkleRoot}, Blockchain: ${blockchainData.merkleRoot}`
188
175
  };
189
176
 
190
177
  } catch (error) {
@@ -202,7 +189,7 @@ export class TokenVerifierBrowser {
202
189
  /**
203
190
  * Validates token metadata structure
204
191
  */
205
- private validateTokenInfo(tokenMetadata: any): tokenMetadata is NZipTokenInfo {
192
+ private validateTokenInfo(tokenMetadata: any): tokenMetadata is TokenMetadata {
206
193
  return tokenMetadata &&
207
194
  typeof tokenMetadata.version === 'string' &&
208
195
  typeof tokenMetadata.tokenId === 'string' &&
@@ -211,7 +198,6 @@ export class TokenVerifierBrowser {
211
198
  typeof tokenMetadata.networkChainId === 'number' &&
212
199
  typeof tokenMetadata.transactionHash === 'string' &&
213
200
  typeof tokenMetadata.merkleRoot === 'string' &&
214
- typeof tokenMetadata.fileName === 'string' &&
215
201
  typeof tokenMetadata.mintedAt === 'string';
216
202
  }
217
203
 
@@ -224,6 +210,7 @@ export class TokenVerifierBrowser {
224
210
  const contentEntries = zipEntries.filter(entry => entry.filename !== TOKENIZED_METADATA);
225
211
 
226
212
  if (contentEntries.length === 0) {
213
+ console.error(`[TokenVerifier] ❌ No content entries found after filtering`);
227
214
  return null;
228
215
  }
229
216
 
@@ -231,41 +218,96 @@ export class TokenVerifierBrowser {
231
218
  for (const entry of contentEntries) {
232
219
  if (!entry.sha256) {
233
220
  // Extract the file to calculate its SHA-256 hash
234
- await this.zipKit.extractBlob(entry);
221
+ await this.zipkit.extractBlob(entry);
235
222
  }
236
223
  }
237
224
 
238
225
  // Calculate merkle root from content files
239
- // This would need to be implemented based on the ZipKit's merkle tree functionality
240
- // For now, we'll use a placeholder that would need to be implemented
241
- return await this.zipKit.getMerkleRoot?.() || null;
226
+ // getMerkleRoot() already excludes TOKENIZED_METADATA, TIMESTAMP_SUBMITTED, and TIMESTAMP_METADATA
227
+ const merkleRoot = await this.zipkit.getMerkleRoot?.() || null;
228
+
229
+ if (!merkleRoot) {
230
+ console.error(`[TokenVerifier] ❌ Failed to calculate merkle root`);
231
+ }
232
+
233
+ return merkleRoot;
242
234
  } catch (error) {
243
- console.error('Error calculating merkle root:', error);
235
+ console.error(`[TokenVerifier] ❌ Error calculating merkle root:`, error);
244
236
  return null;
245
237
  }
246
238
  }
247
239
 
248
240
  /**
249
- * Queries the blockchain to get the actual merkle root and timestamp stored in the smart contract
241
+ * Queries the blockchain to get the actual merkle root, timestamp, and owner stored in the smart contract
250
242
  */
251
- private async queryBlockchainData(tokenMetadata: NZipTokenInfo): Promise<{merkleRoot: string | null, timestamp: number | null}> {
243
+ private async queryBlockchainData(tokenMetadata: TokenMetadata): Promise<{merkleRoot: string | null, timestamp: number | null, owner: string | null}> {
252
244
  try {
253
- // Dynamic import of ethers to avoid SSR issues
254
- const { ethers } = await import('ethers');
245
+ // Get network configuration from contracts.ts (single source of truth)
246
+ if (!tokenMetadata.networkChainId) {
247
+ console.error(`[TokenVerifier] ❌ No chainId in token metadata`);
248
+ return { merkleRoot: null, timestamp: null, owner: null };
249
+ }
250
+
251
+ const networkConfig = getContractConfig(tokenMetadata.networkChainId);
255
252
 
256
- const networkConfig = NETWORK_CONFIG[tokenMetadata.network];
257
253
  if (!networkConfig) {
258
- console.warn(`Unsupported network: ${tokenMetadata.network}`);
259
- return { merkleRoot: null, timestamp: null };
254
+ console.error(`[TokenVerifier] ❌ Could not resolve network configuration for chainId: ${tokenMetadata.networkChainId}`);
255
+ return { merkleRoot: null, timestamp: null, owner: null };
260
256
  }
261
257
 
262
- // Try multiple RPC endpoints
258
+ // Test RPC endpoints first to find working ones (same as server-side)
259
+ const workingRpcUrls: string[] = [];
260
+
263
261
  for (const rpcUrl of networkConfig.rpcUrls) {
262
+ try {
263
+ const controller = new AbortController();
264
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
265
+
266
+ const testResponse = await fetch(rpcUrl, {
267
+ method: 'POST',
268
+ headers: { 'Content-Type': 'application/json' },
269
+ body: JSON.stringify({
270
+ jsonrpc: '2.0',
271
+ method: 'eth_chainId',
272
+ params: [],
273
+ id: 1
274
+ }),
275
+ signal: controller.signal
276
+ });
277
+
278
+ clearTimeout(timeoutId);
279
+
280
+ if (testResponse.ok) {
281
+ const contentType = testResponse.headers.get('content-type');
282
+ if (contentType && contentType.includes('application/json')) {
283
+ const testData = await testResponse.json() as { jsonrpc?: string; result?: string };
284
+ if (testData?.jsonrpc && testData?.result) {
285
+ const actualChainId = parseInt(testData.result, 16);
286
+ if (actualChainId === tokenMetadata.networkChainId) {
287
+ workingRpcUrls.push(rpcUrl);
288
+ }
289
+ }
290
+ }
291
+ }
292
+ } catch (testError: any) {
293
+ // Silently skip failed endpoints
294
+ }
295
+ }
296
+
297
+ if (workingRpcUrls.length === 0) {
298
+ // Fallback to all endpoints if none tested successfully
299
+ workingRpcUrls.push(...networkConfig.rpcUrls);
300
+ }
301
+
302
+ // Try multiple RPC endpoints (only working ones if available)
303
+ for (let i = 0; i < workingRpcUrls.length; i++) {
304
+ const rpcUrl = workingRpcUrls[i];
305
+
264
306
  try {
265
307
  const provider = new ethers.JsonRpcProvider(rpcUrl);
266
308
 
267
309
  // Test connection with a timeout
268
- const blockNumber = await Promise.race([
310
+ await Promise.race([
269
311
  provider.getBlockNumber(),
270
312
  new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
271
313
  ]);
@@ -276,23 +318,27 @@ export class TokenVerifierBrowser {
276
318
  // Call getZipFileInfo to get the blockchain-stored data
277
319
  const zipInfo = await contract.getZipFileInfo(tokenMetadata.tokenId);
278
320
 
321
+ // Get the token owner
322
+ const owner = await contract.ownerOf(tokenMetadata.tokenId);
323
+
279
324
  return {
280
325
  merkleRoot: zipInfo.merkleRootHash,
281
- timestamp: Number(zipInfo.tokenizationTime)
326
+ timestamp: Number(zipInfo.tokenizationTime),
327
+ owner: owner
282
328
  };
283
329
 
284
- } catch (error) {
285
- console.warn(`RPC ${rpcUrl} failed:`, error);
330
+ } catch (error: any) {
331
+ // Continue to next endpoint on error
286
332
  continue;
287
333
  }
288
334
  }
289
335
 
290
- console.warn(`All RPC endpoints failed for network: ${tokenMetadata.network}`);
291
- return { merkleRoot: null, timestamp: null };
336
+ console.error(`[TokenVerifier] ❌ All RPC endpoints failed for network: ${tokenMetadata.network}`);
337
+ return { merkleRoot: null, timestamp: null, owner: null };
292
338
 
293
- } catch (error) {
294
- console.error('Blockchain query error:', error);
295
- return { merkleRoot: null, timestamp: null };
339
+ } catch (error: any) {
340
+ console.error(`[TokenVerifier] ❌ Blockchain query error:`, error?.message || error);
341
+ return { merkleRoot: null, timestamp: null, owner: null };
296
342
  }
297
343
  }
298
344
 
@@ -311,15 +357,15 @@ export class TokenVerifierBrowser {
311
357
  /**
312
358
  * Creates a formatted summary of token information
313
359
  */
314
- createTokenSummary(tokenMetadata: NZipTokenInfo): string {
360
+ createTokenSummary(tokenMetadata: TokenMetadata): string {
315
361
  return `
316
362
  🎫 NFT Token Information:
317
363
  Token ID: ${tokenMetadata.tokenId}
318
364
  Network: ${tokenMetadata.network}
319
365
  Contract: ${tokenMetadata.contractAddress}
320
366
  Transaction: ${tokenMetadata.transactionHash}
321
- File: ${tokenMetadata.fileName}
322
- Minted: ${new Date(tokenMetadata.mintedAt).toLocaleString()}
367
+ Type: Tokenized Archive
368
+ Minted: ${tokenMetadata.mintedAt ? new Date(tokenMetadata.mintedAt).toLocaleString() : 'Unknown'}
323
369
  `;
324
370
  }
325
371
  }
@@ -327,18 +373,18 @@ export class TokenVerifierBrowser {
327
373
  /**
328
374
  * Creates a new TokenVerifierBrowser instance
329
375
  */
330
- export function createTokenVerifier(zipKit: ZipKitBrowser): TokenVerifierBrowser {
331
- return new TokenVerifierBrowser(zipKit);
376
+ export function createTokenVerifier(zipkit: ZipkitBrowser): TokenVerifierBrowser {
377
+ return new TokenVerifierBrowser(zipkit);
332
378
  }
333
379
 
334
380
  /**
335
381
  * Convenience function to check for tokenization
336
382
  */
337
383
  export async function checkForTokenization(
338
- zipKit: ZipKitBrowser,
384
+ zipkit: ZipkitBrowser,
339
385
  zipEntries: ZipEntry[],
340
386
  options: TokenVerificationOptions = {}
341
387
  ): Promise<TokenVerificationResult> {
342
- const verifier = new TokenVerifierBrowser(zipKit);
388
+ const verifier = new TokenVerifierBrowser(zipkit);
343
389
  return verifier.checkForTokenization(zipEntries, options);
344
390
  }