neozip-blockchain 0.5.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.
Files changed (127) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +189 -0
  3. package/dist/browser/TokenVerifierBrowser.d.ts +63 -0
  4. package/dist/browser/TokenVerifierBrowser.d.ts.map +1 -0
  5. package/dist/browser/TokenVerifierBrowser.js +358 -0
  6. package/dist/browser/TokenVerifierBrowser.js.map +1 -0
  7. package/dist/browser/WalletManagerBrowser.d.ts +99 -0
  8. package/dist/browser/WalletManagerBrowser.d.ts.map +1 -0
  9. package/dist/browser/WalletManagerBrowser.js +434 -0
  10. package/dist/browser/WalletManagerBrowser.js.map +1 -0
  11. package/dist/browser/ZipkitMinterBrowser.d.ts +59 -0
  12. package/dist/browser/ZipkitMinterBrowser.d.ts.map +1 -0
  13. package/dist/browser/ZipkitMinterBrowser.js +337 -0
  14. package/dist/browser/ZipkitMinterBrowser.js.map +1 -0
  15. package/dist/browser/index.d.ts +12 -0
  16. package/dist/browser/index.d.ts.map +1 -0
  17. package/dist/browser/index.js +19 -0
  18. package/dist/browser/index.js.map +1 -0
  19. package/dist/constants/index.d.ts +5 -0
  20. package/dist/constants/index.d.ts.map +1 -0
  21. package/dist/constants/index.js +21 -0
  22. package/dist/constants/index.js.map +1 -0
  23. package/dist/constants/metadata.d.ts +18 -0
  24. package/dist/constants/metadata.d.ts.map +1 -0
  25. package/dist/constants/metadata.js +33 -0
  26. package/dist/constants/metadata.js.map +1 -0
  27. package/dist/constants/servers.d.ts +38 -0
  28. package/dist/constants/servers.d.ts.map +1 -0
  29. package/dist/constants/servers.js +54 -0
  30. package/dist/constants/servers.js.map +1 -0
  31. package/dist/core/ContractVersionRegistry.d.ts +63 -0
  32. package/dist/core/ContractVersionRegistry.d.ts.map +1 -0
  33. package/dist/core/ContractVersionRegistry.js +128 -0
  34. package/dist/core/ContractVersionRegistry.js.map +1 -0
  35. package/dist/core/WalletManager.d.ts +123 -0
  36. package/dist/core/WalletManager.d.ts.map +1 -0
  37. package/dist/core/WalletManager.js +360 -0
  38. package/dist/core/WalletManager.js.map +1 -0
  39. package/dist/core/ZipkitMinter.d.ts +155 -0
  40. package/dist/core/ZipkitMinter.d.ts.map +1 -0
  41. package/dist/core/ZipkitMinter.js +625 -0
  42. package/dist/core/ZipkitMinter.js.map +1 -0
  43. package/dist/core/ZipkitVerifier.d.ts +252 -0
  44. package/dist/core/ZipkitVerifier.d.ts.map +1 -0
  45. package/dist/core/ZipkitVerifier.js +1370 -0
  46. package/dist/core/ZipkitVerifier.js.map +1 -0
  47. package/dist/core/adapters/AdapterFactory.d.ts +22 -0
  48. package/dist/core/adapters/AdapterFactory.d.ts.map +1 -0
  49. package/dist/core/adapters/AdapterFactory.js +62 -0
  50. package/dist/core/adapters/AdapterFactory.js.map +1 -0
  51. package/dist/core/adapters/ContractVersionAdapter.d.ts +96 -0
  52. package/dist/core/adapters/ContractVersionAdapter.d.ts.map +1 -0
  53. package/dist/core/adapters/ContractVersionAdapter.js +9 -0
  54. package/dist/core/adapters/ContractVersionAdapter.js.map +1 -0
  55. package/dist/core/adapters/V2_10Adapter.d.ts +24 -0
  56. package/dist/core/adapters/V2_10Adapter.d.ts.map +1 -0
  57. package/dist/core/adapters/V2_10Adapter.js +87 -0
  58. package/dist/core/adapters/V2_10Adapter.js.map +1 -0
  59. package/dist/core/adapters/V2_11Adapter.d.ts +24 -0
  60. package/dist/core/adapters/V2_11Adapter.d.ts.map +1 -0
  61. package/dist/core/adapters/V2_11Adapter.js +87 -0
  62. package/dist/core/adapters/V2_11Adapter.js.map +1 -0
  63. package/dist/core/adapters/V2_50Adapter.d.ts +105 -0
  64. package/dist/core/adapters/V2_50Adapter.d.ts.map +1 -0
  65. package/dist/core/adapters/V2_50Adapter.js +263 -0
  66. package/dist/core/adapters/V2_50Adapter.js.map +1 -0
  67. package/dist/core/contracts.d.ts +169 -0
  68. package/dist/core/contracts.d.ts.map +1 -0
  69. package/dist/core/contracts.js +731 -0
  70. package/dist/core/contracts.js.map +1 -0
  71. package/dist/core/index.d.ts +24 -0
  72. package/dist/core/index.d.ts.map +1 -0
  73. package/dist/core/index.js +82 -0
  74. package/dist/core/index.js.map +1 -0
  75. package/dist/index.d.ts +15 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +40 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/node/WalletManagerNode.d.ts +47 -0
  80. package/dist/node/WalletManagerNode.d.ts.map +1 -0
  81. package/dist/node/WalletManagerNode.js +203 -0
  82. package/dist/node/WalletManagerNode.js.map +1 -0
  83. package/dist/node/index.d.ts +12 -0
  84. package/dist/node/index.d.ts.map +1 -0
  85. package/dist/node/index.js +21 -0
  86. package/dist/node/index.js.map +1 -0
  87. package/dist/ots/ZipkitOTS.d.ts +152 -0
  88. package/dist/ots/ZipkitOTS.d.ts.map +1 -0
  89. package/dist/ots/ZipkitOTS.js +544 -0
  90. package/dist/ots/ZipkitOTS.js.map +1 -0
  91. package/dist/ots/index.d.ts +9 -0
  92. package/dist/ots/index.d.ts.map +1 -0
  93. package/dist/ots/index.js +25 -0
  94. package/dist/ots/index.js.map +1 -0
  95. package/dist/types/index.d.ts +84 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/index.js +37 -0
  98. package/dist/types/index.js.map +1 -0
  99. package/dist/utils/Logger.d.ts +73 -0
  100. package/dist/utils/Logger.d.ts.map +1 -0
  101. package/dist/utils/Logger.js +156 -0
  102. package/dist/utils/Logger.js.map +1 -0
  103. package/dist/utils/crc32.d.ts +6 -0
  104. package/dist/utils/crc32.d.ts.map +1 -0
  105. package/dist/utils/crc32.js +23 -0
  106. package/dist/utils/crc32.js.map +1 -0
  107. package/dist/zipstamp-server/CalendarManager.d.ts +238 -0
  108. package/dist/zipstamp-server/CalendarManager.d.ts.map +1 -0
  109. package/dist/zipstamp-server/CalendarManager.js +364 -0
  110. package/dist/zipstamp-server/CalendarManager.js.map +1 -0
  111. package/dist/zipstamp-server/ZipstampServerAPI.d.ts +427 -0
  112. package/dist/zipstamp-server/ZipstampServerAPI.d.ts.map +1 -0
  113. package/dist/zipstamp-server/ZipstampServerAPI.js +696 -0
  114. package/dist/zipstamp-server/ZipstampServerAPI.js.map +1 -0
  115. package/dist/zipstamp-server/ZipstampServerClient.d.ts +590 -0
  116. package/dist/zipstamp-server/ZipstampServerClient.d.ts.map +1 -0
  117. package/dist/zipstamp-server/ZipstampServerClient.js +433 -0
  118. package/dist/zipstamp-server/ZipstampServerClient.js.map +1 -0
  119. package/dist/zipstamp-server/ZipstampServerHelpers.d.ts +430 -0
  120. package/dist/zipstamp-server/ZipstampServerHelpers.d.ts.map +1 -0
  121. package/dist/zipstamp-server/ZipstampServerHelpers.js +503 -0
  122. package/dist/zipstamp-server/ZipstampServerHelpers.js.map +1 -0
  123. package/dist/zipstamp-server/index.d.ts +24 -0
  124. package/dist/zipstamp-server/index.d.ts.map +1 -0
  125. package/dist/zipstamp-server/index.js +67 -0
  126. package/dist/zipstamp-server/index.js.map +1 -0
  127. package/package.json +117 -0
