@mapprotocol/common-contracts 0.1.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 (28) hide show
  1. package/README.md +114 -58
  2. package/artifacts/contracts/AuthorityManager.sol/AuthorityManager.json +2 -2
  3. package/artifacts/contracts/factory/Create2Factory.sol/Create2Factory.json +107 -0
  4. package/contracts/factory/Create2Factory.sol +57 -0
  5. package/package.json +15 -3
  6. package/typechain-types/contracts/factory/Create2Factory.ts +174 -0
  7. package/typechain-types/contracts/factory/index.ts +4 -0
  8. package/typechain-types/contracts/index.ts +2 -0
  9. package/typechain-types/factories/@openzeppelin/contracts/access/manager/AccessManager__factory.ts +1 -1
  10. package/typechain-types/factories/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils__factory.ts +1 -1
  11. package/typechain-types/factories/@openzeppelin/contracts/utils/Address__factory.ts +1 -1
  12. package/typechain-types/factories/@openzeppelin/contracts/utils/Errors__factory.ts +1 -1
  13. package/typechain-types/factories/@openzeppelin/contracts/utils/math/SafeCast__factory.ts +1 -1
  14. package/typechain-types/factories/contracts/AuthorityManager__factory.ts +1 -1
  15. package/typechain-types/factories/contracts/factory/Create2Factory__factory.ts +163 -0
  16. package/typechain-types/factories/contracts/factory/index.ts +4 -0
  17. package/typechain-types/factories/contracts/index.ts +1 -0
  18. package/typechain-types/hardhat.d.ts +18 -0
  19. package/typechain-types/index.ts +2 -0
  20. package/utils/addressCodec.ts +57 -0
  21. package/utils/codeHash.ts +75 -0
  22. package/utils/deployRecord.ts +117 -0
  23. package/utils/deployer.ts +123 -0
  24. package/utils/evmHelper.ts +108 -0
  25. package/utils/factory.ts +210 -0
  26. package/utils/index.ts +42 -0
  27. package/utils/tronHelper.ts +362 -0
  28. package/utils/verifier.ts +225 -0
