-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
623 lines (601 loc) · 32.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script src="https://supertestnet.github.io/bitcoin-chess/js/bitcoinjs-lib.js"></script>
<script src="https://supertestnet.github.io/blind-sig-js/blindSigJS.js"></script>
<script src="https://cdn.jsdelivr.net/gh/6502/sha256@main/sha256.js"></script>
<script>var SHA256 = string_or_uint8array => bytesToHex( sha256( string_or_uint8array ) );</script>
<script src="https://bundle.run/noble-secp256k1@1.2.14"></script>
<script src="https://bundle.run/buffer@6.0.3"></script>
<script>var Buffer = buffer.Buffer;</script>
<style>
* {
box-sizing: border-box;
font-size: 1.15rem;
font-family: Arial, sans-serif;
}
html {
max-width: 800px;
padding: 3rem 1rem;
margin: auto;
line-height: 1.25;
padding: 0;
}
body {
margin: 3rem 1rem;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.5rem;
}
input {
line-height: 1.25;
width: 100%;
height: 1.8rem;
font-size: 1.15rem;
border: 1px solid grey;
}
@media screen and (max-width: 600px) {
}
</style>
<script>
var $ = document.querySelector.bind( document );
var $$ = document.querySelectorAll.bind( document );
var url_params = new URLSearchParams( window.location.search );
var url_keys = url_params.keys();
var $_GET = {}
for ( var key of url_keys ) $_GET[ key ] = url_params.get( key );
</script>
<script>
function getData( url ) {
return new Promise( async function( resolve, reject ) {
function inner_get( url ) {
var xhttp = new XMLHttpRequest();
xhttp.open( "GET", url, true );
xhttp.send();
return xhttp;
}
var data = inner_get( url );
data.onerror = function( e ) {
resolve( "error" );
}
async function isResponseReady() {
return new Promise( function( resolve2, reject ) {
if ( !data.responseText || data.readyState != 4 ) {
setTimeout( async function() {
var msg = await isResponseReady();
resolve2( msg );
}, 1 );
} else {
resolve2( data.responseText );
}
});
}
var returnable = await isResponseReady();
resolve( returnable );
});
}
function isValidHex( h ) {
if ( !h ) return;
var length = h.length;
if ( length % 2 ) return;
try {
var a = BigInt( "0x" + h, "hex" );
} catch( e ) {
return;
}
var unpadded = a.toString( 16 );
var padding = [];
var i; for ( i=0; i<length; i++ ) padding.push( 0 );
padding = padding.join( "" );
padding = padding + unpadded.toString();
padding = padding.slice( -Math.abs( length ) );
return ( padding === h );
}
async function postData( url, json, content_type = "", apikey = "" ) {
var rtext = "";
function inner_post( url, json, content_type = "", apikey = "" ) {
var xhttp = new XMLHttpRequest();
xhttp.open( "POST", url, true );
if ( content_type ) {
xhttp.setRequestHeader( `Content-Type`, content_type );
}
if ( apikey ) {
xhttp.setRequestHeader( `X-Api-Key`, apikey );
}
xhttp.send( json );
return xhttp;
}
var data = inner_post( url, json, content_type, apikey );
data.onerror = function( e ) {
rtext = "error";
}
async function isResponseReady() {
return new Promise( function( resolve, reject ) {
if ( rtext == "error" ) {
resolve( rtext );
}
if ( !data.responseText || data.readyState != 4 ) {
setTimeout( async function() {
var msg = await isResponseReady();
resolve( msg );
}, 50 );
} else {
resolve( data.responseText );
}
});
}
var returnable = await isResponseReady();
return returnable;
}
var hexToBytes = hex => Uint8Array.from( hex.match( /.{1,2}/g ).map( byte => parseInt( byte, 16 ) ) );
var bytesToHex = bytes => bytes.reduce( ( str, byte ) => str + byte.toString( 16 ).padStart( 2, "0" ), "" );
function getCompressedPubkeyHexFromUncompressedPubkeyHex( pubkeyhex ) {
return bitcoinjs.ECPair.fromPublicKey( Buffer.from( pubkeyhex, "hex" ) ).publicKey.toString( "hex" );
}
function hexToText( hex ) {
var bytes = new Uint8Array(Math.ceil(hex.length / 2));
for (var i = 0; i < hex.length; i++) bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
var text = new TextDecoder().decode( bytes );
return text;
}
</script>
</head>
<body>
<p>Open your browser console to see some cool stuff</p>
<script>
(async () => {
// Step 1 Create a 32 byte secret (this will be called r later in these steps)
var secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
// Step 2 Get a keyset id
var keysets = await getData( `https://testnut.cashu.space/v1/keysets` );
keysets = JSON.parse( keysets )[ "keysets" ];
var keyset;
keysets.every( item => {if ( isValidHex( item.id ) && item.active ) {keyset = item.id;return;} return true;});
console.log( keyset );
// Step 3 Get mint's pubkey (“use the pubkey for the amount...you're minting”)
var pubkeys = await getData( `https://testnut.cashu.space/v1/keys/${keyset}` );
pubkeys = JSON.parse( pubkeys )[ "keysets" ][ 0 ][ "keys" ];
var amount_i_want = 256;
var mint_pubkey = pubkeys[ amount_i_want ];
mint_pubkey = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( mint_pubkey ) );
// Step 4 Query for an invoice
var invoice_data = await postData( `https://testnut.cashu.space/v1/mint/quote/bolt11`, JSON.stringify({"amount": amount_i_want, "unit": "sat"}), "application/json" );
invoice_data = JSON.parse( invoice_data );
var quote_id = invoice_data[ "quote" ];
var invoice = invoice_data[ "request" ];
// Step 5 Pay the invoice [on testnut I don’t need to because they are marked paid automatically, but I can still poll to see if it is paid]
var is_paid_info = await getData( `https://testnut.cashu.space/v1/mint/quote/bolt11/${quote_id}` );
is_paid = JSON.parse( is_paid_info )[ "paid" ];
if ( !is_paid ) return console.log( "is paid, right?", is_paid );
// Step 6 Query for a blinded signature aka C_
var message = new blindSigJS.bsjMsg();
var B_ = await message.createBlindedMessageFromString( secret_for_message );
var B_hex = blindSigJS.ecPointToHex( B_ );
var sig_request = {
"quote": quote_id,
"outputs": [{
"amount": amount_i_want,
"id": keyset,
"B_": B_hex,
}],
}
var blinded_sigs = await postData( `https://testnut.cashu.space/v1/mint/bolt11`, JSON.stringify( sig_request ), "application/json" );
var blinded_sig = JSON.parse( blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "blinded_sig:", blinded_sig );
var C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( blinded_sig ) );
var {C, secret} = message.unblindSignature( C_, mint_pubkey );
var compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( C ) );
var input = {
id: keyset,
amount: amount_i_want,
secret: secret_for_message,
C: compressed_C,
}
//swap a second time
var secret_for_message_2 = bytesToHex( blindSigJS.getRand( 32 ) );
var message_2 = new blindSigJS.bsjMsg();
var second_B_ = await message_2.createBlindedMessageFromString( secret_for_message_2 );
var second_output_B_hex = blindSigJS.ecPointToHex( second_B_ );
var second_output = {
"amount": amount_i_want,
"id": keyset,
"B_": second_output_B_hex,
}
var swap_data = {
"inputs": [input],
"outputs": [second_output],
}
var new_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( swap_data ), "application/json" );
var new_blinded_sig = JSON.parse( new_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "new blinded_sig:", new_blinded_sig );
var new_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( new_blinded_sig ) );
var {C, secret} = message_2.unblindSignature( new_C_, mint_pubkey );
var new_C = C;
var new_secret = secret;
var new_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( new_C ) );
var new_input = {
id: keyset,
amount: amount_i_want,
secret: secret_for_message_2,
C: new_compressed_C,
}
//swap a third time
var secret_for_message_3 = bytesToHex( blindSigJS.getRand( 32 ) );
var message_3 = new blindSigJS.bsjMsg();
var third_B_ = await message_3.createBlindedMessageFromString( secret_for_message_3 );
var third_output_B_hex = blindSigJS.ecPointToHex( third_B_ );
var third_output = {
"amount": amount_i_want,
"id": keyset,
"B_": third_output_B_hex,
}
var third_swap_data = {
"inputs": [new_input],
"outputs": [third_output],
}
var yet_more_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( third_swap_data ), "application/json" );
var yet_another_blinded_sig = JSON.parse( yet_more_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "yet_another_blinded_sig:", yet_another_blinded_sig );
var third_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( yet_another_blinded_sig ) );
var {C, secret} = message_3.unblindSignature( third_C_, mint_pubkey );
var third_C = C;
var third_secret = secret;
var third_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( third_C ) );
var third_input = {
id: keyset,
amount: amount_i_want,
secret: secret_for_message_3,
C: third_compressed_C,
}
//swap using p2pk
console.log( "now I'll try with p2pk" );
var nonce_for_message_4 = bytesToHex( blindSigJS.getRand( 16 ) );
var privkey_for_message_4 = bytesToHex( nobleSecp256k1.utils.randomPrivateKey() );
var pubkey_for_message_4 = nobleSecp256k1.getPublicKey( privkey_for_message_4, true );
var secret_for_message_4 = [
"P2PK",
{
"nonce": nonce_for_message_4,
"data": pubkey_for_message_4,
}
];
secret_for_message_4 = JSON.stringify( secret_for_message_4 );
var message_4 = new blindSigJS.bsjMsg();
var fourth_B_ = await message_4.createBlindedMessageFromString( secret_for_message_4 );
var fourth_output_B_hex = blindSigJS.ecPointToHex( fourth_B_ );
var fourth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": fourth_output_B_hex,
}
var fourth_swap_data = {
"inputs": [third_input],
"outputs": [fourth_output],
}
var fourth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( fourth_swap_data ), "application/json" );
var fourth_blinded_sig = JSON.parse( fourth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "fourth_blinded_sig:", fourth_blinded_sig );
var fourth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( fourth_blinded_sig ) );
var {C, secret} = message_4.unblindSignature( fourth_C_, mint_pubkey );
var fourth_C = C;
var fourth_secret = secret;
var fourth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( fourth_C ) );
var msghash = SHA256( secret_for_message_4 );
var sig = await nobleSecp256k1.schnorr.sign( msghash, privkey_for_message_4 );
var fourth_input = {
id: keyset,
amount: amount_i_want,
secret: secret_for_message_4,
C: fourth_compressed_C,
witness: JSON.stringify({
"signatures":
[
sig
]
})
}
console.log( "p2pk worked!" );
//swap a fifth time
var secret_for_message_5 = bytesToHex( blindSigJS.getRand( 32 ) );
var message_5 = new blindSigJS.bsjMsg();
var fifth_B_ = await message_5.createBlindedMessageFromString( secret_for_message_5 );
var fifth_output_B_hex = blindSigJS.ecPointToHex( fifth_B_ );
var fifth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": fifth_output_B_hex,
}
var fifth_swap_data = {
"inputs": [fourth_input],
"outputs": [fifth_output],
}
var fifth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( fifth_swap_data ), "application/json" );
var fifth_blinded_sig = JSON.parse( fifth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "fifth_blinded_sig:", fifth_blinded_sig );
var fifth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( fifth_blinded_sig ) );
var {C, secret} = message_5.unblindSignature( fifth_C_, mint_pubkey );
var fifth_C = C;
var fifth_secret = secret;
var fifth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( fifth_C ) );
var fifth_input = {
id: keyset,
amount: amount_i_want,
secret: secret_for_message_5,
C: fifth_compressed_C,
}
//swap a sixth time
var sixth_secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
var sixth_message = new blindSigJS.bsjMsg();
var sixth_B_ = await sixth_message.createBlindedMessageFromString( sixth_secret_for_message );
var sixth_output_B_hex = blindSigJS.ecPointToHex( sixth_B_ );
var sixth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": sixth_output_B_hex,
}
var sixth_swap_data = {
"inputs": [fifth_input],
"outputs": [sixth_output],
}
var sixth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( sixth_swap_data ), "application/json" );
var sixth_blinded_sig = JSON.parse( sixth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "sixth_blinded_sig:", sixth_blinded_sig );
var sixth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( sixth_blinded_sig ) );
var {C, secret} = sixth_message.unblindSignature( sixth_C_, mint_pubkey );
var sixth_C = C;
var sixth_secret = secret;
var sixth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( sixth_C ) );
var sixth_input = {
id: keyset,
amount: amount_i_want,
secret: sixth_secret_for_message,
C: sixth_compressed_C,
}
//swap using p2pk and sighash_all
console.log( "now I'll try p2pk with sighash_all" );
var seventh_nonce_for_message = bytesToHex( blindSigJS.getRand( 16 ) );
var seventh_privkey_for_message = bytesToHex( nobleSecp256k1.utils.randomPrivateKey() );
var seventh_pubkey_for_message = nobleSecp256k1.getPublicKey( seventh_privkey_for_message, true );
var seventh_secret_for_message = [
"P2PK",
{
"nonce": seventh_nonce_for_message,
"data": seventh_pubkey_for_message,
"tags": [ [ "sigflag", "SIG_ALL" ] ],
}
];
seventh_secret_for_message = JSON.stringify( seventh_secret_for_message );
var seventh_message = new blindSigJS.bsjMsg();
var seventh_B_ = await seventh_message.createBlindedMessageFromString( seventh_secret_for_message );
var seventh_output_B_hex = blindSigJS.ecPointToHex( seventh_B_ );
var seventh_output = {
"amount": amount_i_want,
"id": keyset,
"B_": seventh_output_B_hex,
}
var seventh_swap_data = {
"inputs": [sixth_input],
"outputs": [seventh_output],
}
var seventh_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( seventh_swap_data ), "application/json" );
var seventh_blinded_sig = JSON.parse( seventh_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "seventh_blinded_sig:", seventh_blinded_sig );
var seventh_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( seventh_blinded_sig ) );
var {C, secret} = seventh_message.unblindSignature( seventh_C_, mint_pubkey );
var seventh_C = C;
var seventh_secret = secret;
var seventh_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( seventh_C ) );
var msghash = SHA256( seventh_secret_for_message );
var seventh_sig = await nobleSecp256k1.schnorr.sign( msghash, seventh_privkey_for_message );
var seventh_input = {
id: keyset,
amount: amount_i_want,
secret: seventh_secret_for_message,
C: seventh_compressed_C,
witness: JSON.stringify({
"signatures":
[
seventh_sig
]
})
}
console.log( "p2pk with sighash_all worked!" );
//swap an eighth time
var eighth_secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
var eighth_message = new blindSigJS.bsjMsg();
var eighth_B_ = await eighth_message.createBlindedMessageFromString( eighth_secret_for_message );
var eighth_output_B_hex = blindSigJS.ecPointToHex( eighth_B_ );
var msghash = SHA256( hexToBytes( eighth_output_B_hex ) );
var eighth_output_sig = await nobleSecp256k1.schnorr.sign( msghash, seventh_privkey_for_message );
var eighth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": eighth_output_B_hex,
"witness": JSON.stringify({
"signatures":
[
eighth_output_sig
]
})
}
var eighth_swap_data = {
"inputs": [seventh_input],
"outputs": [eighth_output],
}
var eighth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( eighth_swap_data ), "application/json" );
var eighth_blinded_sig = JSON.parse( eighth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "eighth_blinded_sig:", eighth_blinded_sig );
var eighth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( eighth_blinded_sig ) );
var {C, secret} = eighth_message.unblindSignature( eighth_C_, mint_pubkey );
var eighth_C = C;
var eighth_secret = secret;
var eighth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( eighth_C ) );
var eighth_input = {
id: keyset,
amount: amount_i_want,
secret: eighth_secret_for_message,
C: eighth_compressed_C,
}
//swap a ninth time
var ninth_secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
var ninth_message = new blindSigJS.bsjMsg();
var ninth_B_ = await ninth_message.createBlindedMessageFromString( ninth_secret_for_message );
var ninth_output_B_hex = blindSigJS.ecPointToHex( ninth_B_ );
var ninth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": ninth_output_B_hex,
}
var ninth_swap_data = {
"inputs": [eighth_input],
"outputs": [ninth_output],
}
var ninth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( ninth_swap_data ), "application/json" );
var ninth_blinded_sig = JSON.parse( ninth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "ninth_blinded_sig:", ninth_blinded_sig );
var ninth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( ninth_blinded_sig ) );
var {C, secret} = ninth_message.unblindSignature( ninth_C_, mint_pubkey );
var ninth_C = C;
var ninth_secret = secret;
var ninth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( ninth_C ) );
var ninth_input = {
id: keyset,
amount: amount_i_want,
secret: ninth_secret_for_message,
C: ninth_compressed_C,
}
//swap using multisig
console.log( "now I'll try with multisig" );
var tenth_nonce_for_message = bytesToHex( blindSigJS.getRand( 16 ) );
var tenth_privkey_for_message = bytesToHex( nobleSecp256k1.utils.randomPrivateKey() );
var tenth_pubkey_for_message = nobleSecp256k1.getPublicKey( tenth_privkey_for_message, true );
var tenth_privkey_2_for_message = bytesToHex( nobleSecp256k1.utils.randomPrivateKey() );
var tenth_pubkey_2_for_message = nobleSecp256k1.getPublicKey( tenth_privkey_2_for_message, true );
var tenth_privkey_3_for_message = bytesToHex( nobleSecp256k1.utils.randomPrivateKey() );
var tenth_pubkey_3_for_message = nobleSecp256k1.getPublicKey( tenth_privkey_3_for_message, true );
var tenth_secret_for_message = [
"P2PK",
{
"nonce": tenth_nonce_for_message,
"data": tenth_pubkey_for_message,
"tags": [
[ "sigflag", "SIG_ALL" ],
[ "n_sigs", "2" ],
[ "pubkeys", tenth_pubkey_2_for_message, tenth_pubkey_3_for_message ],
],
}
];
tenth_secret_for_message = JSON.stringify( tenth_secret_for_message );
var tenth_message = new blindSigJS.bsjMsg();
var tenth_B_ = await tenth_message.createBlindedMessageFromString( tenth_secret_for_message );
var tenth_output_B_hex = blindSigJS.ecPointToHex( tenth_B_ );
var tenth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": tenth_output_B_hex,
}
var tenth_swap_data = {
"inputs": [ninth_input],
"outputs": [tenth_output],
}
var tenth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( tenth_swap_data ), "application/json" );
var tenth_blinded_sig = JSON.parse( tenth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "tenth_blinded_sig:", tenth_blinded_sig );
var tenth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( tenth_blinded_sig ) );
var {C, secret} = tenth_message.unblindSignature( tenth_C_, mint_pubkey );
var tenth_C = C;
var tenth_secret = secret;
var tenth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( tenth_C ) );
var msghash = SHA256( tenth_secret_for_message );
var tenth_sig = await nobleSecp256k1.schnorr.sign( msghash, tenth_privkey_for_message );
var tenth_sig_2 = await nobleSecp256k1.schnorr.sign( msghash, tenth_privkey_2_for_message );
var tenth_input = {
id: keyset,
amount: amount_i_want,
secret: tenth_secret_for_message,
C: tenth_compressed_C,
witness: JSON.stringify({
"signatures":
[
tenth_sig,
tenth_sig_2,
]
})
}
console.log( "multisig worked!" );
//swap an eleventh time
var eleventh_secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
var eleventh_message = new blindSigJS.bsjMsg();
var eleventh_B_ = await eleventh_message.createBlindedMessageFromString( eleventh_secret_for_message );
var eleventh_output_B_hex = blindSigJS.ecPointToHex( eleventh_B_ );
var msghash = SHA256( hexToBytes( eleventh_output_B_hex ) );
var eleventh_output_sig = await nobleSecp256k1.schnorr.sign( msghash, tenth_privkey_for_message );
var eleventh_output_sig_2 = await nobleSecp256k1.schnorr.sign( msghash, tenth_privkey_2_for_message );
var eleventh_output = {
"amount": amount_i_want,
"id": keyset,
"B_": eleventh_output_B_hex,
"witness": JSON.stringify({
"signatures":
[
eleventh_output_sig,
eleventh_output_sig_2
]
})
}
var eleventh_swap_data = {
"inputs": [tenth_input],
"outputs": [eleventh_output],
}
var eleventh_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( eleventh_swap_data ), "application/json" );
var eleventh_blinded_sig = JSON.parse( eleventh_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "eleventh_blinded_sig:", eleventh_blinded_sig );
var eleventh_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( eleventh_blinded_sig ) );
var {C, secret} = eleventh_message.unblindSignature( eleventh_C_, mint_pubkey );
var eleventh_C = C;
var eleventh_secret = secret;
var eleventh_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( eleventh_C ) );
var eleventh_input = {
id: keyset,
amount: amount_i_want,
secret: eleventh_secret_for_message,
C: eleventh_compressed_C,
}
//swap a twelfth time
var twelfth_secret_for_message = bytesToHex( blindSigJS.getRand( 32 ) );
var twelfth_message = new blindSigJS.bsjMsg();
var twelfth_B_ = await twelfth_message.createBlindedMessageFromString( twelfth_secret_for_message );
var twelfth_output_B_hex = blindSigJS.ecPointToHex( twelfth_B_ );
var twelfth_output = {
"amount": amount_i_want,
"id": keyset,
"B_": twelfth_output_B_hex,
}
var twelfth_swap_data = {
"inputs": [eleventh_input],
"outputs": [twelfth_output],
}
var twelfth_blinded_sigs = await postData( `https://testnut.cashu.space/v1/swap`, JSON.stringify( twelfth_swap_data ), "application/json" );
var twelfth_blinded_sig = JSON.parse( twelfth_blinded_sigs )[ "signatures" ][ 0 ][ "C_" ];
console.log( "twelfth_blinded_sig:", twelfth_blinded_sig );
var twelfth_C_ = nobleSecp256k1.Point.fromCompressedHex( hexToBytes( twelfth_blinded_sig ) );
var {C, secret} = twelfth_message.unblindSignature( twelfth_C_, mint_pubkey );
var twelfth_C = C;
var twelfth_secret = secret;
var twelfth_compressed_C = getCompressedPubkeyHexFromUncompressedPubkeyHex( blindSigJS.ecPointToHex( twelfth_C ) );
var twelfth_input = {
id: keyset,
amount: amount_i_want,
secret: twelfth_secret_for_message,
C: twelfth_compressed_C,
}
console.log( "twelfth_input:", twelfth_input );
})();
</script>
</body>
</html>