Skip to content

Commit d906254

Browse files
committed
dart manual format
1 parent 7c103fb commit d906254

File tree

2 files changed

+194
-109
lines changed

2 files changed

+194
-109
lines changed

payjoin-ffi/dart/test/test_payjoin_integration_test.dart

Lines changed: 155 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ class IsScriptOwnedCallback implements payjoin.IsScriptOwned {
9292
bool callback(Uint8List script) {
9393
try {
9494
final scriptObj = bitcoin.Script(script);
95-
final address =
96-
bitcoin.Address.fromScript(scriptObj, bitcoin.Network.regtest);
95+
final address = bitcoin.Address.fromScript(
96+
scriptObj,
97+
bitcoin.Network.regtest,
98+
);
9799
// This is a hack due to toString() not being exposed by dart FFI
98100
final address_str = address.toQrUri().split(":")[1];
99101
final result = connection.call("getaddressinfo", [address_str]);
@@ -130,41 +132,58 @@ class ProcessPsbtCallback implements payjoin.ProcessPsbt {
130132
}
131133

132134
payjoin.Initialized create_receiver_context(
133-
bitcoin.Address address,
134-
String directory,
135-
payjoin.OhttpKeys ohttp_keys,
136-
InMemoryReceiverPersister persister) {
137-
var receiver = payjoin.ReceiverBuilder(address, directory, ohttp_keys)
138-
.build()
139-
.save(persister);
135+
bitcoin.Address address,
136+
String directory,
137+
payjoin.OhttpKeys ohttp_keys,
138+
InMemoryReceiverPersister persister,
139+
) {
140+
var receiver = payjoin.ReceiverBuilder(
141+
address,
142+
directory,
143+
ohttp_keys,
144+
).build().save(persister);
140145
return receiver;
141146
}
142147

143148
String build_sweep_psbt(payjoin.RpcClient sender, payjoin.PjUri pj_uri) {
144149
var outputs = <String, dynamic>{};
145150
outputs[pj_uri.address()] = 50;
146-
var psbt = jsonDecode(sender.call("walletcreatefundedpsbt", [
147-
jsonEncode([]),
148-
jsonEncode(outputs),
149-
jsonEncode(0),
150-
jsonEncode({
151-
"lockUnspents": true,
152-
"fee_rate": 10,
153-
"subtractFeeFromOutputs": [0]
154-
})
155-
]))["psbt"];
156-
return jsonDecode(sender.call("walletprocesspsbt",
157-
[psbt, jsonEncode(true), jsonEncode("ALL"), jsonEncode(false)]))["psbt"];
151+
var psbt = jsonDecode(
152+
sender.call("walletcreatefundedpsbt", [
153+
jsonEncode([]),
154+
jsonEncode(outputs),
155+
jsonEncode(0),
156+
jsonEncode({
157+
"lockUnspents": true,
158+
"fee_rate": 10,
159+
"subtractFeeFromOutputs": [0],
160+
}),
161+
]),
162+
)["psbt"];
163+
return jsonDecode(
164+
sender.call("walletprocesspsbt", [
165+
psbt,
166+
jsonEncode(true),
167+
jsonEncode("ALL"),
168+
jsonEncode(false),
169+
]),
170+
)["psbt"];
158171
}
159172

160173
List<payjoin.InputPair> get_inputs(payjoin.RpcClient rpc_connection) {
161174
var utxos = jsonDecode(rpc_connection.call("listunspent", []));
162175
List<payjoin.InputPair> inputs = [];
163176
for (var utxo in utxos) {
164-
var txin = bitcoin.TxIn(bitcoin.OutPoint(utxo["txid"], utxo["vout"]),
165-
bitcoin.Script(Uint8List.fromList([])), 0, []);
166-
var tx_out = bitcoin.TxOut(bitcoin.Amount.fromBtc(utxo["amount"]),
167-
bitcoin.Script(Uint8List.fromList(hex.decode(utxo["scriptPubKey"]))));
177+
var txin = bitcoin.TxIn(
178+
bitcoin.OutPoint(utxo["txid"], utxo["vout"]),
179+
bitcoin.Script(Uint8List.fromList([])),
180+
0,
181+
[],
182+
);
183+
var tx_out = bitcoin.TxOut(
184+
bitcoin.Amount.fromBtc(utxo["amount"]),
185+
bitcoin.Script(Uint8List.fromList(hex.decode(utxo["scriptPubKey"]))),
186+
);
168187
var psbt_in = payjoin.PsbtInput(tx_out, null, null);
169188
inputs.add(payjoin.InputPair(txin, psbt_in, null));
170189
}
@@ -173,24 +192,27 @@ List<payjoin.InputPair> get_inputs(payjoin.RpcClient rpc_connection) {
173192
}
174193

175194
Future<payjoin.PayjoinProposalReceiveSession> process_provisional_proposal(
176-
payjoin.ProvisionalProposal proposal,
177-
InMemoryReceiverPersister recv_persister) async {
195+
payjoin.ProvisionalProposal proposal,
196+
InMemoryReceiverPersister recv_persister,
197+
) async {
178198
final payjoin_proposal = proposal
179199
.finalizeProposal(ProcessPsbtCallback(receiver))
180200
.save(recv_persister);
181201
return payjoin.PayjoinProposalReceiveSession(payjoin_proposal);
182202
}
183203

184204
Future<payjoin.PayjoinProposalReceiveSession> process_wants_fee_range(
185-
payjoin.WantsFeeRange proposal,
186-
InMemoryReceiverPersister recv_persister) async {
205+
payjoin.WantsFeeRange proposal,
206+
InMemoryReceiverPersister recv_persister,
207+
) async {
187208
final wants_fee_range = proposal.applyFeeRange(1, 10).save(recv_persister);
188209
return await process_provisional_proposal(wants_fee_range, recv_persister);
189210
}
190211

191212
Future<payjoin.PayjoinProposalReceiveSession> process_wants_inputs(
192-
payjoin.WantsInputs proposal,
193-
InMemoryReceiverPersister recv_persister) async {
213+
payjoin.WantsInputs proposal,
214+
InMemoryReceiverPersister recv_persister,
215+
) async {
194216
final provisional_proposal = proposal
195217
.contributeInputs(get_inputs(receiver))
196218
.commitInputs()
@@ -199,57 +221,65 @@ Future<payjoin.PayjoinProposalReceiveSession> process_wants_inputs(
199221
}
200222

201223
Future<payjoin.PayjoinProposalReceiveSession> process_wants_outputs(
202-
payjoin.WantsOutputs proposal,
203-
InMemoryReceiverPersister recv_persister) async {
224+
payjoin.WantsOutputs proposal,
225+
InMemoryReceiverPersister recv_persister,
226+
) async {
204227
final wants_inputs = proposal.commitOutputs().save(recv_persister);
205228
return await process_wants_inputs(wants_inputs, recv_persister);
206229
}
207230

208231
Future<payjoin.PayjoinProposalReceiveSession> process_outputs_unknown(
209-
payjoin.OutputsUnknown proposal,
210-
InMemoryReceiverPersister recv_persister) async {
232+
payjoin.OutputsUnknown proposal,
233+
InMemoryReceiverPersister recv_persister,
234+
) async {
211235
final wants_outputs = proposal
212236
.identifyReceiverOutputs(IsScriptOwnedCallback(receiver))
213237
.save(recv_persister);
214238
return await process_wants_outputs(wants_outputs, recv_persister);
215239
}
216240

217241
Future<payjoin.PayjoinProposalReceiveSession> process_maybe_inputs_seen(
218-
payjoin.MaybeInputsSeen proposal,
219-
InMemoryReceiverPersister recv_persister) async {
242+
payjoin.MaybeInputsSeen proposal,
243+
InMemoryReceiverPersister recv_persister,
244+
) async {
220245
final outputs_unknown = proposal
221246
.checkNoInputsSeenBefore(CheckInputsNotSeenCallback(receiver))
222247
.save(recv_persister);
223248
return await process_outputs_unknown(outputs_unknown, recv_persister);
224249
}
225250

226251
Future<payjoin.PayjoinProposalReceiveSession> process_maybe_inputs_owned(
227-
payjoin.MaybeInputsOwned proposal,
228-
InMemoryReceiverPersister recv_persister) async {
252+
payjoin.MaybeInputsOwned proposal,
253+
InMemoryReceiverPersister recv_persister,
254+
) async {
229255
final maybe_inputs_owned = proposal
230256
.checkInputsNotOwned(IsScriptOwnedCallback(receiver))
231257
.save(recv_persister);
232258
return await process_maybe_inputs_seen(maybe_inputs_owned, recv_persister);
233259
}
234260

235261
Future<payjoin.PayjoinProposalReceiveSession> process_unchecked_proposal(
236-
payjoin.UncheckedOriginalPayload proposal,
237-
InMemoryReceiverPersister recv_persister) async {
262+
payjoin.UncheckedOriginalPayload proposal,
263+
InMemoryReceiverPersister recv_persister,
264+
) async {
238265
final unchecked_proposal = proposal
239266
.checkBroadcastSuitability(null, MempoolAcceptanceCallback(receiver))
240267
.save(recv_persister);
241268
return await process_maybe_inputs_owned(unchecked_proposal, recv_persister);
242269
}
243270

244271
Future<payjoin.ReceiveSession?> retrieve_receiver_proposal(
245-
payjoin.Initialized receiver,
246-
InMemoryReceiverPersister recv_persister,
247-
String ohttp_relay) async {
272+
payjoin.Initialized receiver,
273+
InMemoryReceiverPersister recv_persister,
274+
String ohttp_relay,
275+
) async {
248276
var agent = http.Client();
249277
var request = receiver.createPollRequest(ohttp_relay);
250-
var response = await agent.post(Uri.parse(request.request.url),
251-
headers: {"Content-Type": request.request.contentType},
252-
body: request.request.body);
278+
var response = await agent.post(
279+
Uri.parse(request.request.url),
280+
headers: {"Content-Type": request.request.contentType},
281+
body: request.request.body,
282+
);
253283
var res = receiver
254284
.processResponse(response.bodyBytes, request.clientResponse)
255285
.save(recv_persister);
@@ -265,12 +295,16 @@ Future<payjoin.ReceiveSession?> retrieve_receiver_proposal(
265295
}
266296

267297
Future<payjoin.ReceiveSession?> process_receiver_proposal(
268-
payjoin.ReceiveSession receiver,
269-
InMemoryReceiverPersister recv_persister,
270-
String ohttp_relay) async {
298+
payjoin.ReceiveSession receiver,
299+
InMemoryReceiverPersister recv_persister,
300+
String ohttp_relay,
301+
) async {
271302
if (receiver is payjoin.InitializedReceiveSession) {
272303
var res = await retrieve_receiver_proposal(
273-
receiver.inner, recv_persister, ohttp_relay);
304+
receiver.inner,
305+
recv_persister,
306+
ohttp_relay,
307+
);
274308
if (res == null) {
275309
return null;
276310
}
@@ -313,8 +347,9 @@ void main() {
313347
receiver = env.getReceiver();
314348
sender = env.getSender();
315349
var receiver_address = bitcoin.Address(
316-
jsonDecode(receiver.call("getnewaddress", [])),
317-
bitcoin.Network.regtest);
350+
jsonDecode(receiver.call("getnewaddress", [])),
351+
bitcoin.Network.regtest,
352+
);
318353
var services = payjoin.TestServices.initialize();
319354

320355
services.waitForServicesReady();
@@ -328,26 +363,35 @@ void main() {
328363
var recv_persister = InMemoryReceiverPersister("1");
329364
var sender_persister = InMemorySenderPersister("1");
330365
var session = create_receiver_context(
331-
receiver_address, directory, ohttp_keys, recv_persister);
366+
receiver_address,
367+
directory,
368+
ohttp_keys,
369+
recv_persister,
370+
);
332371
var process_response = await process_receiver_proposal(
333-
payjoin.InitializedReceiveSession(session),
334-
recv_persister,
335-
ohttp_relay);
372+
payjoin.InitializedReceiveSession(session),
373+
recv_persister,
374+
ohttp_relay,
375+
);
336376
expect(process_response, isNull);
337377

338378
// **********************
339379
// Inside the Sender:
340380
// Create a funded PSBT (not broadcasted) to address with amount given in the pj_uri
341381
var pj_uri = session.pjUri();
342382
var psbt = build_sweep_psbt(sender, pj_uri);
343-
payjoin.WithReplyKey req_ctx = payjoin.SenderBuilder(psbt, pj_uri)
344-
.buildRecommended(1000)
345-
.save(sender_persister);
346-
payjoin.RequestOhttpContext request =
347-
req_ctx.createV2PostRequest(ohttp_relay);
348-
var response = await agent.post(Uri.parse(request.request.url),
349-
headers: {"Content-Type": request.request.contentType},
350-
body: request.request.body);
383+
payjoin.WithReplyKey req_ctx = payjoin.SenderBuilder(
384+
psbt,
385+
pj_uri,
386+
).buildRecommended(1000).save(sender_persister);
387+
payjoin.RequestOhttpContext request = req_ctx.createV2PostRequest(
388+
ohttp_relay,
389+
);
390+
var response = await agent.post(
391+
Uri.parse(request.request.url),
392+
headers: {"Content-Type": request.request.contentType},
393+
body: request.request.body,
394+
);
351395
payjoin.PollingForProposal send_ctx = req_ctx
352396
.processResponse(response.bodyBytes, request.ohttpCtx)
353397
.save(sender_persister);
@@ -359,59 +403,76 @@ void main() {
359403
// GET fallback psbt
360404
payjoin.ReceiveSession? payjoin_proposal =
361405
await process_receiver_proposal(
362-
payjoin.InitializedReceiveSession(session),
363-
recv_persister,
364-
ohttp_relay);
406+
payjoin.InitializedReceiveSession(session),
407+
recv_persister,
408+
ohttp_relay,
409+
);
365410
expect(payjoin_proposal, isNotNull);
366411
expect(payjoin_proposal, isA<payjoin.PayjoinProposalReceiveSession>());
367412

368413
payjoin.PayjoinProposal proposal =
369414
(payjoin_proposal as payjoin.PayjoinProposalReceiveSession).inner;
370-
payjoin.RequestResponse request_response =
371-
proposal.createPostRequest(ohttp_relay);
415+
payjoin.RequestResponse request_response = proposal.createPostRequest(
416+
ohttp_relay,
417+
);
372418
var fallback_response = await agent.post(
373-
Uri.parse(request_response.request.url),
374-
headers: {"Content-Type": request_response.request.contentType},
375-
body: request_response.request.body);
419+
Uri.parse(request_response.request.url),
420+
headers: {"Content-Type": request_response.request.contentType},
421+
body: request_response.request.body,
422+
);
376423
proposal.processResponse(
377-
fallback_response.bodyBytes, request_response.clientResponse);
424+
fallback_response.bodyBytes,
425+
request_response.clientResponse,
426+
);
378427

379428
// **********************
380429
// Inside the Sender:
381430
// Sender checks, isngs, finalizes, extracts, and broadcasts
382431
// Replay post fallback to get the response
383-
payjoin.RequestOhttpContext ohttp_context_request =
384-
send_ctx.createPollRequest(ohttp_relay);
432+
payjoin.RequestOhttpContext ohttp_context_request = send_ctx
433+
.createPollRequest(ohttp_relay);
385434
var final_response = await agent.post(
386-
Uri.parse(ohttp_context_request.request.url),
387-
headers: {"Content-Type": ohttp_context_request.request.contentType},
388-
body: ohttp_context_request.request.body);
435+
Uri.parse(ohttp_context_request.request.url),
436+
headers: {"Content-Type": ohttp_context_request.request.contentType},
437+
body: ohttp_context_request.request.body,
438+
);
389439
var checked_payjoin_proposal_psbt = send_ctx
390440
.processResponse(
391-
final_response.bodyBytes, ohttp_context_request.ohttpCtx)
441+
final_response.bodyBytes,
442+
ohttp_context_request.ohttpCtx,
443+
)
392444
.save(sender_persister);
393445
expect(checked_payjoin_proposal_psbt, isNotNull);
394-
var checked_payjoin_proposal_psbt_inner = (checked_payjoin_proposal_psbt
395-
as payjoin.ProgressPollingForProposalTransitionOutcome)
396-
.inner;
397-
var payjoin_psbt = jsonDecode(sender.call("walletprocesspsbt",
398-
[checked_payjoin_proposal_psbt_inner.serializeBase64()]))["psbt"];
399-
var final_psbt = jsonDecode(sender
400-
.call("finalizepsbt", [payjoin_psbt, jsonEncode(false)]))["psbt"];
446+
var checked_payjoin_proposal_psbt_inner =
447+
(checked_payjoin_proposal_psbt
448+
as payjoin.ProgressPollingForProposalTransitionOutcome)
449+
.inner;
450+
var payjoin_psbt = jsonDecode(
451+
sender.call("walletprocesspsbt", [
452+
checked_payjoin_proposal_psbt_inner.serializeBase64(),
453+
]),
454+
)["psbt"];
455+
var final_psbt = jsonDecode(
456+
sender.call("finalizepsbt", [payjoin_psbt, jsonEncode(false)]),
457+
)["psbt"];
401458
var payjoin_tx = bitcoin.Psbt.deserializeBase64(final_psbt).extractTx();
402-
sender.call("sendrawtransaction",
403-
[jsonEncode(hex.encode(payjoin_tx.serialize()))]);
459+
sender.call("sendrawtransaction", [
460+
jsonEncode(hex.encode(payjoin_tx.serialize())),
461+
]);
404462

405463
// Check resulting transaction and balances
406-
var network_fees =
407-
bitcoin.Psbt.deserializeBase64(final_psbt).fee().toBtc();
464+
var network_fees = bitcoin.Psbt.deserializeBase64(
465+
final_psbt,
466+
).fee().toBtc();
408467
// Sender sent the entire value of their utxo to the receiver (minus fees)
409468
expect(payjoin_tx.input().length, 2);
410469
expect(payjoin_tx.output().length, 1);
411470
expect(
412-
jsonDecode(receiver.call("getbalances", []))["mine"]
413-
["untrusted_pending"],
414-
100 - network_fees);
471+
jsonDecode(
472+
receiver.call("getbalances", []),
473+
)["mine"]["untrusted_pending"],
474+
100 - network_fees,
475+
);
415476
expect(jsonDecode(sender.call("getbalance", [])), 0.0);
416477
});
417478
});

0 commit comments

Comments
 (0)