Skip to content

Commit f13bac0

Browse files
committed
chore: create claims data script
1 parent 0e01899 commit f13bac0

File tree

4 files changed

+208
-1
lines changed

4 files changed

+208
-1
lines changed

examples/ts/access-token.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ import { BitGoAPI } from '@bitgo/sdk-api';
66
require('dotenv').config({ path: '../../.env' });
77

88
const bitgo = new BitGoAPI({
9-
env: 'test', // Change this to env: 'prod' when you are ready for production
9+
// env: 'prod', // Change this to env: 'prod' when you are ready for production
10+
env: 'staging',
1011
});
1112

1213
async function main() {
1314
const auth_res = await bitgo.authenticate({
15+
// username: process.env.PROD_EMAIL!,
16+
// password: process.env.PROD_PASS!,
17+
// otp: '874342',
1418
username: process.env.TEST_EMAIL!,
1519
password: process.env.TEST_PASS!,
1620
otp: '000000',

examples/ts/build-message.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ async function main() {
3636
message: {
3737
messageRaw: testnetMessageRaw,
3838
messageStandardType: MessageStandardType.EIP191,
39+
// signerAddress: '' // optional, will use wallet root address if not provided
3940
},
4041
});
4142
console.dir(txRequest);

examples/ts/create-claims-data.ts

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/**
2+
* Create test wallets and generate claims data for multiple coins.
3+
*
4+
* This script can either create new wallets or use existing wallets to generate
5+
* receive addresses and CSV files containing claims data for Midnight airdrop testing.
6+
*
7+
* USAGE GUIDELINES:
8+
*
9+
* 1. ENVIRONMENT SETUP:
10+
* - Set TESTNET_ACCESS_TOKEN in .env file (your BitGo testnet access token)
11+
* - Set TEST_PASS in .env file (wallet passphrase)
12+
*
13+
* 2. CONFIGURATION OPTIONS:
14+
* - CREATE_NEW_WALLETS: Set to true to create new wallets, false to use existing ones
15+
* - COINS_TO_PROCESS: Array of coin symbols to process (empty array = process all coins)
16+
* - EXISTING_WALLET_IDS: Required when CREATE_NEW_WALLETS is false
17+
* - numAddresses: Number of receive addresses to generate per wallet
18+
*
19+
* 3. EXAMPLES:
20+
* - Process all coins with new wallets: CREATE_NEW_WALLETS = true, COINS_TO_PROCESS = []
21+
* - Process only BTC and SOL: COINS_TO_PROCESS = ['tbtc4', 'tsol']
22+
* - Use existing wallets: CREATE_NEW_WALLETS = false, update EXISTING_WALLET_IDS
23+
*
24+
* 4. OUTPUT:
25+
* - CSV files: receive-addresses-{coin}-{walletId}.csv
26+
* - Format: coin,allocationAmount,walletId,enterpriseId,address
27+
*
28+
* Copyright 2022, BitGo, Inc. All Rights Reserved.
29+
*/
30+
import { BitGoAPI } from '@bitgo/sdk-api';
31+
import { Tada } from "@bitgo/sdk-coin-ada";
32+
import { Tsol } from "@bitgo/sdk-coin-sol";
33+
import { Tbtc4 } from "@bitgo/sdk-coin-btc";
34+
import { Tbsc } from "@bitgo/sdk-coin-bsc";
35+
import { Hteth } from "@bitgo/sdk-coin-eth";
36+
import * as fs from 'fs';
37+
require('dotenv').config({ path: '../../.env' });
38+
39+
const bitgo = new BitGoAPI({
40+
accessToken: process.env.TESTNET_ACCESS_TOKEN,
41+
env: 'staging',
42+
});
43+
44+
// Register coin types
45+
bitgo.register('hteth', Hteth.createInstance);
46+
bitgo.register('tada', Tada.createInstance);
47+
bitgo.register('tsol', Tsol.createInstance);
48+
bitgo.register('tbtc4', Tbtc4.createInstance);
49+
bitgo.register('tbsc', Tbsc.createInstance);
50+
51+
const passphrase = process.env.TEST_PASS;
52+
const enterprise = '5bd795f1bf7435a503a0a647ec5d3b3d';
53+
const numAddresses = 20;
54+
55+
// Configuration: Set to true to create new wallets, false to use existing wallet IDs
56+
const CREATE_NEW_WALLETS = false;
57+
58+
// Configuration: Specify which coins to process (empty array means process all coins)
59+
const COINS_TO_PROCESS: string[] = ['tbsc']; // e.g., ['tbtc4', 'tsol'] to process only these coins
60+
61+
// If CREATE_NEW_WALLETS is false, provide existing wallet IDs for each coin
62+
const EXISTING_WALLET_IDS = {
63+
hteth: '67123abc456def789ghi012jkl345mno',
64+
tbtc4: '67234bcd567efg890hij123klm456nop',
65+
tsol: '67345cde678fgh901ijk234lmn567opq',
66+
tada: '67456def789ghi012jkl345mno678pqr',
67+
tbsc: '6894dd8ff0ee06d1630c84d54d381dde'
68+
};
69+
70+
// Generate unique timestamp for this run
71+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19); // 2025-09-15T14-30-45
72+
73+
const coins = [
74+
{ coin: 'hteth', label: `Midnight Claims ETH Wallet ${timestamp}` },
75+
{ coin: 'tbtc4', label: `Midnight Claims BTC Wallet ${timestamp}` },
76+
{ coin: 'tsol', label: `Midnight Claims SOL Wallet ${timestamp}` },
77+
{ coin: 'tada', label: `Midnight Claims ADA Wallet ${timestamp}` },
78+
{ coin: 'tbsc', label: `Midnight Claims BSC Wallet ${timestamp}` }
79+
];
80+
81+
type WalletCreationResult = {
82+
coin: string;
83+
success: true;
84+
walletId: string;
85+
addressCount: number;
86+
filename: string;
87+
} | {
88+
coin: string;
89+
success: false;
90+
error: string;
91+
};
92+
93+
async function createWalletAndAddresses(coin: string, label: string): Promise<WalletCreationResult> {
94+
console.log(`\n=== ${CREATE_NEW_WALLETS ? 'Creating' : 'Using existing'} wallet for ${coin.toUpperCase()} ===`);
95+
96+
try {
97+
let wallet;
98+
let walletId;
99+
100+
if (CREATE_NEW_WALLETS) {
101+
// Create a new wallet
102+
const response = await bitgo.coin(coin).wallets().generateWallet({
103+
label,
104+
passphrase,
105+
enterprise,
106+
});
107+
108+
if (!('backupKeychain' in response)) {
109+
throw new Error('wallet missing required keychains');
110+
}
111+
112+
wallet = response.wallet;
113+
walletId = wallet.id();
114+
console.log('Created new wallet ID:', walletId);
115+
} else {
116+
// Use existing wallet
117+
walletId = EXISTING_WALLET_IDS[coin as keyof typeof EXISTING_WALLET_IDS];
118+
if (!walletId) {
119+
throw new Error(`No existing wallet ID configured for coin: ${coin}`);
120+
}
121+
122+
wallet = await bitgo.coin(coin).wallets().get({ id: walletId });
123+
console.log('Using existing wallet ID:', walletId);
124+
}
125+
126+
console.log(`Wallet label: ${wallet.label()}`);
127+
128+
const csvHeader = 'coin,allocationAmount,originWalletId,enterpriseId,originAddress\n';
129+
let csvRows = '';
130+
for (let i = 0; i < numAddresses; i++) {
131+
const newAddress = await wallet.createAddress();
132+
console.log(`Receive Address ${i + 1}:`, newAddress.address);
133+
const allocationAmount = Math.floor(Math.random() * 1_000_000);
134+
csvRows += `${coin},${allocationAmount},${walletId},${enterprise},${newAddress.address}\n`;
135+
}
136+
137+
const filename = `./receive-addresses-${coin}-${walletId}.csv`;
138+
fs.writeFileSync(filename, csvHeader + csvRows);
139+
console.log(`CSV file updated: ${filename}`);
140+
141+
return {
142+
coin,
143+
walletId,
144+
success: true,
145+
addressCount: numAddresses,
146+
filename
147+
};
148+
} catch (error: any) {
149+
console.error(`Error ${CREATE_NEW_WALLETS ? 'creating' : 'using'} wallet for ${coin}:`, error);
150+
return {
151+
coin,
152+
success: false,
153+
error: error.message || error.toString()
154+
};
155+
}
156+
}
157+
158+
async function main() {
159+
if (!passphrase) {
160+
throw new Error('TEST_PASS environment variable is required');
161+
}
162+
163+
if (!process.env.TESTNET_ACCESS_TOKEN) {
164+
throw new Error('TESTNET_ACCESS_TOKEN environment variable is required');
165+
}
166+
167+
console.log(`Starting ${CREATE_NEW_WALLETS ? 'wallet creation' : 'address generation on existing wallets'} for multiple coins...`);
168+
console.log(`Enterprise ID: ${enterprise}`);
169+
console.log(`Number of addresses per wallet: ${numAddresses}`);
170+
console.log(`Mode: ${CREATE_NEW_WALLETS ? 'CREATE NEW WALLETS' : 'USE EXISTING WALLETS'}`);
171+
172+
const results: WalletCreationResult[] = [];
173+
174+
for (const { coin, label } of coins) {
175+
// Check if the coin is in the COINS_TO_PROCESS list or if the list is empty (process all coins)
176+
if (COINS_TO_PROCESS.length === 0 || COINS_TO_PROCESS.includes(coin)) {
177+
const result = await createWalletAndAddresses(coin, label);
178+
results.push(result);
179+
180+
// Add a small delay between wallet creations to avoid rate limiting
181+
await new Promise(resolve => setTimeout(resolve, 2000));
182+
} else {
183+
console.log(`Skipping ${coin.toUpperCase()} as it's not in the COINS_TO_PROCESS list`);
184+
}
185+
}
186+
187+
console.log('\n=== SUMMARY ===');
188+
results.forEach(result => {
189+
if (result.success) {
190+
console.log(`✅ ${result.coin}: Wallet ${result.walletId} created with ${result.addressCount} addresses`);
191+
console.log(` File: ${result.filename}`);
192+
} else {
193+
console.log(`❌ ${result.coin}: Failed - ${result.error}`);
194+
}
195+
});
196+
197+
const successfulCreations = results.filter(r => r.success);
198+
console.log(`\nCompleted: ${successfulCreations.length}/${results.length} wallets created successfully`);
199+
}
200+
201+
main().catch((e) => console.error('Script failed:', e));

examples/ts/sign-message.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ async function signMessage(): Promise<void> {
2626
message: {
2727
messageRaw: testnetMessageRaw,
2828
messageStandardType: MessageStandardType.EIP191,
29+
// signerAddress: '' // optional, will use wallet root address if not provided
2930
},
3031
walletPassphrase,
3132
});

0 commit comments

Comments
 (0)