Skip to content

Commit

Permalink
prefer library functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
bdemann committed May 15, 2024
1 parent e7a93ec commit 723b5fe
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 51 deletions.
61 changes: 14 additions & 47 deletions examples/basic_bitcoin/src/bitcoin_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,23 +255,18 @@ async function signTransaction(
SIG_HASH_TYPE
);

const signature = Uint8Array.from(
await signer(keyName, derivationPath, sighash)
);

// Convert signature to DER.
const derSignature = sec1ToDer(signature);
const signature = await signer(keyName, derivationPath, sighash);

const sigWithHashType = Uint8Array.from([
...derSignature,
const encodedSig = bitcoin.script.signature.encode(
Buffer.from(signature),
SIG_HASH_TYPE
);

const scriptSig = bitcoin.script.compile([
encodedSig,
Buffer.from(ownPublicKey)
]);
const scriptSig = Uint8Array.from([
sigWithHashType.length,
...sigWithHashType,
ownPublicKey.length,
...ownPublicKey
]);

transaction.setInputScript(i, Buffer.from(scriptSig));
}

Expand Down Expand Up @@ -299,40 +294,12 @@ function mockSigner(
_derivationPath: Uint8Array[],
_messageHash: Uint8Array
): Uint8Array {
return new Uint8Array(64);
}

// Converts a SEC1 ECDSA signature to the DER format.
function sec1ToDer(sec1Signature: Uint8Array): Uint8Array {
let r: Uint8Array;

if ((sec1Signature[0] & 0x80) !== 0) {
// r is negative. Prepend a zero byte.
const tmp = Uint8Array.from([0x00, ...sec1Signature.slice(0, 32)]);
r = tmp;
} else {
// r is positive.
r = sec1Signature.slice(0, 32);
}

let s: Uint8Array;

if ((sec1Signature[32] & 0x80) !== 0) {
// s is negative. Prepend a zero byte.
const tmp = Uint8Array.from([0x00, ...sec1Signature.slice(32)]);
s = tmp;
} else {
// s is positive.
s = sec1Signature.slice(32);
let array = new Uint8Array(64);
// bitcoin.script.signature.encode threw away most of the signature when it was all 0's so we need to fill it up with something
for (let i = 0; i < 64; i++) {
array[i] = i + 1;
}

// Convert signature to DER.
return Uint8Array.from([
...[0x30, 4 + r.length + s.length, 0x02, r.length],
...r,
...[0x02, s.length],
...s
]);
return array;
}

export function determineNetwork(network: BitcoinNetwork): Network {
Expand Down
14 changes: 14 additions & 0 deletions examples/basic_bitcoin/test/bitcoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ export function createWallet(name: string) {
);
}

export function getMempoolCount(): number {
const mempool = execSync(
`.bitcoin/bin/bitcoin-cli -conf=$(pwd)/.bitcoin.conf getrawmempool true`
)
.toString()
.trim();

const mempoolObj = JSON.parse(mempool);

const transactionCount = Object.keys(mempoolObj).length;

return transactionCount;
}

export function getTransaction(txid: string): Transaction {
return Transaction.fromHex(getTxHex(txid));
}
Expand Down
25 changes: 21 additions & 4 deletions examples/basic_bitcoin/test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createWallet,
generate,
generateToAddress,
getMempoolCount,
getTotalOutput,
getTransaction
} from './bitcoin';
Expand Down Expand Up @@ -129,10 +130,12 @@ export function getTests(canisterId: string): Test[] {
console.info(lastTx);
}
},
// TODO it might be nice to look at the mempool and wait for a transaction to show up before generating any blocks
{ name: 'wait for transaction to appear in mempool', wait: 15_000 },
{
name: '',
name: 'wait for transaction to appear in mempool',
prep: waitForMempool
},
{
name: 'mine a block with the latest transaction',
prep: async () => {
generate(1);
}
Expand Down Expand Up @@ -207,7 +210,10 @@ export function getTests(canisterId: string): Test[] {
console.info(lastTx);
}
},
{ name: 'wait for transaction to appear in mempool', wait: 15_000 },
{
name: 'wait for transaction to appear in mempool',
prep: waitForMempool
},
{
name: 'mine a block for the latest transaction',
prep: async () => {
Expand Down Expand Up @@ -326,3 +332,14 @@ function checkUtxos(utxos: Utxo[]): boolean {
(utxo) => utxo.value === SINGLE_BLOCK_REWARD && utxo.outpoint.vout === 0
);
}

async function waitForMempool() {
for (let i = 0; i < 60; i++) {
if (getMempoolCount() > 0) {
console.info('done waiting');
return;
}
await new Promise((resolve) => setTimeout(resolve, 1_000));
}
throw new Error('Timeout: Transaction was not added to the mempool');
}

0 comments on commit 723b5fe

Please sign in to comment.