@bennyblader/ddk-rn 0.3.10 → 0.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cpp/ddk_ffi.cpp CHANGED
@@ -133,6 +133,13 @@ extern "C" {
133
133
  uint64_t callback_data,
134
134
  UniffiForeignFutureStructVoid result
135
135
  );
136
+ RustBuffer uniffi_ddk_ffi_fn_func_add_signature_to_transaction(
137
+ RustBuffer tx,
138
+ RustBuffer signature,
139
+ RustBuffer pubkey,
140
+ uint32_t input_index,
141
+ RustCallStatus *uniffi_out_err
142
+ );
136
143
  RustBuffer uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed(
137
144
  RustBuffer mnemonic,
138
145
  RustBuffer passphrase,
@@ -508,6 +515,8 @@ extern "C" {
508
515
  /*handle*/ uint64_t handle,
509
516
  RustCallStatus *uniffi_out_err
510
517
  );
518
+ uint16_t uniffi_ddk_ffi_checksum_func_add_signature_to_transaction(
519
+ );
511
520
  uint16_t uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed(
512
521
  );
513
522
  uint16_t uniffi_ddk_ffi_checksum_func_create_cet(
@@ -2094,6 +2103,14 @@ NativeDdkFfi::NativeDdkFfi(
2094
2103
  return this->cpp_uniffi_internal_fn_func_ffi__arraybuffer_to_string(rt, thisVal, args, count);
2095
2104
  }
2096
2105
  );
2106
+ props["ubrn_uniffi_ddk_ffi_fn_func_add_signature_to_transaction"] = jsi::Function::createFromHostFunction(
2107
+ rt,
2108
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_ddk_ffi_fn_func_add_signature_to_transaction"),
2109
+ 4,
2110
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) -> jsi::Value {
2111
+ return this->cpp_uniffi_ddk_ffi_fn_func_add_signature_to_transaction(rt, thisVal, args, count);
2112
+ }
2113
+ );
2097
2114
  props["ubrn_uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed"] = jsi::Function::createFromHostFunction(
2098
2115
  rt,
2099
2116
  jsi::PropNameID::forAscii(rt, "ubrn_uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed"),
@@ -2262,6 +2279,14 @@ NativeDdkFfi::NativeDdkFfi(
2262
2279
  return this->cpp_uniffi_ddk_ffi_fn_func_version(rt, thisVal, args, count);
2263
2280
  }
2264
2281
  );