@@ -0,0 +1,731 @@
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.DEFAULT_CONTRACT_VERSION = exports.CURRENT_DEPLOYMENT = exports.DEFAULT_NETWORK = exports.NZIP_CONTRACT_ABI_WEB3 = exports.UNIFIED_NFT_VERIFY_ABI = exports.TIMESTAMP_PROOF_NFT_ABI = exports.NZIP_TIMESTAMP_REG_ABI = exports.NZIP_CONTRACT_ABI_V250 = exports.NZIP_CONTRACT_ABI = exports.CONTRACT_CONFIGS = exports.TOKENIZED_METADATA_LEGACY = exports.TOKENIZED_METADATA = void 0;
5
+ exports.normalizeNetworkName = normalizeNetworkName;
6
+ exports.getChainIdByName = getChainIdByName;
7
+ exports.getNetworkByName = getNetworkByName;
8
+ exports.getSupportedNetworkNames = getSupportedNetworkNames;
9
+ exports.getContractAdapter = getContractAdapter;
10
+ exports.getContractAdapterByVersion = getContractAdapterByVersion;
11
+ exports.fuzzyMatchNetworkName = fuzzyMatchNetworkName;
12
+ exports.validateTokenId = validateTokenId;
13
+ exports.validateEthereumAddress = validateEthereumAddress;
14
+ exports.sanitizeNetworkName = sanitizeNetworkName;
15
+ exports.validateMerkleRootFormat = validateMerkleRootFormat;
16
+ exports.validateContractAddress = validateContractAddress;
17
+ const metadata_1 = require("../constants/metadata");
18
+ // Re-export token metadata filenames (used by ZipkitVerifier, TokenVerifierBrowser)
19
+ // Standard: TOKEN.NZIP. Legacy NZIP.TOKEN accepted for reading only.
20
+ exports.TOKENIZED_METADATA = metadata_1.TOKEN_NZIP;
21
+ exports.TOKENIZED_METADATA_LEGACY = metadata_1.TOKEN_NZIP_LEGACY;
22
+ // Import ethers for address validation
23
+ const ethers_1 = require("ethers");
24
+ // NZIP NFT Contract configurations by network
25
+ exports.CONTRACT_CONFIGS = {
26
+ // Base Sepolia (Primary testnet)
27
+ 84532: {
28
+ address: '0xc9527869c2526C2A88d4f03202F93149B481e2d3', // Production contract v2.50
29
+ network: 'Base Sepolia',
30
+ chainId: 84532,
31
+ explorerUrl: 'https://sepolia.basescan.org',
32
+ rpcUrls: [
33
+ 'https://sepolia.base.org',
34
+ 'https://base-sepolia-rpc.publicnode.com',
35
+ 'https://base-sepolia.gateway.tenderly.co'
36
+ ],
37
+ version: '2.50',
38
+ registryAddress: '0x3CFc4E3886839dC859f611887660783a3EE241b4', // NZIPTimestampReg v0.90
39
+ registryVersion: '0.90',
40
+ nameAliases: ['base-sepolia', 'base sepolia', 'basesepolia', 'base-sepolia-testnet']
41
+ },
42
+ // Base Mainnet (Production)
43
+ 8453: {
44
+ address: '0xd871Fba59F85108aF29299786DD8243B38dD9686', // Production contract v2.10
45
+ network: 'Base Mainnet',
46
+ chainId: 8453,
47
+ explorerUrl: 'https://basescan.org',
48
+ rpcUrls: [
49
+ 'https://mainnet.base.org',
50
+ 'https://base.drpc.org',
51
+ 'https://base.gateway.tenderly.co'
52
+ ],
53
+ version: '2.10',
54
+ nameAliases: ['base-mainnet', 'base mainnet', 'basemainnet', 'base']
55
+ },
56
+ // Ethereum Sepolia (Testnet)
57
+ 11155111: {
58
+ address: '0x007e8888D976b0b9B6073694Da32B7b6e393f890', // Production contract v2.11
59
+ network: 'Sepolia Testnet',
60
+ chainId: 11155111,
61
+ explorerUrl: 'https://sepolia.etherscan.io',
62
+ rpcUrls: [
63
+ 'https://rpc.sepolia.ethpandaops.io',
64
+ 'https://eth-sepolia.public.blastapi.io',
65
+ 'https://ethereum-sepolia-rpc.publicnode.com',
66
+ 'https://sepolia.drpc.org',
67
+ 'https://1rpc.io/sepolia',
68
+ ],
69
+ version: '2.11',
70
+ nameAliases: ['sepolia-testnet', 'sepolia testnet', 'sepoliatestnet', 'sepolia', 'ethereum-sepolia', 'ethereum sepolia']
71
+ },
72
+ // Arbitrum Sepolia (Testnet)
73
+ 421614: {
74
+ address: '0x3b99a72cCAc108037741cacb0D60d5571CF6412C', // Production contract v2.11
75
+ network: 'Arbitrum Sepolia',
76
+ chainId: 421614,
77
+ explorerUrl: 'https://sepolia.arbiscan.io',
78
+ rpcUrls: [
79
+ 'https://sepolia-rollup.arbitrum.io/rpc',
80
+ 'https://arbitrum-sepolia-rpc.publicnode.com'
81
+ ],
82
+ version: '2.11',
83
+ nameAliases: ['arbitrum-sepolia', 'arbitrum sepolia', 'arbitrumsepolia', 'arbitrum-sepolia-testnet']
84
+ },
85
+ // Arbitrum One (Production)
86
+ 42161: {
87
+ address: '0x2716c4609fD97DaEdF429BC4B4Ec2faa81e2cC60', // Production contract v2.10
88
+ network: 'Arbitrum One',
89
+ chainId: 42161,
90
+ explorerUrl: 'https://arbiscan.io',
91
+ rpcUrls: [
92
+ 'https://arb1.arbitrum.io/rpc',
93
+ 'https://arbitrum.llamarpc.com',
94
+ 'https://arbitrum.publicnode.com'
95
+ ],
96
+ version: '2.10',
97
+ nameAliases: ['arbitrum-one', 'arbitrum one', 'arbitrumone', 'arbitrum', 'arbitrum-mainnet', 'arbitrum mainnet']
98
+ },
99
+ };
100
+ // Contract ABI (ethers.js human-readable format)
101
+ // Minimal ABI that works with v2.10, v2.11, and v2.50 contracts
102
+ exports.NZIP_CONTRACT_ABI = [
103
+ // Minting function (v2.11/v2.50 signature with encryptedHash for new mints)
104
+ "function publicMintZipFile(string memory merkleRootHash, string memory encryptedHash, uint256 creationTimestamp, string memory ipfsHash, string memory metadataURI) public payable returns (uint256)",
105
+ "function totalSupply() external view returns (uint256)",
106
+ "function getTokensByMerkleRoot(string memory merkleRoot) external view returns (uint256[])",
107
+ "function getTokensByOwner(address owner) external view returns (uint256[])",
108
+ "function getZipFileInfo(uint256 tokenId) external view returns (tuple(string merkleRootHash, string encryptedHash, string ipfsHash, address creator, uint256 creationTimestamp, uint256 tokenizationTime, uint256 blockNumber))",
109
+ "function ownerOf(uint256 tokenId) external view returns (address)",
110
+ "function balanceOf(address owner) external view returns (uint256)",
111
+ "function isZipFileTokenized(string memory merkleRootHash, uint256 creationTimestamp) external view returns (bool exists, uint256 tokenId)",
112
+ "function verifyZipFile(uint256 tokenId, string memory providedMerkleRoot) external view returns (bool isValid)",
113
+ "function getVersion() external pure returns (string memory)",
114
+ "event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)",
115
+ "event ZipFileTokenized(uint256 indexed tokenId, address indexed creator, string merkleRootHash, string encryptedHash, uint256 creationTimestamp, string ipfsHash, uint256 tokenizationTime, uint256 blockNumber)"
116
+ ];
117
+ // NZIP NFT v2.50 Contract ABI (full ABI with timestamp proof support)
118
+ exports.NZIP_CONTRACT_ABI_V250 = [
119
+ // v2.11 compatible functions
120
+ "function publicMintZipFile(string memory merkleRootHash, string memory encryptedHash, uint256 creationTimestamp, string memory ipfsHash, string memory metadataURI) public payable returns (uint256)",
121
+ "function publicMintZipFile(string memory merkleRootHash, uint256 creationTimestamp, string memory ipfsHash, string memory metadataURI) public payable returns (uint256)",
122
+ "function getZipFileInfo(uint256 tokenId) external view returns (tuple(string merkleRootHash, string encryptedHash, string ipfsHash, address creator, uint256 creationTimestamp, uint256 tokenizationTime, uint256 blockNumber))",
123
+ "function getEncryptedHash(uint256 tokenId) external view returns (string memory)",
124
+ "function isZipFileTokenized(string memory merkleRootHash, uint256 creationTimestamp) external view returns (bool exists, uint256 tokenId)",
125
+ "function verifyZipFile(uint256 tokenId, string memory providedMerkleRoot) external view returns (bool isValid)",
126
+ "function verifyEncryptedZipFile(uint256 tokenId, string memory providedEncryptedHash) external view returns (bool isValid)",
127
+ "function getBlockchainMetadata(uint256 tokenId) public view returns (uint256 blockNumber, uint256 tokenizationTime)",
128
+ "function generateCompositeKey(string memory merkleRootHash, uint256 creationTimestamp) public pure returns (bytes32)",
129
+ "function totalSupply() public view returns (uint256)",
130
+ "function getVersion() external pure returns (string memory)",
131
+ "function ownerOf(uint256 tokenId) external view returns (address)",
132
+ "function balanceOf(address owner) external view returns (uint256)",
133
+ // v2.50 timestamp proof functions
134
+ "function mintWithTimestampProof(string memory merkleRootHash, bytes32[] calldata proof, bytes32 batchMerkleRoot) external payable returns (uint256)",
135
+ "function hasTimestampProof(uint256 tokenId) external view returns (bool)",
136
+ "function getTimestampProof(uint256 tokenId) external view returns (tuple(bool hasTimestampProof, bytes32 batchMerkleRoot, uint256 batchTimestamp, uint256 batchBlockNumber) data, bytes32[] memory merkleProof)",
137
+ "function getTokenData(uint256 tokenId) external view returns (bytes32 merkleRoot, uint256 mintedAt, uint256 mintBlockNumber, address originalOwner, bool hasProof, bytes32 batchMerkleRoot, uint256 batchTimestamp, uint256 batchBlockNumber)",
138
+ "function verifyToken(uint256 tokenId) external view returns (bool isValid)",
139
+ "function getRegistry() external view returns (address)",
140
+ // v2.50 admin functions
141
+ "function mintFee() public view returns (uint256)",
142
+ "function mintFeeRequired() public view returns (bool)",
143
+ "function setMintFee(uint256 newFee) external",
144
+ "function setMintFeeRequired(bool required) external",
145
+ "function withdrawFees(address payable to) external",
146
+ "function authorizeMinter(address minter) external",
147
+ "function deauthorizeMinter(address minter) external",
148
+ "function isAuthorizedMinter(address minter) external view returns (bool)",
149
+ // Events
150
+ "event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)",
151
+ "event ZipFileTokenized(uint256 indexed tokenId, address indexed creator, string merkleRootHash, string encryptedHash, uint256 creationTimestamp, string ipfsHash, uint256 tokenizationTime, uint256 blockNumber)",
152
+ "event TimestampProofMinted(uint256 indexed tokenId, address indexed creator, bytes32 indexed batchMerkleRoot, string merkleRootHash, uint256 batchTimestamp, uint256 tokenizationTime, uint256 blockNumber)",
153
+ "event FeeUpdated(uint256 oldFee, uint256 newFee)",
154
+ "event MinterAuthorized(address indexed minter, address indexed authorizedBy)",
155
+ "event MinterDeauthorized(address indexed minter, address indexed deauthorizedBy)"
156
+ ];
157
+ // NZIPTimestampReg Contract ABI (for batch timestamp verification)
158
+ exports.NZIP_TIMESTAMP_REG_ABI = [
159
+ 'function verifyProof(bytes32 digest, bytes32[] calldata proof, bytes32 merkleRoot) external view returns (bool isValid, uint256 batchNumber, uint256 timestamp, uint256 blockNumber)',
160
+ 'function getBatch(bytes32 merkleRoot) external view returns (bool exists, uint256 batchNumber, uint256 timestamp, uint256 blockNumber, uint256 hashCount)',
161
+ 'function getBatchByNumber(uint256 batchNumber) external view returns (bool exists, bytes32 merkleRoot, uint256 timestamp, uint256 blockNumber, uint256 hashCount)',
162
+ 'function batchExists(bytes32 merkleRoot) external view returns (bool)',
163
+ 'function totalBatches() public view returns (uint256)',
164
+ 'function totalDigests() public view returns (uint256)',
165
+ 'function getStats() external view returns (uint256 _totalBatches, uint256 _totalDigests)',
166
+ 'function getVersion() external pure returns (string memory)',
167
+ 'function submitBatch(bytes32 merkleRoot, uint64 hashCount) external',
168
+ 'function addAuthorizedSubmitter(address submitter) external',
169
+ 'function removeAuthorizedSubmitter(address submitter) external',
170
+ 'function isAuthorizedSubmitter(address submitter) external view returns (bool)',
171
+ 'event BatchSubmitted(bytes32 indexed merkleRoot, uint256 indexed batchNumber, address indexed submitter, uint256 timestamp, uint256 blockNumber, uint256 hashCount)',
172
+ 'event SubmitterAdded(address indexed submitter, address indexed addedBy)',
173
+ 'event SubmitterRemoved(address indexed submitter, address indexed removedBy)',
174
+ ];
175
+ // TimestampProofNFT ABI (minimal - for verification of v0.90-style timestamp proof NFT)
176
+ // Used by verify-zip when contract exposes getProof(uint256) with legacy tuple shape.
177
+ exports.TIMESTAMP_PROOF_NFT_ABI = [
178
+ 'function ownerOf(uint256 tokenId) view returns (address)',
179
+ 'function getProof(uint256 tokenId) view returns (tuple(bytes32 digest, bytes32 merkleRoot, uint256 batchTimestamp, uint256 batchBlockNumber, uint256 mintedAt, address originalOwner), bytes32[])',
180
+ 'function getTokenByDigest(bytes32 digest) view returns (uint256)',
181
+ 'function isDigestMinted(bytes32 digest) view returns (bool)',
182
+ 'function verifyToken(uint256 tokenId) view returns (bool)',
183
+ 'function getVersion() pure returns (string)',
184
+ 'function registry() view returns (address)',
185
+ ];
186
+ // UnifiedNFT verification ABI (minimal - for verify-zip and token-create; v2.50 getTokenData/getTimestampProof)
187
+ // Subset of NZIP_CONTRACT_ABI_V250 used when only reading token/proof data.
188
+ exports.UNIFIED_NFT_VERIFY_ABI = [
189
+ 'function ownerOf(uint256 tokenId) view returns (address)',
190
+ 'function getTokenData(uint256 tokenId) view returns (tuple(bytes32 merkleRoot, uint256 mintedAt, uint256 mintBlockNumber, address originalOwner, bool hasTimestampProof, bytes32 batchMerkleRoot, uint256 batchTimestamp, uint256 batchBlockNumber))',
191
+ 'function getTimestampProof(uint256 tokenId) view returns (bytes32 digest, bytes32[] proof, bytes32 batchMerkleRoot, uint256 batchTimestamp, uint256 batchBlockNumber)',
192
+ 'function getTokenByMerkleRoot(bytes32 merkleRoot) view returns (uint256)',
193
+ 'function isMinted(bytes32 merkleRoot) view returns (bool)',
194
+ 'function hasTimestampProof(uint256 tokenId) view returns (bool)',
195
+ 'function verifyToken(uint256 tokenId) view returns (bool)',
196
+ 'function getVersion() pure returns (string)',
197
+ 'function getRegistry() view returns (address)',
198
+ ];
199
+ // Contract ABI (Web3.js JSON format)
200
+ exports.NZIP_CONTRACT_ABI_WEB3 = [
201
+ {
202
+ inputs: [
203
+ { name: "merkleRootHash", type: "string" },
204
+ { name: "encryptedHash", type: "string" },
205
+ { name: "creationTimestamp", type: "uint256" },
206
+ { name: "ipfsHash", type: "string" },
207
+ { name: "metadataURI", type: "string" }
208
+ ],
209
+ name: "publicMintZipFile",
210
+ outputs: [{ name: "", type: "uint256" }],
211
+ stateMutability: "nonpayable",
212
+ type: "function"
213
+ },
214
+ {
215
+ inputs: [],
216
+ name: "totalSupply",
217
+ outputs: [{ name: "", type: "uint256" }],
218
+ stateMutability: "view",
219
+ type: "function"
220
+ },
221
+ {
222
+ inputs: [{ name: "merkleRoot", type: "string" }],
223
+ name: "getTokensByMerkleRoot",
224
+ outputs: [{ name: "", type: "uint256[]" }],
225
+ stateMutability: "view",
226
+ type: "function"
227
+ },
228
+ {
229
+ inputs: [{ name: "tokenId", type: "uint256" }],
230
+ name: "getZipFileInfo",
231
+ outputs: [
232
+ {
233
+ components: [
234
+ { name: "merkleRootHash", type: "string" },
235
+ { name: "encryptedHash", type: "string" },
236
+ { name: "ipfsHash", type: "string" },
237
+ { name: "creator", type: "address" },
238
+ { name: "creationTimestamp", type: "uint256" },
239
+ { name: "tokenizationTime", type: "uint256" },
240
+ { name: "blockNumber", type: "uint256" }
241
+ ],
242
+ name: "",
243
+ type: "tuple"
244
+ }
245
+ ],
246
+ stateMutability: "view",
247
+ type: "function"
248
+ },
249
+ {
250
+ inputs: [{ name: "tokenId", type: "uint256" }],
251
+ name: "ownerOf",
252
+ outputs: [{ name: "", type: "address" }],
253
+ stateMutability: "view",
254
+ type: "function"
255
+ },
256
+ {
257
+ inputs: [{ name: "owner", type: "address" }],
258
+ name: "balanceOf",
259
+ outputs: [{ name: "", type: "uint256" }],
260
+ stateMutability: "view",
261
+ type: "function"
262
+ },
263
+ {
264
+ inputs: [
265
+ { name: "merkleRootHash", type: "string" },
266
+ { name: "creationTimestamp", type: "uint256" }
267
+ ],
268
+ name: "isZipFileTokenized",
269
+ outputs: [
270
+ { name: "exists", type: "bool" },
271
+ { name: "tokenId", type: "uint256" }
272
+ ],
273
+ stateMutability: "view",
274
+ type: "function"
275
+ },
276
+ {
277
+ inputs: [
278
+ { name: "tokenId", type: "uint256" },
279
+ { name: "providedMerkleRoot", type: "string" }
280
+ ],
281
+ name: "verifyZipFile",
282
+ outputs: [{ name: "isValid", type: "bool" }],
283
+ stateMutability: "view",
284
+ type: "function"
285
+ },
286
+ {
287
+ inputs: [
288
+ { name: "tokenId", type: "uint256" },
289
+ { name: "providedEncryptedHash", type: "string" }
290
+ ],
291
+ name: "verifyEncryptedZipFile",
292
+ outputs: [{ name: "isValid", type: "bool" }],
293
+ stateMutability: "view",
294
+ type: "function"
295
+ },
296
+ {
297
+ inputs: [],
298
+ name: "getVersion",
299
+ outputs: [{ name: "", type: "string" }],
300
+ stateMutability: "pure",
301
+ type: "function"
302
+ },
303
+ {
304
+ anonymous: false,
305
+ inputs: [
306
+ { indexed: true, name: "from", type: "address" },
307
+ { indexed: true, name: "to", type: "address" },
308
+ { indexed: true, name: "tokenId", type: "uint256" }
309
+ ],
310
+ name: "Transfer",
311
+ type: "event"
312
+ },
313
+ {
314
+ anonymous: false,
315
+ inputs: [
316
+ { indexed: true, name: "tokenId", type: "uint256" },
317
+ { indexed: true, name: "creator", type: "address" },
318
+ { indexed: false, name: "merkleRootHash", type: "string" },
319
+ { indexed: false, name: "encryptedHash", type: "string" },
320
+ { indexed: false, name: "creationTimestamp", type: "uint256" },
321
+ { indexed: false, name: "ipfsHash", type: "string" },
322
+ { indexed: false, name: "tokenizationTime", type: "uint256" },
323
+ { indexed: false, name: "blockNumber", type: "uint256" }
324
+ ],
325
+ name: "ZipFileTokenized",
326
+ type: "event"
327
+ }
328
+ ];
329
+ // Default configuration (Base Sepolia for development; v2.50 contract)
330
+ exports.DEFAULT_NETWORK = 84532;
331
+ exports.CURRENT_DEPLOYMENT = exports.CONTRACT_CONFIGS[exports.DEFAULT_NETWORK];
332
+ /** Default contract version used when version is unspecified (e.g. legacy metadata). Prefer v2.50. */
333
+ exports.DEFAULT_CONTRACT_VERSION = '2.50';
334
+ // Helper functions
335
+ const getContractConfig = (chainId) => {
336
+ return exports.CONTRACT_CONFIGS[chainId] || exports.CURRENT_DEPLOYMENT;
337
+ };
338
+ exports.getContractConfig = getContractConfig;
339
+ const getSupportedNetworks = () => {
340
+ return Object.keys(exports.CONTRACT_CONFIGS).map(Number);
341
+ };
342
+ exports.getSupportedNetworks = getSupportedNetworks;
343
+ const isNetworkSupported = (chainId) => {
344
+ return chainId in exports.CONTRACT_CONFIGS;
345
+ };
346
+ exports.isNetworkSupported = isNetworkSupported;
347
+ /**
348
+ * Normalize network name for matching (lowercase, trim, replace spaces with hyphens)
349
+ */
350
+ function normalizeNetworkName(networkName) {
351
+ return networkName.toLowerCase().trim().replace(/\s+/g, '-').replace(/_/g, '-');
352
+ }
353
+ /**
354
+ * Get chain ID by network name (supports aliases)
355
+ * Returns chain ID if found, null otherwise
356
+ */
357
+ function getChainIdByName(networkName) {
358
+ const normalized = normalizeNetworkName(networkName);
359
+ // Search through all configs
360
+ for (const [chainIdStr, config] of Object.entries(exports.CONTRACT_CONFIGS)) {
361
+ const chainId = Number(chainIdStr);
362
+ // Check primary network name
363
+ if (normalizeNetworkName(config.network) === normalized) {
364
+ return chainId;
365
+ }
366
+ // Check name aliases
367
+ if (config.nameAliases) {
368
+ for (const alias of config.nameAliases) {
369
+ if (normalizeNetworkName(alias) === normalized) {
370
+ return chainId;
371
+ }
372
+ }
373
+ }
374
+ }
375
+ return null;
376
+ }
377
+ /**
378
+ * Get network configuration by network name (supports aliases)
379
+ * Returns ContractConfig if found, null otherwise
380
+ */
381
+ function getNetworkByName(networkName) {
382
+ const chainId = getChainIdByName(networkName);
383
+ if (chainId === null) {
384
+ return null;
385
+ }
386
+ return (0, exports.getContractConfig)(chainId);
387
+ }
388
+ /**
389
+ * Get all supported network name aliases
390
+ * Returns array of all supported network names (primary + aliases)
391
+ */
392
+ function getSupportedNetworkNames() {
393
+ const names = [];
394
+ for (const config of Object.values(exports.CONTRACT_CONFIGS)) {
395
+ // Add primary network name
396
+ names.push(config.network);
397
+ // Add aliases
398
+ if (config.nameAliases) {
399
+ names.push(...config.nameAliases);
400
+ }
401
+ }
402
+ return names;
403
+ }
404
+ /**
405
+ * Get contract adapter for a given chain ID
406
+ * Uses the version from CONTRACT_CONFIGS to select the appropriate adapter
407
+ * @param chainId Chain ID
408
+ * @returns ContractVersionAdapter instance
409
+ * @throws Error if chainId not found or version not supported
410
+ */
411
+ function getContractAdapter(chainId) {
412
+ const config = (0, exports.getContractConfig)(chainId);
413
+ if (!config) {
414
+ throw new Error(`No contract config found for chainId: ${chainId}`);
415
+ }
416
+ if (!config.version) {
417
+ throw new Error(`Contract version not specified for chainId: ${chainId}`);
418
+ }
419
+ // Import here to avoid circular dependency
420
+ const { getAdapter } = require('./adapters/AdapterFactory');
421
+ return getAdapter(config.version);
422
+ }
423
+ /**
424
+ * Get contract adapter by version string
425
+ * @param version Contract version (e.g., "2.11", "2.10")
426
+ * @returns ContractVersionAdapter instance
427
+ * @throws Error if version not supported
428
+ */
429
+ function getContractAdapterByVersion(version) {
430
+ // Import here to avoid circular dependency
431
+ const { getAdapter } = require('./adapters/AdapterFactory');
432
+ return getAdapter(version);
433
+ }
434
+ /**
435
+ * Fuzzy match network name (for backward compatibility)
436
+ * Handles partial matches like "sepolia" matching "Base Sepolia" or "Arbitrum Sepolia"
437
+ * Returns best match or null
438
+ */
439
+ function fuzzyMatchNetworkName(networkName) {
440
+ const normalized = normalizeNetworkName(networkName);
441
+ // First try exact match
442
+ const exactMatch = getNetworkByName(networkName);
443
+ if (exactMatch) {
444
+ return exactMatch;
445
+ }
446
+ // Try partial matching
447
+ const matches = [];
448
+ for (const config of Object.values(exports.CONTRACT_CONFIGS)) {
449
+ const configNormalized = normalizeNetworkName(config.network);
450
+ let score = 0;
451
+ // Check if normalized input is contained in config name or vice versa
452
+ if (configNormalized.includes(normalized) || normalized.includes(configNormalized)) {
453
+ score = Math.max(configNormalized.length, normalized.length) / Math.min(configNormalized.length, normalized.length);
454
+ matches.push({ config, score });
455
+ }
456
+ // Check aliases
457
+ if (config.nameAliases) {
458
+ for (const alias of config.nameAliases) {
459
+ const aliasNormalized = normalizeNetworkName(alias);
460
+ if (aliasNormalized.includes(normalized) || normalized.includes(aliasNormalized)) {
461
+ score = Math.max(aliasNormalized.length, normalized.length) / Math.min(aliasNormalized.length, normalized.length);
462
+ matches.push({ config, score });
463
+ }
464
+ }
465
+ }
466
+ }
467
+ // Return best match (highest score)
468
+ if (matches.length > 0) {
469
+ matches.sort((a, b) => b.score - a.score);
470
+ return matches[0].config;
471
+ }
472
+ return null;
473
+ }
474
+ /**
475
+ * Validate that a token ID is a valid uint256 format
476
+ * Token IDs must be numeric strings that can be converted to BigInt and be within uint256 bounds
477
+ *
478
+ * @param tokenId Token ID string to validate
479
+ * @returns Validation result with success status and error message if failed
480
+ */
481
+ function validateTokenId(tokenId) {
482
+ if (!tokenId || typeof tokenId !== 'string') {
483
+ return {
484
+ success: false,
485
+ error: 'Token ID must be a non-empty string'
486
+ };
487
+ }
488
+ // Trim whitespace
489
+ const trimmed = tokenId.trim();
490
+ if (trimmed.length === 0) {
491
+ return {
492
+ success: false,
493
+ error: 'Token ID cannot be empty or whitespace only'
494
+ };
495
+ }
496
+ // Check if it's a valid numeric string (allows decimal, hex with 0x prefix, or plain numeric)
497
+ // Remove 0x prefix if present for validation
498
+ const normalized = trimmed.startsWith('0x') ? trimmed.slice(2) : trimmed;
499
+ // Must contain only hexadecimal digits (0-9, a-f, A-F)
500
+ if (!/^[0-9a-fA-F]+$/.test(normalized)) {
501
+ return {
502
+ success: false,
503
+ error: `Token ID must be a valid numeric string (hexadecimal). Got: ${tokenId}`
504
+ };
505
+ }
506
+ // Check if it can be converted to BigInt (uint256)
507
+ try {
508
+ const bigIntValue = BigInt(trimmed.startsWith('0x') ? trimmed : `0x${normalized}`);
509
+ // uint256 max value: 2^256 - 1
510
+ const maxUint256 = BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
511
+ if (bigIntValue < 0n || bigIntValue > maxUint256) {
512
+ return {
513
+ success: false,
514
+ error: `Token ID out of uint256 bounds (0 to 2^256-1). Got: ${tokenId}`
515
+ };
516
+ }
517
+ }
518
+ catch (error) {
519
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
520
+ return {
521
+ success: false,
522
+ error: `Token ID validation failed: ${errorMessage}. Token ID: ${tokenId}`
523
+ };
524
+ }
525
+ return { success: true };
526
+ }
527
+ /**
528
+ * Validate that an Ethereum address is in the correct format
529
+ * Uses ethers.js validation to ensure proper format and checksum
530
+ *
531
+ * @param address Ethereum address to validate
532
+ * @returns Validation result with success status and error message if failed
533
+ */
534
+ function validateEthereumAddress(address) {
535
+ if (!address || typeof address !== 'string') {
536
+ return {
537
+ success: false,
538
+ error: 'Address must be a non-empty string'
539
+ };
540
+ }
541
+ // Trim whitespace
542
+ const trimmed = address.trim();
543
+ if (trimmed.length === 0) {
544
+ return {
545
+ success: false,
546
+ error: 'Address cannot be empty or whitespace only'
547
+ };
548
+ }
549
+ // Validate address format using ethers.js
550
+ if (!ethers_1.ethers.isAddress(trimmed)) {
551
+ return {
552
+ success: false,
553
+ error: `Invalid Ethereum address format: ${trimmed}`
554
+ };
555
+ }
556
+ // Normalize to checksum format
557
+ try {
558
+ const normalized = ethers_1.ethers.getAddress(trimmed);
559
+ return {
560
+ success: true,
561
+ normalizedAddress: normalized
562
+ };
563
+ }
564
+ catch (error) {
565
+ const errorMessage = error instanceof Error ? error.message : 'Unknown address normalization error';
566
+ return {
567
+ success: false,
568
+ error: `Address normalization failed: ${errorMessage}`
569
+ };
570
+ }
571
+ }
572
+ /**
573
+ * Sanitize and validate network name
574
+ * Removes leading/trailing whitespace, validates length, and removes potentially dangerous characters
575
+ *
576
+ * @param networkName Network name to sanitize
577
+ * @returns Validation result with success status, sanitized name, and error message if failed
578
+ */
579
+ function sanitizeNetworkName(networkName) {
580
+ if (!networkName || typeof networkName !== 'string') {
581
+ return {
582
+ success: false,
583
+ error: 'Network name must be a non-empty string'
584
+ };
585
+ }
586
+ // Trim whitespace
587
+ const trimmed = networkName.trim();
588
+ if (trimmed.length === 0) {
589
+ return {
590
+ success: false,
591
+ error: 'Network name cannot be empty or whitespace only'
592
+ };
593
+ }
594
+ // Validate length (reasonable limit to prevent DoS)
595
+ const MAX_NETWORK_NAME_LENGTH = 100;
596
+ if (trimmed.length > MAX_NETWORK_NAME_LENGTH) {
597
+ return {
598
+ success: false,
599
+ error: `Network name too long (max ${MAX_NETWORK_NAME_LENGTH} characters). Got: ${trimmed.length}`
600
+ };
601
+ }
602
+ // Remove control characters and validate basic character set
603
+ // Allow alphanumeric, spaces, hyphens, underscores, and common punctuation
604
+ const sanitized = trimmed.replace(/[\x00-\x1F\x7F-\x9F]/g, ''); // Remove control characters
605
+ // Check for potentially dangerous patterns (script tags, etc.)
606
+ const dangerousPatterns = [
607
+ /<script/i,
608
+ /javascript:/i,
609
+ /on\w+\s*=/i, // Event handlers like onclick=
610
+ /data:text\/html/i
611
+ ];
612
+ for (const pattern of dangerousPatterns) {
613
+ if (pattern.test(sanitized)) {
614
+ return {
615
+ success: false,
616
+ error: `Network name contains potentially dangerous content: ${sanitized}`
617
+ };
618
+ }
619
+ }
620
+ return {
621
+ success: true,
622
+ sanitized
623
+ };
624
+ }
625
+ /**
626
+ * Validate that a merkle root is in the correct format
627
+ * Merkle roots should be valid hexadecimal strings of 64 characters (SHA-256 hash)
628
+ *
629
+ * @param merkleRoot Merkle root string to validate
630
+ * @returns Validation result with success status and error message if failed
631
+ */
632
+ function validateMerkleRootFormat(merkleRoot) {
633
+ if (!merkleRoot || typeof merkleRoot !== 'string') {
634
+ return {
635
+ success: false,
636
+ error: 'Merkle root must be a non-empty string'
637
+ };
638
+ }
639
+ // Trim whitespace
640
+ const trimmed = merkleRoot.trim();
641
+ if (trimmed.length === 0) {
642
+ return {
643
+ success: false,
644
+ error: 'Merkle root cannot be empty or whitespace only'
645
+ };
646
+ }
647
+ // Remove 0x prefix if present for validation
648
+ const normalized = trimmed.startsWith('0x') ? trimmed.slice(2) : trimmed;
649
+ // Must be exactly 64 hexadecimal characters (SHA-256 hash)
650
+ if (normalized.length !== 64) {
651
+ return {
652
+ success: false,
653
+ error: `Merkle root must be exactly 64 hexadecimal characters (SHA-256). Got: ${normalized.length} characters`
654
+ };
655
+ }
656
+ // Must contain only hexadecimal digits (0-9, a-f, A-F)
657
+ if (!/^[0-9a-fA-F]{64}$/.test(normalized)) {
658
+ return {
659
+ success: false,
660
+ error: `Merkle root must be a valid hexadecimal string. Got: ${trimmed}`
661
+ };
662
+ }
663
+ // Return normalized version (with 0x prefix for consistency)
664
+ return {
665
+ success: true,
666
+ normalized: `0x${normalized.toLowerCase()}`
667
+ };
668
+ }
669
+ /**
670
+ * Validate that a contract address matches the expected contract address for a network
671
+ * This prevents attackers from creating fake metadata pointing to malicious contracts
672
+ *
673
+ * @param contractAddress Contract address to validate
674
+ * @param networkChainId Chain ID of the network
675
+ * @param debug Optional debug flag for logging
676
+ * @returns Validation result with success status and error message if failed
677
+ */
678
+ function validateContractAddress(contractAddress, networkChainId, debug = false) {
679
+ if (debug) {
680
+ console.log(`[DEBUG] Validating contract address: ${contractAddress} for chainId: ${networkChainId}`);
681
+ }
682
+ // Get expected contract address for this network
683
+ const networkConfig = (0, exports.getContractConfig)(networkChainId);
684
+ if (!networkConfig) {
685
+ return {
686
+ success: false,
687
+ error: `Network configuration not found for chainId: ${networkChainId}`
688
+ };
689
+ }
690
+ const expectedAddress = networkConfig.address;
691
+ // Normalize addresses for comparison (Ethereum addresses are case-insensitive)
692
+ // Use ethers.js getAddress() to normalize both addresses to checksum format
693
+ let normalizedProvided;
694
+ let normalizedExpected;
695
+ try {
696
+ // Validate and normalize the provided address
697
+ if (!ethers_1.ethers.isAddress(contractAddress)) {
698
+ return {
699
+ success: false,
700
+ error: `Invalid contract address format: ${contractAddress}`
701
+ };
702
+ }
703
+ normalizedProvided = ethers_1.ethers.getAddress(contractAddress);
704
+ // Normalize the expected address
705
+ normalizedExpected = ethers_1.ethers.getAddress(expectedAddress);
706
+ }
707
+ catch (error) {
708
+ const errorMessage = error instanceof Error ? error.message : 'Unknown address validation error';
709
+ return {
710
+ success: false,
711
+ error: `Address validation failed: ${errorMessage}`
712
+ };
713
+ }
714
+ // Compare normalized addresses
715
+ if (normalizedProvided.toLowerCase() !== normalizedExpected.toLowerCase()) {
716
+ if (debug) {
717
+ console.log(`[DEBUG] Contract address mismatch:`);
718
+ console.log(`[DEBUG] Provided: ${normalizedProvided}`);
719
+ console.log(`[DEBUG] Expected: ${normalizedExpected}`);
720
+ }
721
+ return {
722
+ success: false,
723
+ error: `Contract address mismatch: provided address ${normalizedProvided} does not match expected address ${normalizedExpected} for network (chainId: ${networkChainId})`
724
+ };
725
+ }
726
+ if (debug) {
727
+ console.log(`[DEBUG] Contract address validation passed: ${normalizedProvided} matches expected address for network`);
728
+ }
729
+ return { success: true };
730
+ }
731
+ //# sourceMappingURL=contracts.js.map