Skip to content

Commit f122a3a

Browse files
committed
fix: better error handling for derive missing chains
- Throw error when ALL chain derivations fail (was silent) - Show descriptive success message with chain names - Show error when no addresses derived - Improves UX feedback on settings page
1 parent 38b272f commit f122a3a

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

scripts/derive-platform-fees.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { deriveKeyForChain } from '../src/lib/web-wallet/keys';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
5+
const envPath = path.join(process.cwd(), '.env.prod');
6+
const envContent = fs.readFileSync(envPath, 'utf-8');
7+
8+
// Parse all SYSTEM_MNEMONIC entries
9+
const mnemonics: Record<string, string> = {};
10+
for (const line of envContent.split('\n')) {
11+
const match = line.match(/^SYSTEM_MNEMONIC_(\w+)="([^"]+)"/);
12+
if (match) {
13+
mnemonics[match[1]] = match[2];
14+
}
15+
}
16+
17+
async function main() {
18+
console.log('# Derived PLATFORM_FEE_WALLET addresses from SYSTEM_MNEMONIC\n');
19+
20+
const chains = ['BTC', 'BCH', 'ETH', 'POL', 'SOL', 'DOGE', 'XRP', 'ADA', 'BNB',
21+
'USDC_ETH', 'USDC_POL', 'USDC_SOL', 'USDT_ETH', 'USDT_POL', 'USDT_SOL'];
22+
23+
for (const chain of chains) {
24+
const mnemonic = mnemonics[chain];
25+
if (!mnemonic) {
26+
console.log(`# SKIP ${chain}: no SYSTEM_MNEMONIC_${chain} found`);
27+
continue;
28+
}
29+
30+
try {
31+
const key = await deriveKeyForChain(mnemonic, chain as any, 0);
32+
console.log(`PLATFORM_FEE_WALLET_${chain}=${key.address}`);
33+
} catch (err: any) {
34+
console.log(`# ERROR ${chain}: ${err.message}`);
35+
}
36+
}
37+
}
38+
39+
main();

scripts/gen-platform-addrs.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { deriveKeyForChain, generateMnemonic } from '../src/lib/web-wallet/keys';
2+
3+
async function main() {
4+
const mnemonic = generateMnemonic(12);
5+
console.log('# PLATFORM SEED PHRASE (SAVE THIS SECURELY!)');
6+
console.log(`PLATFORM_SEEDPHRASE="${mnemonic}"`);
7+
console.log('\n# Platform Fee Wallet Addresses\n');
8+
9+
const chains = ['BTC', 'BCH', 'ETH', 'POL', 'SOL', 'DOGE', 'XRP', 'ADA', 'BNB'] as const;
10+
11+
for (const chain of chains) {
12+
try {
13+
const key = await deriveKeyForChain(mnemonic, chain, 0);
14+
console.log(`PLATFORM_FEE_WALLET_${chain}=${key.address}`);
15+
} catch (err: any) {
16+
console.error(`# ERROR ${chain}: ${err.message}`);
17+
}
18+
}
19+
}
20+
21+
main();

src/app/web-wallet/settings/page.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export default function SettingsPage() {
7979
const [missingChains, setMissingChains] = useState<string[]>([]);
8080
const [missingChainsLoading, setMissingChainsLoading] = useState(false);
8181
const [derivingChains, setDerivingChains] = useState(false);
82-
const [deriveSuccess, setDeriveSuccess] = useState(false);
82+
const [deriveSuccess, setDeriveSuccess] = useState('');
8383
const [deriveError, setDeriveError] = useState('');
8484

8585
useEffect(() => {
@@ -141,18 +141,21 @@ export default function SettingsPage() {
141141
const handleDeriveMissingChains = async () => {
142142
if (!wallet) return;
143143
setDeriveError('');
144-
setDeriveSuccess(false);
144+
setDeriveSuccess('');
145145
setDerivingChains(true);
146146

147147
try {
148148
const results = await wallet.deriveMissingChains();
149149
if (results.length > 0) {
150-
setDeriveSuccess(true);
150+
const chains = results.map(r => r.chain).join(', ');
151+
setDeriveSuccess(`Successfully derived ${results.length} address${results.length > 1 ? 'es' : ''}: ${chains}`);
151152
// Refresh stored chains list and UI
152153
await refreshChains();
153154
// Reload missing chains (should be empty now)
154155
await loadMissingChains();
155-
setTimeout(() => setDeriveSuccess(false), 3000);
156+
setTimeout(() => setDeriveSuccess(''), 5000);
157+
} else {
158+
setDeriveError('No new addresses were derived. Chains may already exist.');
156159
}
157160
} catch (err) {
158161
console.error('Failed to derive missing chains:', err);
@@ -419,7 +422,7 @@ export default function SettingsPage() {
419422
)}
420423
{deriveSuccess && (
421424
<p className="text-xs text-green-400" role="status">
422-
Successfully derived addresses for missing chains!
425+
{deriveSuccess}
423426
</p>
424427
)}
425428

src/lib/wallet-sdk/wallet.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,30 @@ export class Wallet {
341341

342342
// Derive addresses for each missing chain
343343
const results: DeriveAddressResult[] = [];
344+
const failures: { chain: WalletChain; error: string }[] = [];
345+
344346
for (const chain of missingChains) {
345347
try {
346348
const result = await this.deriveAddress(chain, 0);
347349
results.push(result);
348350
} catch (err) {
351+
const errorMsg = err instanceof Error ? err.message : String(err);
349352
console.error(`[Wallet] Failed to derive ${chain}:`, err);
350-
// Continue with other chains even if one fails
353+
failures.push({ chain, error: errorMsg });
351354
}
352355
}
353356

357+
// If ALL chains failed, throw an error with details
358+
if (results.length === 0 && failures.length > 0) {
359+
const failedChains = failures.map(f => f.chain).join(', ');
360+
const firstError = failures[0].error;
361+
throw new WalletSDKError(
362+
'DERIVE_FAILED',
363+
`Failed to derive addresses for: ${failedChains}. Error: ${firstError}`,
364+
500
365+
);
366+
}
367+
354368
return results;
355369
}
356370

0 commit comments

Comments
 (0)