Hello.
So, this Peach piece of software to purchase Bitcoin via P2P. It has a non-custodial HD wallet. But as far as I know, it doesn't allow you to see your Bitcoin addresses and PKs.
It allows you to backup the wallet with an encrypted file.
So, I tried 2 things:
1 - Try to get the PKs out of the seed prase
2 - Try to check if the backup file would have the PKs in plain text after decryption
Not needed to say that I couldn't make any of them to work, at least to get the PKs like Bitcoin Core shows when we use
dumpprivkey, which if I'm not mistaken, is the random number in hex format and base58 enconded.
As a starting point I went to Peach Github and tried to figure out which functions I coul be interested in. I found a couple.
https://github.com/Peach2Peach/peach-app/blob/develop/src/utils/wallet/getDescriptorSecretKey.tsimport { DescriptorSecretKey, Mnemonic } from "bdk-rn";
import { Network, WordCount } from "bdk-rn/lib/lib/enums";
export const getDescriptorSecretKey = async (
network: Network,
seedphrase?: string,
) => {
let mnemonic = new Mnemonic();
if (seedphrase) {
mnemonic = await mnemonic.fromString(seedphrase);
} else {
mnemonic = await mnemonic.create(WordCount.WORDS12);
}
return new DescriptorSecretKey().create(network, mnemonic);
};
https://github.com/Peach2Peach/peach-app/blob/develop/src/utils/file/writeFile.tsimport RNFS from "react-native-fs";
import { encrypt } from "../crypto/encrypt";
import { error } from "../log/error";
import { info } from "../log/info";
export const writeFile = async (
path: string,
content: string,
password?: string,
): Promise => {
info(password ? "Writing encrypted file" : "Writing file", path);
let encrypted;
try {
if (password) {
encrypted = encrypt(content, password);
} else {
encrypted = content;
}
} catch (e) {
error("Data could not be encrypted", e);
return false;
}
try {
await RNFS.writeFile(RNFS.DocumentDirectoryPath + path, encrypted, "utf8");
return true;
} catch (e) {
error("File could not be written", e);
return false;
}
};
And also:
https://github.com/Peach2Peach/peach-app/blob/develop/src/utils/file/readChunkOfFile.tsimport RNFS from "react-native-fs";
export const readChunkOfFile = (
uri: string,
chunksize: number,
index: number,
) => RNFS.read(uri, chunksize, index, "utf8");
I know nothing about TypeScript and my Python knowledge is also quite limited. And I also don't know all details and aspects of HD wallets, derivation paths, etc, so I went for chatGPT for some help.
I already knew about bitcoinlib python library so I asked chatGPT to use that library and after some adjustments I got one of the codes working for situation 1 where I provide the seed and I get the keys out.
However, what the code gives me is an extended private key, as far as I can tell. And that's not what I'm looking for.
This is the code I got working and returning the zrpv key:
from bitcoinlib.wallets import Wallet, wallet_create_or_open
from bitcoinlib.wallets import wallet_delete_if_exists
import asyncio
async def get_descriptor_secret_key(network: str, seedphrase: str = None,
name='My Wallet'):
delete_wallet(name)
if seedphrase:
# Use the provided seed phrase to generate a wallet
wallet = Wallet.create(name=name, keys=seedphrase,
network=network, witness_type='segwit')
else:
# Generate a new wallet with a new seed phrase
wallet = wallet_create_or_open(name, witness_type='segwit',
network=network)
# Print wallet info
print("Wallet Info:")
print("Address:", wallet.new_key().address)
print("Key:", wallet.new_key())
# print("Descriptor:", wallet.descriptor)
return wallet
def delete_wallet(name="My Wallet"):
try:
wallet_delete_if_exists(name)
print(f"Wallet '{name}' was deleted.")
except Exception as e:
print(f"Faile to delete wallet '{name}': {str(e)}")
# Define the network ('bitcoin' or 'testnet')
network_name = 'bitcoin'
# Optionally, provide a seed phrase
seed_phrase = "word1 word1 word1 word1 word1 word1 word1 word1 word1 word1 word1 word1"
# Example seed phrase
asyncio.run(get_descriptor_secret_key(network_name, seed_phrase))
The output I get from this script is:
Wallet 'My Wallet' was deleted.
Wallet Info:
Address: bc1qd.........my
Key:
As a last resort, I imported the seed phrase into Electrum and from there, I can get all the PKs of the wallet. So, what do I need to change to get the keys in Base58 format? Or what can I do to achieve my goal?
Edited;
There was someone that gave me a JavaScript code but I don't know how to work with JavaScript and I also tried to convert his function to Python but I got some UTF8 encoding issue that I didn't spend too much time trying to fix.
const CryptoJS = require('crypto-js');
const fs = require('fs');
fs.readFile('./peach-account.json.enc', 'utf8', function(err, data) {
const res = CryptoJS.AES.decrypt(data, "").toString(CryptoJS.enc.Utf8);
fs.writeFile('./peach-account.json', res, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
})
});