Skip to content

Commit eca6565

Browse files
author
Hack.bg R&D
committed
test: monitor balance in bigint
1 parent 690d0cc commit eca6565

2 files changed

Lines changed: 43 additions & 41 deletions

File tree

src/sdk.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,35 @@ export function Spend (): Spend {
112112
const options = { recipient: address, sender, utxos: [utxo], asset: utxo.asset, amount, fee };
113113
const { sendSigned } = await Wasm();
114114
const { hex } = sendSigned(signer, options);
115-
return await chain.broadcast(hex);
115+
const tx = await chain.broadcast(hex);
116+
117+
// TODO: Post-broadcast validation?
118+
//function assertTxOuts (
119+
//tx: { hex: unknown, vout: unknown[] },
120+
//p2tr: string,
121+
//amount: Num,
122+
//cost: Num,
123+
//remaining?: number,
124+
//debug = console.debug,
125+
//) {
126+
////equal(tx.vout.length, 3);
127+
////debug('TX:', tx);
128+
//hasVout(isBalance, _ => `balance: program ${p2tr} must receive ${amount}`);
129+
//hasVout(isFee, _ => `fee: no deploy fee matching ${cost}`);
130+
////hasVout((x: Btc.Vout)=>x.value===remaining, v => `remaining: must be ${v}`);
131+
//return tx
132+
//function hasVout (f: Fn, msg: (v)=>string) {
133+
//if (tx.vout.filter(f).length !== 1) throw new Error(`post deploy: ${msg(tx.vout)}`);
134+
//}
135+
//function isBalance (x: Btc.Vout) {
136+
//return ((x.value===amount) && (x.scriptPubKey.address == p2tr));
137+
//}
138+
//function isFee (x: Btc.Vout) {
139+
//return x.value === cost;
140+
//}
141+
//}
142+
143+
return tx;
116144
}
117145
};
118146
return spend;

src/test.ts

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
#!/usr/bin/env -S deno run --allow-read --allow-env --allow-run --allow-write=/tmp/fadroma --allow-import=cdn.skypack.dev:443,deno.land:443 --allow-net=127.0.0.1:8941,liquidtestnet.com:443,blockstream.info:443
22
import { deepStrictEqual as equal, rejects, throws, ok } from 'node:assert';
3-
import { Base16, Fn, Test, Run, sleep } from '../../../library/index.ts';
3+
import { Base16, Fn, Async, Test, Run, sleep } from '../../../library/index.ts';
44
import Btc, { Rpc, LiquidTestnet, ElementsRegtest } from '../../Bitcoin/index.ts';
55
import * as SimplicityHL from './sdk.ts';
6+
const keypair1 = await SimplicityHL.Keypair(new Uint8Array(Array(32).fill(8)));
7+
const keypair2 = await SimplicityHL.Keypair(new Uint8Array(Array(32).fill(9)));
68
const { is, has } = Test;
7-
const { sendSigned, keypair } = await SimplicityHL.Wasm();
8-
9-
const keypair1 = keypair(new Uint8Array(Array(32).fill(8)));
10-
const keypair2 = keypair(new Uint8Array(Array(32).fill(9)));
119

