-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy-thirdweb.js
More file actions
235 lines (201 loc) Β· 8.1 KB
/
Copy pathdeploy-thirdweb.js
File metadata and controls
235 lines (201 loc) Β· 8.1 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// SPDX-License-Identifier: MIT
/**
* Thirdweb Deployment Script for ISELF Token
*
* This script deploys the ISelfToken contract using thirdweb SDK
* Compatible with Termux on Android tablets
*
* Prerequisites:
* 1. Install Node.js on Termux: pkg install nodejs
* 2. Install dependencies: npm install
* 3. Copy .env.example to .env and fill in your details
* 4. Run: npm run deploy
*/
require('dotenv').config();
const { ThirdwebSDK } = require('@thirdweb-dev/sdk');
const { ethers } = require('ethers');
const fs = require('fs');
const path = require('path');
// Configuration validation
function validateConfig() {
const requiredVars = ['THIRDWEB_SECRET_KEY', 'PRIVATE_KEY', 'NETWORK'];
const missing = requiredVars.filter(varName => !process.env[varName]);
if (missing.length > 0) {
console.error('β Error: Missing required environment variables:');
missing.forEach(varName => console.error(` - ${varName}`));
console.error('\nπ‘ Please copy .env.example to .env and fill in your details');
process.exit(1);
}
// Validate private key format
const privateKey = process.env.PRIVATE_KEY.startsWith('0x')
? process.env.PRIVATE_KEY
: '0x' + process.env.PRIVATE_KEY;
if (privateKey.length !== 66) {
console.error('β Error: PRIVATE_KEY appears to be invalid (should be 64 hex characters)');
process.exit(1);
}
return privateKey;
}
// Network configuration
const NETWORK_CONFIG = {
mumbai: {
name: 'Mumbai Testnet',
chainId: 80001,
rpcUrl: 'https://rpc-mumbai.maticvigil.com',
explorer: 'https://mumbai.polygonscan.com'
},
polygon: {
name: 'Polygon Mainnet',
chainId: 137,
rpcUrl: 'https://polygon-rpc.com',
explorer: 'https://polygonscan.com'
},
goerli: {
name: 'Goerli Testnet',
chainId: 5,
rpcUrl: 'https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
explorer: 'https://goerli.etherscan.io'
},
sepolia: {
name: 'Sepolia Testnet',
chainId: 11155111,
rpcUrl: 'https://sepolia.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
explorer: 'https://sepolia.etherscan.io'
},
ethereum: {
name: 'Ethereum Mainnet',
chainId: 1,
rpcUrl: 'https://cloudflare-eth.com',
explorer: 'https://etherscan.io'
}
};
async function deployToken() {
console.log('π ISELF Token Deployment Script (Thirdweb)\n');
console.log('=' .repeat(60));
try {
// Validate configuration
const privateKey = validateConfig();
const network = process.env.NETWORK.toLowerCase();
if (!NETWORK_CONFIG[network]) {
console.error(`β Error: Unsupported network "${network}"`);
console.error(` Supported networks: ${Object.keys(NETWORK_CONFIG).join(', ')}`);
process.exit(1);
}
const networkInfo = NETWORK_CONFIG[network];
console.log(`π‘ Network: ${networkInfo.name} (Chain ID: ${networkInfo.chainId})`);
console.log(`π Using wallet: ${new ethers.Wallet(privateKey).address}`);
console.log(`π‘ Note: All tokens will be minted to the deployer wallet\n`);
// Initialize thirdweb SDK
console.log('βοΈ Initializing Thirdweb SDK...');
const sdk = ThirdwebSDK.fromPrivateKey(
privateKey,
network,
{
secretKey: process.env.THIRDWEB_SECRET_KEY,
}
);
console.log('β
SDK initialized\n');
// Get the wallet address
const wallet = await sdk.wallet.getAddress();
console.log(`πΌ Deploying from wallet: ${wallet}`);
// Check wallet balance
const balance = await sdk.wallet.balance();
console.log(`π° Wallet balance: ${ethers.utils.formatEther(balance.value)} ${balance.symbol}`);
if (balance.value.eq(0)) {
console.error('\nβ Error: Wallet has no funds. Please add some ETH/MATIC to deploy.');
console.error(` Send funds to: ${wallet}`);
process.exit(1);
}
console.log('\nπ Deploying ISelfToken contract...');
console.log(' Token Name: iself');
console.log(' Token Symbol: ISELF');
console.log(' Decimals: 18');
console.log(' Initial Supply: 1,000,000,000 ISELF (1 billion tokens)\n');
// Read the contract bytecode
const contractJsonPath = path.join(__dirname, 'IselfToken_compData.json');
let contractData;
if (fs.existsSync(contractJsonPath)) {
contractData = JSON.parse(fs.readFileSync(contractJsonPath, 'utf8'));
console.log('β
Contract compilation data loaded');
// Parse metadata to get bytecode
const metadata = JSON.parse(contractData.metadata);
console.log(` Compiler: Solidity ${metadata.compiler.version}`);
} else {
console.error('β Error: Contract compilation data not found');
console.error(` Expected at: ${contractJsonPath}`);
console.error(' Please compile the contract first in Remix');
process.exit(1);
}
// The contract expects initialSupply as constructor parameter
// Let's deploy 1 billion tokens (1000000000 * 10^18)
const initialSupply = ethers.BigNumber.from('1000000000').mul(
ethers.BigNumber.from('10').pow(18)
);
// Deploy using thirdweb
console.log('\nβ³ Deploying contract (this may take a minute)...');
console.log(` Initial Supply: ${ethers.utils.formatEther(initialSupply)} ISELF\n`);
const contractAddress = await sdk.deployer.deployContractFromAbi(
contractData.bytecode.object,
contractData.abi,
[initialSupply.toString()],
{
name: 'ISelfToken',
symbol: 'ISELF',
}
);
console.log('\n' + '='.repeat(60));
console.log('π SUCCESS! Contract deployed!');
console.log('='.repeat(60));
console.log(`π Contract Address: ${contractAddress}`);
console.log(`π View on Explorer: ${networkInfo.explorer}/address/${contractAddress}`);
console.log(`π Thirdweb Dashboard: https://thirdweb.com/${network}/${contractAddress}`);
console.log('='.repeat(60));
// Save deployment info
const deploymentInfo = {
network: networkInfo.name,
chainId: networkInfo.chainId,
contractAddress: contractAddress,
deployerAddress: wallet,
initialSupply: initialSupply.toString(),
timestamp: new Date().toISOString(),
explorerUrl: `${networkInfo.explorer}/address/${contractAddress}`,
thirdwebUrl: `https://thirdweb.com/${network}/${contractAddress}`
};
const deploymentFile = path.join(__dirname, `deployment-${network}-${Date.now()}.json`);
fs.writeFileSync(deploymentFile, JSON.stringify(deploymentInfo, null, 2));
console.log(`\nπΎ Deployment info saved to: ${path.basename(deploymentFile)}\n`);
// Verify the deployment
console.log('π Verifying deployment...');
const contract = await sdk.getContract(contractAddress);
const tokenName = await contract.call('name');
const tokenSymbol = await contract.call('symbol');
const totalSupply = await contract.call('totalSupply');
const deployerBalance = await contract.call('balanceOf', [wallet]);
console.log(`\nβ
Contract verified:`);
console.log(` Name: ${tokenName}`);
console.log(` Symbol: ${tokenSymbol}`);
console.log(` Total Supply: ${ethers.utils.formatEther(totalSupply)} ISELF`);
console.log(` Deployer Balance: ${ethers.utils.formatEther(deployerBalance)} ISELF`);
console.log('\n⨠Deployment complete!\n');
} catch (error) {
console.error('\nβ Deployment failed!');
console.error('Error:', error.message);
if (error.message.includes('insufficient funds')) {
console.error('\nπ‘ Tip: Make sure your wallet has enough funds to cover gas fees');
} else if (error.message.includes('nonce')) {
console.error('\nπ‘ Tip: Try again in a few seconds. There might be a pending transaction.');
} else if (error.message.includes('network')) {
console.error('\nπ‘ Tip: Check your internet connection and network configuration');
}
console.error('\nπ For help, visit: https://portal.thirdweb.com/\n');
process.exit(1);
}
}
// Run deployment
if (require.main === module) {
deployToken().catch(error => {
console.error('Unhandled error:', error);
process.exit(1);
});
}
module.exports = { deployToken };