Skip to content

Commit

Permalink
refactor: fixes and polish
Browse files Browse the repository at this point in the history
  • Loading branch information
danwag06 committed Nov 5, 2024
1 parent 8a23b72 commit 1131ff6
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 41 deletions.
90 changes: 49 additions & 41 deletions src/pages/AppsAndTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export const AppsAndTools = () => {
const { addSnackbar } = useSnackbar();
const { query } = useBottomMenu();
const { keysService, bsvService, chromeStorageService, oneSatSPV } = useServiceContext();
const { bsvAddress, ordAddress, identityAddress } = keysService;
const { bsvAddress, ordAddress, identityAddress, getWifBalance, sweepWif } = keysService;
const exchangeRate = chromeStorageService.getCurrentAccountObject().exchangeRateCache?.rate ?? 0;
const [isProcessing, setIsProcessing] = useState(false);
const [page, setPage] = useState<AppsPage>(query === 'pending-locks' ? 'unlock' : 'main');
Expand All @@ -186,35 +186,37 @@ export const AppsAndTools = () => {
const [isBroadcasting, setIsBroadcasting] = useState(false);

const [wifKey, setWifKey] = useState('');
const [sweepBalance, setSweepBalance] = useState<{ regular: number; ordinals: number }>({ regular: 0, ordinals: 0 });
const [sweepBalance, setSweepBalance] = useState(0);
const [isSweeping, setIsSweeping] = useState(false);

const checkWIFBalance = async (wif: string) => {
try {
setIsProcessing(true);

//TODO: logic to check balance

setSweepBalance({
regular: 0,
ordinals: 0,
});
} catch (error) {
const balance = await getWifBalance(wif);
if (balance === undefined) {
addSnackbar('Error checking balance. Please ensure the WIF key is valid.', 'error');
console.error('WIF balance check error:', error);
} finally {
setIsProcessing(false);
return;
}
if (balance === 0) {
addSnackbar('No balance found for this WIF key', 'info');
setSweepBalance(balance);
return;
}

addSnackbar(`Balance found: ${balance / BSV_DECIMAL_CONVERSION} BSV`, 'success');
setSweepBalance(balance);
};

const sweepFunds = async () => {
try {
if (!wifKey) return;
setIsSweeping(true);

//TODO: logic to sweep funds

addSnackbar('Successfully swept funds to your wallet', 'success');
setPage('main');
const res = await sweepWif(wifKey);
if (res?.txid) {
addSnackbar('Successfully swept funds to your wallet', 'success');
handleResetSweep();
return;
} else {
addSnackbar('Error sweeping funds. Please try again.', 'error');
}
} catch (error) {
addSnackbar('Error sweeping funds. Please try again.', 'error');
console.error('Sweep error:', error);
Expand All @@ -223,13 +225,18 @@ export const AppsAndTools = () => {
}
};

const validateWIF = (wif: string): boolean => {
try {
//TODO: logic to validate WIF
return true;
} catch (error) {
return false;
}
const handleWifChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const wif = e.target.value;
if (!wif) return;
checkWIFBalance(wif);
setWifKey(e.target.value);
};

const handleResetSweep = () => {
setWifKey('');
setSweepBalance(0);
setIsSweeping(false);
setPage('main');
};

const getLockData = async () => {
Expand Down Expand Up @@ -556,33 +563,34 @@ export const AppsAndTools = () => {
<PageWrapper $marginTop={'0'}>
<HeaderText theme={theme}>Sweep Private Key</HeaderText>
<Text theme={theme}>Enter a private key in WIF format to sweep all funds to your wallet.</Text>
<Input theme={theme} placeholder="Enter WIF private key" value={wifKey} onChange={handleWifChange} />

<Input
theme={theme}
placeholder="Enter WIF private key"
value={wifKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setWifKey(e.target.value)}
onBlur={() => validateWIF(wifKey) && checkWIFBalance(wifKey)}
/>

{(sweepBalance.regular > 0 || sweepBalance.ordinals > 0) && (
{sweepBalance > 0 && (
<SweepInfo theme={theme}>
<Text theme={theme}>Available to sweep:</Text>
<Text theme={theme}>Regular BSV: {sweepBalance.regular} BSV</Text>
<Text theme={theme}>Ordinals: {sweepBalance.ordinals} BSV</Text>
<Text style={{ fontWeight: 700 }} theme={theme}>
{sweepBalance / BSV_DECIMAL_CONVERSION} BSV
</Text>
</SweepInfo>
)}

<ButtonsWrapper>
<Button theme={theme} type="secondary-outline" label="Cancel" onClick={() => setPage('main')} />
<Button
theme={theme}
type="secondary-outline"
label="Cancel"
onClick={handleResetSweep}
disabled={isSweeping}
/>
<Button
theme={theme}
type="primary"
label="Sweep Funds"
label={isSweeping ? 'Sweeping...' : 'Sweep Funds'}
onClick={sweepFunds}
disabled={!validateWIF(wifKey) || (sweepBalance.regular === 0 && sweepBalance.ordinals === 0)}
disabled={isSweeping || sweepBalance === 0}
/>
</ButtonsWrapper>
<Warning theme={theme}>This will only sweep funds. 1Sat Ordinals could be lost!</Warning>
</PageWrapper>
);

Expand Down
47 changes: 47 additions & 0 deletions src/services/Keys.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,53 @@ export class KeysService {
}
};

getWifBalance = async (wif: string) => {
try {
const privKey = PrivateKey.fromWif(wif);
const { data } = await axios.get<WocUtxo[]>(`${WOC_BASE_URL}/address/${privKey.toAddress()}/unspent`);
const utxos = data;
if (utxos.length === 0) return 0;
const balance = utxos.reduce((acc, u) => acc + u.value, 0);
return balance;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.log(error);
return;
}
};

sweepWif = async (wif: string) => {
try {
const privKey = PrivateKey.fromWif(wif);
const tx = new Transaction();
const outScript = new P2PKH().lock(this.bsvAddress);
tx.addOutput({ lockingScript: outScript, change: true });

const { data } = await axios.get<WocUtxo[]>(`${WOC_BASE_URL}/address/${privKey.toAddress()}/unspent`);
const utxos = data;
if (utxos.length === 0) return;
const feeModel = new SatoshisPerKilobyte(this.chromeStorageService.getCustomFeeRate());
for await (const u of utxos || []) {
tx.addInput({
sourceTransaction: await this.oneSatSPV.getTx(u.tx_hash, true),
sourceOutputIndex: u.tx_pos,
sequence: 0xffffffff,
unlockingScriptTemplate: new P2PKH().unlock(privKey),
});
}
await tx.fee(feeModel);
await tx.sign();
const response = await this.oneSatSPV.broadcast(tx);
if (response.status == 'error') return { error: response.description };
const txid = tx.id('hex');
console.log('Change sweep:', txid);
return { txid, rawtx: Utils.toHex(tx.toBinary()) };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.log(error);
}
};

generateKeysFromWifAndStoreEncrypted = async (password: string, wifs: WifKeys, isNewWallet: boolean) => {
const { passKey, salt } = await this.getPassKeyAndSalt(password, isNewWallet);
const keys = getKeysFromWifs(wifs);
Expand Down

0 comments on commit 1131ff6

Please sign in to comment.