1210
/** Test the SimplicityHL support in Fadroma. */
1311
export default Test(import.meta, 'SimplicityHL', TestWasm(), TestOnLocalnet(), TestOnTestnet())
@@ -34,7 +32,6 @@ export function TestWasm () {
3432
function TestSend (amount = 3000n, fee = 12000n) {
3533
return Fn.Name(`Spend ${amount} for ${fee}`, testSend);
3634
async function testSend (chain: Btc) {
37-
const debug = chain.debug || console.debug;
3835
const from = chain.P2WPKH(keypair1.publicKey()).address;
3936
const to = chain.P2WPKH(keypair2.publicKey()).address;
4037
const utxo = await chain.getUtxo(from);
@@ -124,15 +121,11 @@ function TestProgram (name: string, src: string, {
124121
argTypes = {} as Record<string, string>,
125122
witTypes = {} as Record<string, string>,
126123
/** Function that provides parameter data. */
127-
provideArgs = null as null|Fn.Returns<Fn.Async<SimplicityHL.Args>>,
124+
provideArgs = null as null|Fn.Returns<Async<SimplicityHL.Args>>,
128125
/** Function that provides witness data. */
129-
provideWits = null as null|Fn<[Uint8Array<ArrayBufferLike>], Fn.Async<object>>,
126+
provideWits = null as null|Fn<[Uint8Array<ArrayBufferLike>], Async<object>>,
130127
} = {}) {
131128

132-
const commitAmount = 1_00000000n;
133-
const redeemFee = 1e-4;
134-
const redeemAmount = 1. - redeemFee;
135-
136129
return Fn.Name(`${name} (${p2tr||'unspecified P2TR'})`, testProgram, {
137130
shouldFail, name, src, fee, cmr, p2tr, argTypes, witTypes, provideArgs, provideWits,
138131
});
@@ -160,27 +153,32 @@ function TestProgram (name: string, src: string, {
160153

161154
// Fund program from deployer:
162155
const commitSource = await chain.getUtxo(chain.P2WPKH(keypair1.publicKey()).address);
156+
const commitAmount = BigInt(commitSource.amount * 1e8) - BigInt(fee * 1e8);
163157
const commitTxid = await SimplicityHL.Spend() // TODO wrap as program.commit() ?
164158
.asset(commitSource.asset)
165159
.input(commitSource, keypair1)
166-
.output(p2tr, commitAmount)
160+
.output(program.p2tr, commitAmount)
167161
.fee(fee)
168162
.broadcast(chain);
169163

170164
// Note current recipient balance:
171165
const recipient = chain.P2WPKH(keypair1.publicKey()).address;
172-
const balance = (await chain.getBalance(recipient, 0))['bitcoin'];
166+
const recipientBalance = async (asset = 'bitcoin') =>
167+
BigInt((await chain.getBalance(recipient, 0))[asset] * 1e8);
168+
const balance = await recipientBalance();
173169

174170
// Find commit (deploy) output = redeem (spend) input:
175171
const asset = commitSource.asset;
176172
const prev = await chain.getTxInfo(commitTxid);
177-
assertTxOuts(prev, p2tr, 1, fee);
178173
const txid = prev.txid;
179174
const vout = prev.vout.filter(x=>x.scriptPubKey.address === p2tr)[0];
180175
if (!vout) throw new Error('no corresponding vout found');
181176
const utxos = [{ txid, asset, vout: vout.n, address: vout.scriptPubKey.address, amount: vout.value }];
182177

183178
// To get SIGHASH_ALL for signing, first the rest of the transaction must be specified:
179+
180+
const redeemFee = 1e-4;
181+
const redeemAmount = commitAmount - BigInt(redeemFee * 1e8);
184182
const sighashOpts = { asset, utxos, recipient, amount: redeemAmount, fee: redeemFee };
185183
const sighash = program.redeemSighash(sighashOpts);
186184
ok(sighash instanceof Uint8Array, 'sighash expected to be returned from WASM as Uint8Array')
@@ -199,31 +197,7 @@ function TestProgram (name: string, src: string, {
199197
// TX is expected to pass
200198
await chain.broadcast(redeemTx.hex);
201199
// Balance is expected to increase
202-
equal(await chain.getBalance(recipient, 0), { bitcoin: balance + redeemAmount });
200+
equal(await recipientBalance(), balance + redeemAmount);
203201
}
204202
}
205203

206-
function assertTxOuts (
207-
tx: { hex: unknown, vout: unknown[] },
208-
p2tr: string,
209-
amount: number,
210-
cost: number,
211-
remaining?: number,
212-
debug = console.debug,
213-
) {
214-
equal(tx.vout.length, 3);
215-
//debug('TX:', tx);
216-
hasVout(isBalance, _ => `balance: program ${p2tr} must receive ${amount}`);
217-
hasVout(isFee, _ => `fee: no deploy fee matching ${cost}`);
218-
//hasVout((x: Btc.Vout)=>x.value===remaining, v => `remaining: must be ${v}`);
219-
return tx
220-
function hasVout (f: Fn, msg: (v)=>string) {
221-
if (tx.vout.filter(f).length !== 1) throw new Error(`post deploy: ${msg(tx.vout)}`);
222-
}
223-
function isBalance (x: Btc.Vout) {
224-
return ((x.value===amount) && (x.scriptPubKey.address == p2tr));
225-
}
226-
function isFee (x: Btc.Vout) {
227-
return x.value === cost;
228-
}
229-
}

0 commit comments

Comments
 (0)