-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
157 lines (142 loc) · 4.43 KB
/
index.ts
File metadata and controls
157 lines (142 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import { ethers, web3, run, artifacts } from "hardhat";
import { Contract, Signer } from "ethers";
export default class NFTManager {
private signer: any;
private contractName: string;
/**
* Create an instance of NFTManager
* @param contractName Name of the smart contract (e.g. "NFT")
* @param rpcUrl (optional) RPC url of the node
* @param privateKey (optional) Private key of the account
*/
public constructor(
contractName: string = "NFT",
rpcUrl?: string,
privateKey?: string
) {
this.contractName = contractName;
if (rpcUrl && privateKey) {
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
this.signer = new ethers.Wallet(privateKey, provider);
}
}
/**
* Add a signer to the NFTManager
* @param signer Signer of the account
* @returns NFTManager instance
*/
public connect(signer: Signer): NFTManager {
this.signer = signer;
return this;
}
/**
* Deploy a new NFT smart contract
* @param tokenName Name of the token
* @param tokenSymbol Symbol of the token
* @returns Address of the deployed contract
*/
public async deployContract(
tokenName: string,
tokenSymbol: string,
owner: string
): Promise<string> {
if (!this.signer) {
throw new Error("Signer is not set");
}
const NFT = (await ethers.getContractFactory(this.contractName)).connect(
this.signer
);
const contract = await NFT.deploy(tokenName, tokenSymbol, owner);
await contract.deployed();
await this.txWait(contract.deployTransaction.hash, 2);
return contract.address;
}
/**
* Verify the NFT smart contract
* @param contractAddress Address of the contract
* @param args Arguments of the function
*/
public async verify(contractAddress: string, ...args: any[]) {
await run("verify:verify", {
address: contractAddress,
constructorArguments: args,
}).catch((e: Error) => {
if (!e.message.toLowerCase().includes("already verified")) {
throw e;
}
});
}
/**
* Mint a new NFT
* @param contractAddress Address of the contract
* @param tokenURI URI of the token
*/
public async mintNFT(
contractAddress: string,
tokenURI: string,
artist: string
): Promise<string> {
if (!this.signer) {
throw new Error("Signer is not set");
}
const contract = await this.getContract(contractAddress);
const tx = await contract.mint(tokenURI, artist);
return tx.hash;
}
/**
* Get the token ID associated with a transaction
* @param txHash Transaction hash
* @param contractAddress (Optional) Address of the contract
* @returns The token ID associated with the transaction hash
*/
public async getTokenID(
txHash: string,
contractAddress?: string
): Promise<string> {
if (contractAddress == null) {
contractAddress = (await this.signer.provider.getTransaction(txHash)).to;
}
const abi = (await artifacts.readArtifact(this.contractName)).abi;
const web3Contract = new web3.eth.Contract(abi, contractAddress);
const events = await web3Contract.getPastEvents("Transfer", {
fromBlock: 0,
toBlock: "latest",
});
const event = events.find((e: any) => e.transactionHash === txHash);
if (event == null || event.returnValues.tokenId == null) {
throw new Error("Event not found");
}
return event.returnValues.tokenId;
}
/**
* Get the smart contract instance
* @param contractAddress Address of the contract
* @returns NFT contract instance
*/
public async getContract(contractAddress: string): Promise<Contract> {
if (!this.signer) {
throw new Error("Signer is not set");
}
const NFT = (await ethers.getContractFactory(this.contractName)).connect(
this.signer
);
return NFT.attach(contractAddress);
}
/**
* Wait for a transaction confirmations on the network
* @param txHash Transaction hash
* @param confirmations Number of confirmations to wait for
*/
public async txWait(txHash: string, confirmations: number) {
if (!this.signer) {
throw new Error("Signer is not set");
}
const provider = this.signer.provider;
const tx = await provider.getTransaction(txHash);
let currentBlock = await provider.getBlockNumber();
while (currentBlock - tx.blockNumber < confirmations) {
await new Promise((resolve) => setTimeout(resolve, 500));
currentBlock = await provider.getBlockNumber();
}
}
}