@@ -0,0 +1,163 @@
1
+ /* Autogenerated file. Do not edit manually. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ import {
5
+ Contract,
6
+ ContractFactory,
7
+ ContractTransactionResponse,
8
+ Interface,
9
+ } from "ethers";
10
+ import type { Signer, ContractDeployTransaction, ContractRunner } from "ethers";
11
+ import type { NonPayableOverrides } from "../../../common";
12
+ import type {
13
+ Create2Factory,
14
+ Create2FactoryInterface,
15
+ } from "../../../contracts/factory/Create2Factory";
16
+
17
+ const _abi = [
18
+ {
19
+ anonymous: false,
20
+ inputs: [
21
+ {
22
+ indexed: true,
23
+ internalType: "address",
24
+ name: "addr",
25
+ type: "address",
26
+ },
27
+ {
28
+ indexed: true,
29
+ internalType: "bytes32",
30
+ name: "salt",
31
+ type: "bytes32",
32
+ },
33
+ ],
34
+ name: "Deployed",
35
+ type: "event",
36
+ },
37
+ {
38
+ inputs: [
39
+ {
40
+ internalType: "bytes32",
41
+ name: "salt",
42
+ type: "bytes32",
43
+ },
44
+ {
45
+ internalType: "bytes",
46
+ name: "creationCode",
47
+ type: "bytes",
48
+ },
49
+ {
50
+ internalType: "uint256",
51
+ name: "value",
52
+ type: "uint256",
53
+ },
54
+ ],
55
+ name: "deploy",
56
+ outputs: [
57
+ {
58
+ internalType: "address",
59
+ name: "addr",
60
+ type: "address",
61
+ },
62
+ ],
63
+ stateMutability: "nonpayable",
64
+ type: "function",
65
+ },
66
+ {
67
+ inputs: [
68
+ {
69
+ internalType: "bytes32",
70
+ name: "salt",
71
+ type: "bytes32",
72
+ },
73
+ {
74
+ internalType: "bytes32",
75
+ name: "codeHash",
76
+ type: "bytes32",
77
+ },
78
+ ],
79
+ name: "getAddress",
80
+ outputs: [
81
+ {
82
+ internalType: "address",
83
+ name: "",
84
+ type: "address",
85
+ },
86
+ ],
87
+ stateMutability: "view",
88
+ type: "function",
89
+ },
90
+ {
91
+ inputs: [
92
+ {
93
+ internalType: "bytes32",
94
+ name: "salt",
95
+ type: "bytes32",
96
+ },
97
+ {
98
+ internalType: "bytes32",
99
+ name: "codeHash",
100
+ type: "bytes32",
101
+ },
102
+ ],
103
+ name: "getAddressTron",
104
+ outputs: [
105
+ {
106
+ internalType: "address",
107
+ name: "",
108
+ type: "address",
109
+ },
110
+ ],
111
+ stateMutability: "view",
112
+ type: "function",
113
+ },
114
+ ] as const;
115
+
116
+ const _bytecode =
117
+ "0x6080604052348015600f57600080fd5b506102f98061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063933559b014610046578063c7aeef0f14610075578063d3a3968614610088575b600080fd5b61005961005436600461018e565b61009b565b6040516001600160a01b03909116815260200160405180910390f35b6100596100833660046101c6565b6100d8565b61005961009636600461018e565b61016c565b6040516000906100b990604160f81b9030908690869060200161028a565b60408051601f1981840301815291905280516020909101209392505050565b60008383516020850184f590506001600160a01b03811661012f5760405162461bcd60e51b815260206004820152600d60248201526c1111541313d657d19052531151609a1b604482015260640160405180910390fd5b60405184906001600160a01b038316907f94bfd9af14ef450884c8a7ddb5734e2e1e14e70a1c84f0801cc5a29e34d2642890600090a39392505050565b6040516000906100b9906001600160f81b03199030908690869060200161028a565b600080604083850312156101a157600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156101db57600080fd5b83359250602084013567ffffffffffffffff808211156101fa57600080fd5b818601915086601f83011261020e57600080fd5b813581811115610220576102206101b0565b604051601f8201601f19908116603f01168101908382118183101715610248576102486101b0565b8160405282815289602084870101111561026157600080fd5b826020860160208301376000602084830101528096505050505050604084013590509250925092565b6001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff19166001840152601583015260358201526055019056fea26469706673582212205fb7d781d8404b93aed56d95e5543997fe78a250c5faf35b40c771504b4c853b64736f6c63430008190033";
118
+
119
+ type Create2FactoryConstructorParams =
120
+ | [signer?: Signer]
121
+ | ConstructorParameters<typeof ContractFactory>;
122
+
123
+ const isSuperArgs = (
124
+ xs: Create2FactoryConstructorParams
125
+ ): xs is ConstructorParameters<typeof ContractFactory> => xs.length > 1;
126
+
127
+ export class Create2Factory__factory extends ContractFactory {
128
+ constructor(...args: Create2FactoryConstructorParams) {
129
+ if (isSuperArgs(args)) {
130
+ super(...args);
131
+ } else {
132
+ super(_abi, _bytecode, args[0]);
133
+ }
134
+ }
135
+
136
+ override getDeployTransaction(
137
+ overrides?: NonPayableOverrides & { from?: string }
138
+ ): Promise<ContractDeployTransaction> {
139
+ return super.getDeployTransaction(overrides || {});
140
+ }
141
+ override deploy(overrides?: NonPayableOverrides & { from?: string }) {
142
+ return super.deploy(overrides || {}) as Promise<
143
+ Create2Factory & {
144
+ deploymentTransaction(): ContractTransactionResponse;
145
+ }
146
+ >;
147
+ }
148
+ override connect(runner: ContractRunner | null): Create2Factory__factory {
149
+ return super.connect(runner) as Create2Factory__factory;
150
+ }
151
+
152
+ static readonly bytecode = _bytecode;
153
+ static readonly abi = _abi;
154
+ static createInterface(): Create2FactoryInterface {
155
+ return new Interface(_abi) as Create2FactoryInterface;
156
+ }
157
+ static connect(
158
+ address: string,
159
+ runner?: ContractRunner | null
160
+ ): Create2Factory {
161
+ return new Contract(address, _abi, runner) as unknown as Create2Factory;
162
+ }
163
+ }
@@ -0,0 +1,4 @@
1
+ /* Autogenerated file. Do not edit manually. */
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ export { Create2Factory__factory } from "./Create2Factory__factory";
@@ -2,4 +2,5 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
  export * as base from "./base";