2282
+ props["ubrn_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction"] = jsi::Function::createFromHostFunction(
2283
+ rt,
2284
+ jsi::PropNameID::forAscii(rt, "ubrn_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction"),
2285
+ 0,
2286
+ [this](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) -> jsi::Value {
2287
+ return this->cpp_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction(rt, thisVal, args, count);
2288
+ }
2289
+ );
2265
2290
  props["ubrn_uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed"] = jsi::Function::createFromHostFunction(
2266
2291
  rt,
2267
2292
  jsi::PropNameID::forAscii(rt, "ubrn_uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed"),
@@ -2493,6 +2518,16 @@ jsi::Value NativeDdkFfi::cpp_uniffi_internal_fn_func_ffi__arraybuffer_to_string(
2493
2518
  }
2494
2519
 
2495
2520
  // Methods calling directly into the uniffi generated C API of the Rust crate.
2521
+ jsi::Value NativeDdkFfi::cpp_uniffi_ddk_ffi_fn_func_add_signature_to_transaction(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) {
2522
+ RustCallStatus status = uniffi::ddk_ffi::Bridging<RustCallStatus>::rustSuccess(rt);
2523
+ auto value = uniffi_ddk_ffi_fn_func_add_signature_to_transaction(uniffi::ddk_ffi::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[0]), uniffi::ddk_ffi::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[1]), uniffi::ddk_ffi::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[2]), uniffi_jsi::Bridging<uint32_t>::fromJs(rt, callInvoker, args[3]),
2524
+ &status
2525
+ );
2526
+ uniffi::ddk_ffi::Bridging<RustCallStatus>::copyIntoJs(rt, callInvoker, status, args[count - 1]);
2527
+
2528
+
2529
+ return uniffi::ddk_ffi::Bridging<RustBuffer>::toJs(rt, callInvoker, value);
2530
+ }
2496
2531
  jsi::Value NativeDdkFfi::cpp_uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) {
2497
2532
  RustCallStatus status = uniffi::ddk_ffi::Bridging<RustCallStatus>::rustSuccess(rt);
2498
2533
  auto value = uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed(uniffi::ddk_ffi::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[0]), uniffi::ddk_ffi::Bridging<RustBuffer>::fromJs(rt, callInvoker, args[1]),
@@ -2702,6 +2737,13 @@ jsi::Value NativeDdkFfi::cpp_uniffi_ddk_ffi_fn_func_version(jsi::Runtime& rt, co
2702
2737
 
2703
2738
  return uniffi::ddk_ffi::Bridging<RustBuffer>::toJs(rt, callInvoker, value);
2704
2739
  }
2740
+ jsi::Value NativeDdkFfi::cpp_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) {
2741
+ auto value = uniffi_ddk_ffi_checksum_func_add_signature_to_transaction(
2742
+ );
2743
+
2744
+
2745
+ return uniffi_jsi::Bridging<uint16_t>::toJs(rt, callInvoker, value);
2746
+ }
2705
2747
  jsi::Value NativeDdkFfi::cpp_uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) {
2706
2748
  auto value = uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed(
2707
2749
  );
package/cpp/ddk_ffi.hpp CHANGED
@@ -21,6 +21,7 @@ class NativeDdkFfi : public jsi::HostObject {
21
21
  jsi::Value cpp_uniffi_internal_fn_func_ffi__string_to_byte_length(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
22
22
  jsi::Value cpp_uniffi_internal_fn_func_ffi__string_to_arraybuffer(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
23
23
  jsi::Value cpp_uniffi_internal_fn_func_ffi__arraybuffer_to_string(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
24
+ jsi::Value cpp_uniffi_ddk_ffi_fn_func_add_signature_to_transaction(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
24
25
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_convert_mnemonic_to_seed(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
25
26
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_create_cet(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
26
27
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_create_cet_adaptor_signature_from_oracle_info(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
@@ -42,6 +43,7 @@ class NativeDdkFfi : public jsi::HostObject {
42
43
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_verify_cet_adaptor_sigs_from_oracle_info(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
43
44
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_verify_fund_tx_signature(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
44
45
  jsi::Value cpp_uniffi_ddk_ffi_fn_func_version(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
46
+ jsi::Value cpp_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
45
47
  jsi::Value cpp_uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
46
48
  jsi::Value cpp_uniffi_ddk_ffi_checksum_func_create_cet(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
47
49
  jsi::Value cpp_uniffi_ddk_ffi_checksum_func_create_cet_adaptor_signature_from_oracle_info(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count);
@@ -282,7 +282,7 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
282
282
 
283
283
  [[package]]
284
284
  name = "ddk_ffi"
285
- version = "0.3.10"
285
+ version = "0.3.12"
286
286
  dependencies = [
287
287
  "bip39",
288
288
  "bitcoin",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ddk_ffi"
3
- version = "0.3.10"
3
+ version = "0.3.12"
4
4
  edition = "2021"
5
5
  license = "MIT"
6
6
  description = "rust-dlc language bindings"
@@ -99,6 +99,14 @@ namespace ddk_ffi {
99
99
  u64 input_amount
100
100
  );
101
101
 
102
+ [Throws=DLCError]
103
+ Transaction add_signature_to_transaction(
104
+ Transaction tx,
105
+ sequence<u8> signature,
106
+ sequence<u8> pubkey,
107
+ u32 input_index
108
+ );
109
+
102
110
  [Throws=DLCError]
103
111
  Transaction sign_cet(
104
112
  Transaction cet,
@@ -127,7 +135,7 @@ namespace ddk_ffi {
127
135
  sequence<u8> pubkey,
128
136
  sequence<u8> funding_script_pubkey,
129
137
  u64 total_collateral,
130
- sequence<sequence<sequence<u8>>> msgs
138
+ sequence<sequence<sequence<sequence<u8>>>> msgs
131
139
  );
132
140
 
133
141
  boolean verify_cet_adaptor_sig_from_oracle_info(
@@ -224,6 +224,22 @@ pub fn btc_tx_to_transaction(tx: &BtcTransaction) -> Transaction {
224
224
  }
225
225
  }
226
226
 
227
+ pub fn add_signature_to_transaction(
228
+ tx: Transaction,
229
+ signature: Vec<u8>,
230
+ pubkey: Vec<u8>,
231
+ input_index: u32,
232
+ ) -> Result<Transaction, DLCError> {
233
+ let mut tx = transaction_to_btc_tx(&tx).map_err(|_| DLCError::InvalidTransaction)?;
234
+ let mut witness = Witness::new();
235
+ witness.push(signature);
236
+ witness.push(pubkey);
237
+
238
+ tx.input[input_index as usize].witness = witness;
239
+
240
+ Ok(btc_tx_to_transaction(&tx))
241
+ }
242
+
227
243
  pub fn plz_work() -> String {
228
244
  "heyhowareya".to_string()
229
245
  }
@@ -904,11 +920,12 @@ pub fn verify_cet_adaptor_sigs_from_oracle_info(
904
920
  pubkey: Vec<u8>,
905
921
  funding_script_pubkey: Vec<u8>,
906
922
  total_collateral: u64,
907
- msgs: Vec<Vec<Vec<u8>>>,
923
+ msgs: Vec<Vec<Vec<Vec<u8>>>>,
908
924
  ) -> bool {
909
925
  cets.into_iter()
910
926
  .zip(adaptor_sigs.into_iter())
911
- .all(|(cet, adaptor_sig)| {
927
+ .enumerate()
928
+ .all(|(i, (cet, adaptor_sig))| {
912
929
  verify_cet_adaptor_sig_from_oracle_info(
913
930
  adaptor_sig,
914
931
  cet,
@@ -916,7 +933,7 @@ pub fn verify_cet_adaptor_sigs_from_oracle_info(
916
933
  pubkey.clone(),
917
934
  funding_script_pubkey.clone(),
918
935
  total_collateral,
919
- msgs.clone(),
936
+ msgs[i].clone(),
920
937
  )
921
938
  })
922
939
  }
@@ -1030,8 +1047,12 @@ pub fn get_xpub_from_xpriv(xpriv: Vec<u8>, network: String) -> Result<Vec<u8>, D
1030
1047
  #[cfg(test)]
1031
1048
  mod tests {
1032
1049
  use super::*;
1033
- use bitcoin::locktime::absolute::LockTime;
1034
- use secp256k1_zkp::rand::{thread_rng, RngCore};
1050
+ use bitcoin::{hashes::sha256, locktime::absolute::LockTime, Address, CompressedPublicKey};
1051
+ use dlc::secp_utils;
1052
+ use secp256k1_zkp::{
1053
+ rand::{thread_rng, RngCore},
1054
+ Keypair, Scalar,
1055
+ };
1035
1056
  use std::str::FromStr;
1036
1057
 
1037
1058
  /// Create test keys similar to rust-dlc tests
@@ -1428,4 +1449,264 @@ mod tests {
1428
1449
  );
1429
1450
  assert!(matches!(result, Err(DLCError::InvalidArgument(_))));
1430
1451
  }
1452
+
1453
+ fn get_p2wpkh_script_pubkey(secp: &Secp256k1<All>) -> ScriptBuf {
1454
+ let mut rng = secp256k1_zkp::rand::thread_rng();
1455
+ let sk = bitcoin::PrivateKey {
1456
+ inner: SecretKey::new(&mut rng),
1457
+ network: Network::Testnet.into(),
1458
+ compressed: true,
1459
+ };
1460
+ let pk = CompressedPublicKey::from_private_key(secp, &sk).unwrap();
1461
+ Address::p2wpkh(&pk, Network::Testnet).script_pubkey()
1462
+ }
1463
+
1464
+ fn get_party_params(
1465
+ input_amount: u64,
1466
+ collateral: u64,
1467
+ serial_id: Option<u64>,
1468
+ ) -> (PartyParams, SecretKey) {
1469
+ let secp = Secp256k1::new();
1470
+ let mut rng = secp256k1_zkp::rand::thread_rng();
1471
+ let fund_privkey = SecretKey::new(&mut rng);
1472
+ let serial_id = serial_id.unwrap_or(1);
1473
+ (
1474
+ PartyParams {
1475
+ fund_pubkey: PublicKey::from_secret_key(&secp, &fund_privkey)
1476
+ .serialize()
1477
+ .to_vec(),
1478
+ change_script_pubkey: get_p2wpkh_script_pubkey(&secp).into_bytes(),
1479
+ change_serial_id: serial_id,
1480
+ payout_script_pubkey: get_p2wpkh_script_pubkey(&secp).into_bytes(),
1481
+ payout_serial_id: serial_id,
1482
+ input_amount,
1483
+ collateral,
1484
+ inputs: vec![TxInputInfo {
1485
+ txid: "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456"
1486
+ .to_string(),
1487
+ vout: 0,
1488
+ max_witness_length: 108,
1489
+ script_sig: vec![],
1490
+ serial_id,
1491
+ }],
1492
+ dlc_inputs: vec![],
1493
+ },
1494
+ fund_privkey,
1495
+ )
1496
+ }
1497
+
1498
+ fn payouts_test() -> Vec<Payout> {
1499
+ vec![
1500
+ Payout {
1501
+ offer: 100000000,
1502
+ accept: 100000000,
1503
+ },
1504
+ Payout {
1505
+ offer: 100000000,
1506
+ accept: 100000000,
1507
+ },
1508
+ Payout {
1509
+ offer: 100000000,
1510
+ accept: 100000000,
1511
+ },
1512
+ ]
1513
+ }
1514
+
1515
+ fn signatures_to_secret(signatures: &[Vec<SchnorrSignature>]) -> SecretKey {
1516
+ let s_values = signatures
1517
+ .iter()
1518
+ .flatten()
1519
+ .map(|x| secp_utils::schnorrsig_decompose(x).unwrap().1)
1520
+ .collect::<Vec<_>>();
1521
+ let secret = SecretKey::from_slice(s_values[0]).unwrap();
1522
+
1523
+ s_values.iter().skip(1).fold(secret, |accum, s| {
1524
+ let sec = SecretKey::from_slice(s).unwrap();
1525
+ accum.add_tweak(&Scalar::from(sec)).unwrap()
1526
+ })
1527
+ }
1528
+
1529
+ /// Verify a signature for a given transaction input.
1530
+ fn verify_tx_input_sig(
1531
+ signature: Vec<u8>,
1532
+ tx: Transaction,
1533
+ input_index: usize,
1534
+ script_pubkey: Vec<u8>,
1535
+ value: u64,
1536
+ pk: Vec<u8>,
1537
+ ) -> Result<(), DLCError> {
1538
+ let secp = get_secp_context();
1539
+ let btc_txn = transaction_to_btc_tx(&tx)?;
1540
+ let script = ScriptBuf::from_bytes(script_pubkey);
1541
+ let sig_hash_msg =
1542
+ dlc::util::get_sig_hash_msg(&btc_txn, input_index, &script, Amount::from_sat(value))?;
1543
+ let sig = if signature.len() == 64 {
1544
+ EcdsaSignature::from_compact(&signature).map_err(|_| DLCError::InvalidSignature)
1545
+ } else {
1546
+ EcdsaSignature::from_der(&signature).map_err(|_| DLCError::InvalidSignature)
1547
+ }?;
1548
+ let pk = PublicKey::from_slice(&pk).map_err(|_| DLCError::InvalidPublicKey)?;
1549
+ secp.verify_ecdsa(&sig_hash_msg, &sig, &pk)
1550
+ .map_err(|_| DLCError::InvalidSignature)?;
1551
+ Ok(())
1552
+ }
1553
+
1554
+ #[test]
1555
+ fn create_cet_adaptor_sig_single_oracle_three_outcomes() {
1556
+ // Arrange
1557
+ let secp = Secp256k1::new();
1558
+ let mut rng = secp256k1_zkp::rand::thread_rng();
1559
+ let (offer_party_params, offer_fund_sk) =
1560
+ get_party_params(1_000_000_000, 100_000_000, None);
1561
+ let (accept_party_params, accept_fund_sk) =
1562
+ get_party_params(1_000_000_000, 100_000_000, None);
1563
+
1564
+ let dlc_txs = create_dlc_transactions(
1565
+ payouts_test(),
1566
+ offer_party_params.clone(),
1567
+ accept_party_params.clone(),
1568
+ 100,
1569
+ 4,
1570
+ 10,
1571
+ 10,
1572
+ 0,
1573
+ )
1574
+ .unwrap();
1575
+
1576
+ let cets = dlc_txs.cets;
1577
+ const NB_ORACLES: usize = 1; // 1 oracle
1578
+ const NB_OUTCOMES: usize = 3; // 3 outcomes (enumeration)
1579
+ const NB_DIGITS: usize = 1; // 1 nonce for enumeration contract
1580
+
1581
+ let mut oracle_infos: Vec<OracleInfo> = Vec::with_capacity(NB_ORACLES);
1582
+ let mut oracle_sks: Vec<Keypair> = Vec::with_capacity(NB_ORACLES);
1583
+ let mut oracle_sk_nonce: Vec<Vec<[u8; 32]>> = Vec::with_capacity(NB_ORACLES);
1584
+ let mut oracle_sigs: Vec<Vec<SchnorrSignature>> = Vec::with_capacity(NB_ORACLES);
1585
+
1586
+ // Messages: 3 outcomes × 1 oracle × 1 message per outcome
1587
+ let messages: Vec<Vec<Vec<_>>> = (0..NB_OUTCOMES)
1588
+ .map(|outcome_idx| {
1589
+ vec![
1590
+ // Single oracle
1591
+ vec![
1592
+ // Single message for this outcome
1593
+ {
1594
+ let message = &[outcome_idx as u8]; // Different message per outcome
1595
+ let hash = sha256::Hash::hash(message).to_byte_array();
1596
+ hash.to_vec()
1597
+ },
1598
+ ],
1599
+ ]
1600
+ })
1601
+ .collect();
1602
+
1603
+ // Setup single oracle with single nonce
1604
+ for i in 0..NB_ORACLES {
1605
+ // Runs once
1606
+ let oracle_kp = Keypair::new(&secp, &mut rng);
1607
+ let oracle_pubkey = oracle_kp.x_only_public_key().0;
1608
+ let mut nonces: Vec<XOnlyPublicKey> = Vec::with_capacity(NB_DIGITS);
1609
+ let mut sk_nonces: Vec<[u8; 32]> = Vec::with_capacity(NB_DIGITS);
1610
+ oracle_sigs.push(Vec::with_capacity(NB_DIGITS));
1611
+
1612
+ // Single nonce for enumeration
1613
+ let mut sk_nonce = [0u8; 32];
1614
+ rng.fill_bytes(&mut sk_nonce);
1615
+ let oracle_r_kp = Keypair::from_seckey_slice(&secp, &sk_nonce).unwrap();
1616
+ let nonce = XOnlyPublicKey::from_keypair(&oracle_r_kp).0;
1617
+
1618
+ // Sign the first outcome's message with the single nonce
1619
+ let sig = secp_utils::schnorrsig_sign_with_nonce(
1620
+ &secp,
1621
+ &Message::from_digest_slice(&messages[0][0][0]).unwrap(), // First outcome, first oracle, first message
1622
+ &oracle_kp,
1623
+ &sk_nonce,
1624
+ );
1625
+
1626
+ oracle_sigs[i].push(sig);
1627
+ nonces.push(nonce);
1628
+ sk_nonces.push(sk_nonce);
1629
+
1630
+ oracle_infos.push(OracleInfo {
1631
+ public_key: oracle_pubkey.serialize().to_vec(),
1632
+ nonces: nonces.iter().map(|n| n.serialize().to_vec()).collect(), // Just 1 nonce
1633
+ });
1634
+ oracle_sk_nonce.push(sk_nonces);
1635
+ oracle_sks.push(oracle_kp);
1636
+ }
1637
+ let funding_script_pubkey = dlc::make_funding_redeemscript(
1638
+ &PublicKey::from_slice(&offer_party_params.fund_pubkey.clone()).unwrap(),
1639
+ &PublicKey::from_slice(&accept_party_params.fund_pubkey.clone()).unwrap(),
1640
+ );
1641
+ let fund_output_value = dlc_txs.fund.outputs[0].value;
1642
+
1643
+ // Act
1644
+ let cet_sigs = create_cet_adaptor_sigs_from_oracle_info(
1645
+ cets.clone(), // Use only first 3 CETs
1646
+ oracle_infos.clone(),
1647
+ offer_fund_sk.secret_bytes().to_vec(),
1648
+ funding_script_pubkey.clone().into_bytes(),
1649
+ fund_output_value,
1650
+ messages.clone(),
1651
+ )
1652
+ .unwrap();
1653
+
1654
+ let oracle_signatures = oracle_sigs
1655
+ .iter()
1656
+ .map(|s| s.iter().map(|s| s.serialize().to_vec()).collect::<Vec<_>>())
1657
+ .collect::<Vec<_>>();
1658
+
1659
+ let sign_res = sign_cet(
1660
+ cets[0].clone(),
1661
+ cet_sigs[0].signature.clone(),
1662
+ oracle_signatures[0].clone(),
1663
+ accept_fund_sk.secret_bytes().to_vec(),
1664
+ offer_party_params.fund_pubkey.clone(),
1665
+ funding_script_pubkey.clone().into_bytes(),
1666
+ fund_output_value,
1667
+ );
1668
+
1669
+ assert!(sign_res.is_ok());
1670
+
1671
+ let adaptor_secret = signatures_to_secret(&oracle_sigs);
1672
+ let signature = vec_to_ecdsa_adaptor_signature(cet_sigs[0].signature.clone()).unwrap();
1673
+ let adapted_sig = signature.decrypt(&adaptor_secret).unwrap();
1674
+
1675
+ let batch_verify = verify_cet_adaptor_sigs_from_oracle_info(
1676
+ cet_sigs.clone(),
1677
+ cets.clone(),
1678
+ oracle_infos.clone(),
1679
+ offer_party_params.fund_pubkey.clone(),
1680
+ funding_script_pubkey.clone().into_bytes(),
1681
+ fund_output_value,
1682
+ messages.clone(),
1683
+ );
1684
+
1685
+ assert!(batch_verify);
1686
+
1687
+ // Assert
1688
+ assert_eq!(cet_sigs.len(), 3, "Should have 3 CET signatures");
1689
+ assert!(cet_sigs
1690
+ .iter()
1691
+ .enumerate()
1692
+ .all(|(i, x)| verify_cet_adaptor_sig_from_oracle_info(
1693
+ x.clone(),
1694
+ cets[i].clone(),
1695
+ oracle_infos.clone(),
1696
+ offer_party_params.fund_pubkey.clone(),
1697
+ funding_script_pubkey.clone().into_bytes(),
1698
+ fund_output_value,
1699
+ messages[i].clone(),
1700
+ )));
1701
+ sign_res.expect("Error signing CET");
1702
+ verify_tx_input_sig(
1703
+ adapted_sig.serialize_compact().to_vec(),
1704
+ cets[0].clone(),
1705
+ 0,
1706
+ funding_script_pubkey.clone().into_bytes(),
1707
+ fund_output_value,
1708
+ offer_party_params.fund_pubkey.clone(),
1709
+ )
1710
+ .expect("Invalid decrypted adaptor signature");
1711
+ }
1431
1712
  }
@@ -1 +1 @@
1
- {"version":3,"names":["getter","globalThis","NativeDdkFfi","_default","exports","default","isRustFutureContinuationCallbackTypeCompatible","isUniffiForeignFutureTypeCompatible"],"sourceRoot":"../../src","sources":["ddk_ffi-ffi.ts"],"mappings":";;;;;;AAAA;AACA;;AAoNA;AACA;AACA;AACA;AACA;AACA,MAAMA,MAAmC,GAAGA,CAAA,KACzCC,UAAU,CAASC,YAAY;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACpBL,MAAM,EAErB;AAmHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,8CAGL,GAAG,IAAI;AACR,MAAMC,mCAGL,GAAG,IAAI","ignoreList":[]}
1
+ {"version":3,"names":["getter","globalThis","NativeDdkFfi","_default","exports","default","isRustFutureContinuationCallbackTypeCompatible","isUniffiForeignFutureTypeCompatible"],"sourceRoot":"../../src","sources":["ddk_ffi-ffi.ts"],"mappings":";;;;;;AAAA;AACA;;AA4NA;AACA;AACA;AACA;AACA;AACA,MAAMA,MAAmC,GAAGA,CAAA,KACzCC,UAAU,CAASC,YAAY;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACpBL,MAAM,EAErB;AAmHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,8CAGL,GAAG,IAAI;AACR,MAAMC,mCAGL,GAAG,IAAI","ignoreList":[]}
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.TxOutput = exports.TxInputInfo = exports.TxInput = exports.Transaction = exports.Payout = exports.PartyParams = exports.OracleInfo = exports.ExtendedKey_Tags = exports.ExtendedKey = exports.DlcTransactions = exports.DlcInputInfo = exports.DlcError_Tags = exports.DlcError = exports.ChangeOutputAndFees = exports.AdaptorSignature = void 0;
7
+ exports.addSignatureToTransaction = addSignatureToTransaction;
7
8
  exports.convertMnemonicToSeed = convertMnemonicToSeed;
8
9
  exports.createCet = createCet;
9
10
  exports.createCetAdaptorSignatureFromOracleInfo = createCetAdaptorSignatureFromOracleInfo;
@@ -43,6 +44,14 @@ typeof process !== 'object' ||
43
44
  process?.env?.NODE_ENV !== 'production' || true;
44
45
  // Public interface members begin here.
45
46
 
47
+ function addSignatureToTransaction(tx, signature, pubkey, inputIndex) /*throws*/{
48
+ return FfiConverterTypeTransaction.lift(uniffiCaller.rustCallWithError(/*liftError:*/FfiConverterTypeDLCError.lift.bind(FfiConverterTypeDLCError), /*caller:*/callStatus => {
49
+ return (() => {
50
+ console.debug(`-- uniffi_ddk_ffi_fn_func_add_signature_to_transaction`);
51
+ return (0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_fn_func_add_signature_to_transaction;
52
+ })()(FfiConverterTypeTransaction.lower(tx), FfiConverterArrayUInt8.lower(signature), FfiConverterArrayUInt8.lower(pubkey), _uniffiBindgenReactNative.FfiConverterUInt32.lower(inputIndex), callStatus);
53
+ }, /*liftString:*/FfiConverterString.lift));
54
+ }
46
55
  function convertMnemonicToSeed(mnemonic, passphrase) /*throws*/{
47
56
  return FfiConverterArrayUInt8.lift(uniffiCaller.rustCallWithError(/*liftError:*/FfiConverterTypeDLCError.lift.bind(FfiConverterTypeDLCError), /*caller:*/callStatus => {
48
57
  return (() => {
@@ -192,7 +201,7 @@ function verifyCetAdaptorSigsFromOracleInfo(adaptorSigs, cets, oracleInfo, pubke
192
201
  return (() => {
193
202
  console.debug(`-- uniffi_ddk_ffi_fn_func_verify_cet_adaptor_sigs_from_oracle_info`);
194
203
  return (0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_fn_func_verify_cet_adaptor_sigs_from_oracle_info;
195
- })()(FfiConverterArrayTypeAdaptorSignature.lower(adaptorSigs), FfiConverterArrayTypeTransaction.lower(cets), FfiConverterArrayTypeOracleInfo.lower(oracleInfo), FfiConverterArrayUInt8.lower(pubkey), FfiConverterArrayUInt8.lower(fundingScriptPubkey), _uniffiBindgenReactNative.FfiConverterUInt64.lower(totalCollateral), FfiConverterArrayArrayArrayUInt8.lower(msgs), callStatus);
204
+ })()(FfiConverterArrayTypeAdaptorSignature.lower(adaptorSigs), FfiConverterArrayTypeTransaction.lower(cets), FfiConverterArrayTypeOracleInfo.lower(oracleInfo), FfiConverterArrayUInt8.lower(pubkey), FfiConverterArrayUInt8.lower(fundingScriptPubkey), _uniffiBindgenReactNative.FfiConverterUInt64.lower(totalCollateral), FfiConverterArrayArrayArrayArrayUInt8.lower(msgs), callStatus);
196
205
  }, /*liftString:*/FfiConverterString.lift));
197
206
  }
198
207
  function verifyFundTxSignature(fundTx, signature, pubkey, txid, vout, inputAmount) /*throws*/{
@@ -1196,6 +1205,9 @@ function uniffiEnsureInitialized() {
1196
1205
  if (bindingsContractVersion !== scaffoldingContractVersion) {
1197
1206
  throw new _uniffiBindgenReactNative.UniffiInternalError.ContractVersionMismatch(scaffoldingContractVersion, bindingsContractVersion);
1198
1207
  }
1208
+ if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_add_signature_to_transaction() !== 1337) {
1209
+ throw new _uniffiBindgenReactNative.UniffiInternalError.ApiChecksumMismatch('uniffi_ddk_ffi_checksum_func_add_signature_to_transaction');
1210
+ }
1199
1211
  if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed() !== 65049) {
1200
1212
  throw new _uniffiBindgenReactNative.UniffiInternalError.ApiChecksumMismatch('uniffi_ddk_ffi_checksum_func_convert_mnemonic_to_seed');
1201
1213
  }
@@ -1250,7 +1262,7 @@ function uniffiEnsureInitialized() {
1250
1262
  if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_verify_cet_adaptor_sig_from_oracle_info() !== 52232) {
1251
1263
  throw new _uniffiBindgenReactNative.UniffiInternalError.ApiChecksumMismatch('uniffi_ddk_ffi_checksum_func_verify_cet_adaptor_sig_from_oracle_info');
1252
1264
  }
1253
- if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_verify_cet_adaptor_sigs_from_oracle_info() !== 37581) {
1265
+ if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_verify_cet_adaptor_sigs_from_oracle_info() !== 14181) {
1254
1266
  throw new _uniffiBindgenReactNative.UniffiInternalError.ApiChecksumMismatch('uniffi_ddk_ffi_checksum_func_verify_cet_adaptor_sigs_from_oracle_info');
1255
1267
  }
1256
1268
  if ((0, _ddk_ffiFfi.default)().ubrn_uniffi_ddk_ffi_checksum_func_verify_fund_tx_signature() !== 27316) {