Pode ser que algum de vós mais experiente em Python me consiga ajudar.
Estou a tentar fazer um script em Python para extrair umas informações de uma wallet que é a Peach que tenho usado para comprar Bitcoin P2P.
O objectivo é mesmo tentar extrair as PKs das addresses desta wallet. Ou pelo menos uma PK.
Eu tenho a seed phrase e já tentei usá-la para extrair as PKs mas tudo o que consigo é uma PK em formato WIF. Não quero WIF. Quero no mesmo formato que o Bitcoin Core as mostra com o comando dumpprivkey.
Então, como ponto de partida, fui ao Github da Peach e fui tentar perceber quais as funções de interesse tanto para criar uma wallet a partir de uma seed ou para criar os backups e talvez conseguir perceber como extrair as PKs através ou do backup ou directamente através a seed phrase!
Achei alguns files de interesse com funcções que fazem o que acabei de dizer. Mas o código é TypeScript. É preciso tentar converter ese código para Python e também é preciso conhecer os detalhes das HD wallets e os passos que é necessário dar para criar as PKs e respectivas addresses. Não tenho conhecimento aprofundado de nenhuma das partes. lol.
Mas o que encontrei foi o seguinte:
https://github.com/Peach2Peach/peach-app/blob/develop/src/utils/wallet/getDescriptorSecretKey.ts
import { 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.ts
import 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;
}
};
e este:
https://github.com/Peach2Peach/peach-app/blob/develop/src/utils/file/readChunkOfFile.ts
import RNFS from "react-native-fs";
export const readChunkOfFile = (
uri: string,
chunksize: number,
index: number,
) => RNFS.read(uri, chunksize, index, "utf8");
Como nada sei sobre TypeScript, pedi ao chatGPT para converter estas funções para Python e depois, como o código nunca funciona vindo irecto do chatGPT, lá tentei fazer algusn ajustes até conseguir obter uma adress bitcoin a respectiva WIF e até o derivation path. O cóigo é este:
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))
Obtenho o seguinte output:
Wallet Info:
Address: bc1qd.........my
Key:
Como ainda não consegui extrair exactamente o que quero, o que tentei foi usar a seed phrase na Electrum e aí consigo obter todas as addresses e as respectivas PKs nos formatos que pretendo, ou seja, acho que é Base58 e/ou Bech32.
Se alguém me conseguir ajudar, agradeço. Estou a usar a bliblioteca bitcoinlib.
Edited;
Alguém no canal de Telegram da Peach me deu também uma função JavaScript mas eu nem sequer tentei usar porque me parece que a única coisa que faz é abrir o ficheiro de backup, desencriptar e mostrar o conteúdo.
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!");
})
});
Também a tentei converter para Python com o chatGPT mas obtenho sempre um erro que diz que não consegue ler o primeiro caractér UTF8 do ficheiro ou que o UTF8 está malformado ou algo assim!