5
+ export * as factory from "./factory";
5
6
  export { AuthorityManager__factory } from "./AuthorityManager__factory";
@@ -89,6 +89,10 @@ declare module "hardhat/types/runtime" {
89
89
  name: "BaseImplementation",
90
90
  signerOrOptions?: ethers.Signer | FactoryOptions
91
91
  ): Promise<Contracts.BaseImplementation__factory>;
92
+ getContractFactory(
93
+ name: "Create2Factory",
94
+ signerOrOptions?: ethers.Signer | FactoryOptions
95
+ ): Promise<Contracts.Create2Factory__factory>;
92
96
 
93
97
  getContractAt(
94
98
  name: "AccessManagedUpgradeable",
@@ -185,6 +189,11 @@ declare module "hardhat/types/runtime" {
185
189
  address: string | ethers.Addressable,
186
190
  signer?: ethers.Signer
187
191
  ): Promise<Contracts.BaseImplementation>;
192
+ getContractAt(
193
+ name: "Create2Factory",
194
+ address: string | ethers.Addressable,
195
+ signer?: ethers.Signer
196
+ ): Promise<Contracts.Create2Factory>;
188
197
 
189
198
  deployContract(
190
199
  name: "AccessManagedUpgradeable",
@@ -262,6 +271,10 @@ declare module "hardhat/types/runtime" {
262
271
  name: "BaseImplementation",
263
272
  signerOrOptions?: ethers.Signer | DeployContractOptions
264
273
  ): Promise<Contracts.BaseImplementation>;
274
+ deployContract(
275
+ name: "Create2Factory",
276
+ signerOrOptions?: ethers.Signer | DeployContractOptions
277
+ ): Promise<Contracts.Create2Factory>;
265
278
 
266
279
  deployContract(
267
280
  name: "AccessManagedUpgradeable",
@@ -358,6 +371,11 @@ declare module "hardhat/types/runtime" {
358
371
  args: any[],
359
372
  signerOrOptions?: ethers.Signer | DeployContractOptions
360
373
  ): Promise<Contracts.BaseImplementation>;
374
+ deployContract(
375
+ name: "Create2Factory",
376
+ args: any[],
377
+ signerOrOptions?: ethers.Signer | DeployContractOptions
378
+ ): Promise<Contracts.Create2Factory>;
361
379
 
362
380
  // default types
363
381
  getContractFactory(
@@ -44,3 +44,5 @@ export type { AuthorityManager } from "./contracts/AuthorityManager";
44
44
  export { AuthorityManager__factory } from "./factories/contracts/AuthorityManager__factory";
45
45
  export type { BaseImplementation } from "./contracts/base/BaseImplementation";
46
46
  export { BaseImplementation__factory } from "./factories/contracts/base/BaseImplementation__factory";
47
+ export type { Create2Factory } from "./contracts/factory/Create2Factory";
48
+ export { Create2Factory__factory } from "./factories/contracts/factory/Create2Factory__factory";
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Multi-chain address encoding — converts EVM, Tron, and Solana addresses to hex bytes.
3
+ */
4
+ import bs58 from "bs58";
5
+ import { tronToHex } from "./tronHelper";
6
+
7
+ /**
8
+ * Convert any address format to hex bytes.
9
+ * - EVM address (0x prefix): return as-is lowercase
10
+ * - Tron address (T prefix, 34 chars, 0x41 byte): convert via tronToHex
11
+ * - Solana/other base58 address: base58 decode to full bytes
12
+ * @param addr - address in any supported format
13
+ */
14
+ export function addressToHex(addr: string): string {
15
+ if (addr.startsWith("0x")) {
16
+ return addr.toLowerCase();
17
+ }
18
+
19
+ if (isTronAddress(addr)) {
20
+ return tronToHex(addr);
21
+ }
22
+
23
+ if (isBase58(addr)) {
24
+ const decoded = bs58.decode(addr);
25
+ return "0x" + Buffer.from(decoded).toString("hex");
26
+ }
27
+
28
+ throw new Error(`Unknown address format: ${addr}`);
29
+ }
30
+
31
+ /** Check if a string is valid base58 encoding. */
32
+ export function isBase58(addr: string): boolean {
33
+ const base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
34
+ for (const char of addr) {
35
+ if (!base58Chars.includes(char)) {
36
+ return false;
37
+ }
38
+ }
39
+ return true;
40
+ }
41
+
42
+ /** Check if address is Tron format (T prefix, 34 chars, 0x41 first byte after decode). */
43
+ export function isTronAddress(addr: string): boolean {
44
+ if (!addr.startsWith("T") || addr.length !== 34 || !isBase58(addr)) return false;
45
+ try {
46
+ const decoded = bs58.decode(addr);
47
+ // Tron: 0x41 (1 byte) + address (20 bytes) + checksum (4 bytes) = 25 bytes
48
+ return decoded.length === 25 && decoded[0] === 0x41;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /** Check if chain name is Solana. */
55
+ export function isSolanaChain(chainName: string): boolean {
56
+ return chainName === "Sol" || chainName === "sol_test";
57
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Calculate creationCode hash for CREATE2 address prediction.
3
+ */
4
+ const { keccak256, Interface } = require("ethers");
5
+
6
+ /**
7
+ * Get codeHash for a contract deployment.
8
+ * @param artifacts - hardhat artifacts (hre.artifacts)
9
+ * @param contractName - contract name (e.g. "Gateway", "AuthorityManager")
10
+ * @param args - constructor arguments array
11
+ */
12
+ export async function getCodeHash(artifacts: any, contractName: string, args: any[] = []): Promise<string> {
13
+ const artifact = await artifacts.readArtifact(contractName);
14
+ let bytecode = artifact.bytecode;
15
+ if (!bytecode.startsWith("0x")) bytecode = "0x" + bytecode;
16
+
17
+ if (args.length > 0) {
18
+ const iface = new Interface(artifact.abi);
19
+ const encoded = iface.encodeDeploy(args);
20
+ return keccak256(bytecode + encoded.slice(2));
21
+ }
22
+
23
+ return keccak256(bytecode);
24
+ }
25
+
26
+ /**
27
+ * Get codeHash for an ERC1967Proxy deployment.
28
+ * @param artifacts - hardhat artifacts (hre.artifacts)
29
+ * @param implAddress - implementation address
30
+ * @param implName - implementation contract name (for encoding initData)
31
+ * @param initArgs - arguments for initialize() function
32
+ */
33
+ export async function getProxyCodeHash(
34
+ artifacts: any,
35
+ implAddress: string,
36
+ implName: string,
37
+ initArgs: any[] = []
38
+ ): Promise<string> {
39
+ return getCustomProxyCodeHash(artifacts, "ERC1967Proxy", implAddress, implName, initArgs);
40
+ }
41
+
42
+ /**
43
+ * Get codeHash for a custom proxy deployment.
44
+ * @param artifacts - hardhat artifacts (hre.artifacts)
45
+ * @param proxyName - proxy contract name (e.g. "MyCustomProxy")
46
+ * @param implAddress - implementation address
47
+ * @param implName - implementation contract name (for encoding initData)
48
+ * @param initArgs - arguments for initialize() function
49
+ */
50
+ export async function getCustomProxyCodeHash(
51
+ artifacts: any,
52
+ proxyName: string,
53
+ implAddress: string,
54
+ implName: string,
55
+ initArgs: any[] = []
56
+ ): Promise<string> {
57
+ const proxyArtifact = await artifacts.readArtifact(proxyName);
58
+ let bytecode = proxyArtifact.bytecode;
59
+ if (!bytecode.startsWith("0x")) bytecode = "0x" + bytecode;
60
+
61
+ let initData = "0x";
62
+ if (initArgs.length > 0) {
63
+ const implArtifact = await artifacts.readArtifact(implName);
64
+ const iface = new Interface(implArtifact.abi);
65
+ initData = iface.encodeFunctionData("initialize", initArgs);
66
+ }
67
+
68
+ const { AbiCoder } = require("ethers");
69
+ const constructorArgs = AbiCoder.defaultAbiCoder().encode(
70
+ ["address", "bytes"],
71
+ [implAddress, initData]
72
+ );
73
+
74
+ return keccak256(bytecode + constructorArgs.slice(2));
75
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Deploy record — read/write deployed contract addresses from deploy.json
3
+ *
4
+ * Structure:
5
+ * {
6
+ * "prod": { "Mapo": { "Relay": "0x..." }, "Bsc": { "Gateway": "0x..." } },
7
+ * "main": { "Mapo": { "Relay": "0x..." } },
8
+ * "test": { "Mapo": { "Relay": "0x..." } }
9
+ * }
10
+ */
11
+ let fs = require("fs");
12
+ let path = require("path");
13
+
14
+ type DeployData = {
15
+ [env: string]: {
16
+ [chain: string]: {
17
+ [key: string]: string;
18
+ };
19
+ };
20
+ };
21
+
22
+ export interface DeploymentPath {
23
+ env: string; // "prod", "main", "test"
24
+ chain: string; // "Mapo", "Bsc", "Tron"
25
+ }
26
+
27
+ export interface DeploymentOptions {
28
+ basePath?: string; // defaults to <cwd>/deployments/
29
+ env: string; // "prod", "main", "test" — required
30
+ }
31
+
32
+ function defaultDeployPath(): string {
33
+ return path.join(process.cwd(), "deployments");
34
+ }
35
+
36
+ /**
37
+ * Resolve deployment path from network name and env.
38
+ * @param network - hardhat network name (e.g. "Bsc", "Mapo_test", "Tron")
39
+ * @param env - deployment environment: "prod", "main", "test"
40
+ * @returns { env, chain } for deploy.json lookup
41
+ */
42
+ export function resolveDeploymentPath(network: string, env: string): DeploymentPath {
43
+ // Strip _test suffix from network name to get chain name
44
+ const chain = network.replace(/_?test$/i, "");
45
+ return { env, chain: chain.charAt(0).toUpperCase() + chain.slice(1) };
46
+ }
47
+
48
+ /**
49
+ * Read a deployed contract address from deploy.json.
50
+ * @param network - hardhat network name
51
+ * @param key - contract key (e.g. "Gateway", "Authority")
52
+ * @param opts - optional basePath and env overrides
53
+ */
54
+ export async function getDeploymentByKey(network: string, key: string, opts: DeploymentOptions): Promise<string> {
55
+ const deployPath = opts.basePath || defaultDeployPath();
56
+ const { env, chain } = resolveDeploymentPath(network, opts.env);
57
+ const data = await readDeployFile(deployPath);
58
+ const addr = data[env]?.[chain]?.[key];
59
+ if (!addr) throw new Error(`no ${key} deployment in ${env}.${chain}`);
60
+ return addr;
61
+ }
62
+
63
+ /**
64
+ * Check if a contract address exists and is valid in deploy.json.
65
+ * @param network - hardhat network name
66
+ * @param key - contract key
67
+ * @param opts - optional basePath and env overrides
68
+ */
69
+ export async function hasDeployment(network: string, key: string, opts: DeploymentOptions): Promise<boolean> {
70
+ try {
71
+ const deployPath = opts.basePath || defaultDeployPath();
72
+ const { env, chain } = resolveDeploymentPath(network, opts.env);
73
+ const data = await readDeployFile(deployPath);
74
+ const addr = data[env]?.[chain]?.[key];
75
+ return !!addr && addr.length > 2 && addr !== "0x";
76
+ } catch {
77
+ return false;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Save a deployed contract address to deploy.json.
83
+ * @param network - hardhat network name
84
+ * @param key - contract key (e.g. "Gateway")
85
+ * @param addr - deployed address
86
+ * @param opts - optional basePath and env overrides
87
+ */
88
+ export async function saveDeployment(network: string, key: string, addr: string, opts: DeploymentOptions): Promise<void> {
89
+ const deployPath = opts.basePath || defaultDeployPath();
90
+ const { env, chain } = resolveDeploymentPath(network, opts.env);
91
+ const data = await readDeployFile(deployPath);
92
+ if (!data[env]) data[env] = {};
93
+ if (!data[env][chain]) data[env][chain] = {};
94
+ data[env][chain][key] = addr;
95
+ const filePath = path.resolve(deployPath, "deploy.json");
96
+ await ensureDir(deployPath);
97
+ await fs.promises.writeFile(filePath, JSON.stringify(data, null, "\t"));
98
+ }
99
+
100
+ async function readDeployFile(basePath: string): Promise<DeployData> {
101
+ const filePath = path.resolve(basePath, "deploy.json");
102
+ try {
103
+ const rawdata = await fs.promises.readFile(filePath, "utf-8");
104
+ return JSON.parse(rawdata);
105
+ } catch {
106
+ return {};
107
+ }
108
+ }
109
+
110
+ async function ensureDir(dirPath: string): Promise<void> {
111
+ const absPath = path.resolve(dirPath);
112
+ try {
113
+ await fs.promises.stat(absPath);
114
+ } catch {
115
+ await fs.promises.mkdir(absPath, { recursive: true });
116
+ }
117
+ }
@@ -0,0 +1,123 @@
1
+ import { isTronNetwork, TronClient } from "./tronHelper";
2
+ import { evmDeploy, evmDeployProxy, evmUpgradeProxy } from "./evmHelper";
3
+ import { verify as _verify } from "./verifier";
4
+
5
+ /**
6
+ * Unified deployer — auto-routes to EVM or Tron based on network name.
7
+ *
8
+ * Usage in hardhat tasks:
9
+ * const deployer = createDeployer(hre, { autoVerify: true });
10
+ * let addr = await deployer.deploy("Gateway", [admin], salt);
11
+ * let { proxy, implementation } = await deployer.deployProxy("Gateway", [admin], salt);
12
+ * let newImpl = await deployer.upgrade("Gateway", proxyAddr);
13
+ */
14
+
15
+ export interface DeployerOptions {
16
+ autoVerify?: boolean; // auto verify after deploy/upgrade, defaults to false
17
+ }
18
+
19
+ export interface DeployResult {
20
+ address: string; // primary address (0x hex for EVM, base58 for Tron)
21
+ hex?: string; // 0x hex (Tron only, EVM same as address)
22
+ }
23
+
24
+ export interface DeployProxyResult {
25
+ proxy: string; // proxy address (0x hex for EVM, base58 for Tron)
26
+ implementation: string; // impl address
27
+ proxyHex?: string; // Tron hex
28
+ implementationHex?: string; // Tron hex
29
+ }
30
+
31
+ export interface Deployer {
32
+ deploy(contractName: string, args?: any[], salt?: string): Promise<DeployResult>;
33
+ deployProxy(contractName: string, initArgs?: any[], salt?: string): Promise<DeployProxyResult>;
34
+ upgrade(contractName: string, proxyAddr: string): Promise<DeployResult>;
35
+ verify(contractName: string, address: string, constructorArgs?: any[], contractPath?: string): Promise<void>;
36
+ isTron: boolean;
37
+ network: string;
38
+ }
39
+
40
+ /**
41
+ * Create a unified deployer that auto-routes to EVM or Tron based on network.
42
+ * @param hre - hardhat runtime environment
43
+ * @param opts - options (autoVerify: auto-verify after deploy, defaults to false)
44
+ */
45
+ export function createDeployer(hre: any, opts: DeployerOptions = {}): Deployer {
46
+ const network = hre.network.name;
47
+ const isTron = isTronNetwork(network);
48
+ const autoVerify = opts.autoVerify || false;
49
+
50
+ async function tryVerify(contractName: string, address: string, constructorArgs?: any[], contractPath?: string) {
51
+ if (!autoVerify) return;
52
+ try {
53
+ await _verify(hre, { contractName, address, constructorArgs, contractPath });
54
+ } catch (e: any) {
55
+ console.log(`[warn] auto-verify failed: ${e.message || e}`);
56
+ }
57
+ }
58
+
59
+ if (isTron) {
60
+ const client = TronClient.fromHre(hre);
61
+
62
+ return {
63
+ isTron: true,
64
+ network,
65
+
66
+ async deploy(contractName, args = [], salt = "") {
67
+ let result = await client.deploy(hre.artifacts, contractName, args, salt);
68
+ await tryVerify(contractName, result.base58, args);
69
+ return { address: result.base58, hex: result.hex };
70
+ },
71
+
72
+ async deployProxy(contractName, initArgs = [], salt = "") {
73
+ let result = await client.deployProxy(hre.artifacts, contractName, initArgs, salt);
74
+ await tryVerify(contractName, result.implementation.base58);
75
+ return {
76
+ proxy: result.proxy.base58,
77
+ implementation: result.implementation.base58,
78
+ proxyHex: result.proxy.hex,
79
+ implementationHex: result.implementation.hex,
80
+ };
81
+ },
82
+
83
+ async upgrade(contractName, proxyAddr) {
84
+ let result = await client.upgradeProxy(hre.artifacts, contractName, proxyAddr);
85
+ await tryVerify(contractName, result.base58);
86
+ return { address: result.base58, hex: result.hex };
87
+ },
88
+
89
+ async verify(contractName, address, constructorArgs, contractPath) {
90
+ await _verify(hre, { contractName, address, constructorArgs, contractPath });
91
+ },
92
+ };
93
+ }
94
+
95
+ // EVM
96
+ const { ethers, artifacts } = hre;
97
+ return {
98
+ isTron: false,
99
+ network,
100
+
101
+ async deploy(contractName, args = [], salt = "") {
102
+ let addr = await evmDeploy(ethers, artifacts, contractName, args, salt);
103
+ await tryVerify(contractName, addr, args);
104
+ return { address: addr };
105
+ },
106
+
107
+ async deployProxy(contractName, initArgs = [], salt = "") {
108
+ let result = await evmDeployProxy(ethers, artifacts, contractName, initArgs, salt);
109
+ await tryVerify(contractName, result.implementation);
110
+ return { proxy: result.proxy, implementation: result.implementation };
111
+ },
112
+
113
+ async upgrade(contractName, proxyAddr) {
114
+ let addr = await evmUpgradeProxy(ethers, contractName, proxyAddr);
115
+ await tryVerify(contractName, addr);
116
+ return { address: addr };
117
+ },
118
+
119
+ async verify(contractName, address, constructorArgs, contractPath) {
120
+ await _verify(hre, { contractName, address, constructorArgs, contractPath });
121
+ },
122
+ };
123
+ }