1#![allow(async_fn_in_trait)]
2
3pub mod error;
4#[cfg(feature = "nostr")]
5pub mod nostr_events;
6pub mod storage;
7
8use crate::error::Error;
9use crate::storage::Storage;
10use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv};
11use bitcoin::hashes::{sha256, Hash};
12use bitcoin::key::XOnlyPublicKey;
13use bitcoin::secp256k1::{All, Secp256k1, SecretKey};
14use bitcoin::Network;
15use secp256k1_zkp::Keypair;
16use std::str::FromStr;
17
18pub use bitcoin;
19pub use bitcoin::secp256k1::schnorr::Signature;
20use ddk_messages::oracle_msgs::DigitDecompositionEventDescriptor;
21pub use ddk_messages::oracle_msgs::{
22 EnumEventDescriptor, EventDescriptor, OracleAnnouncement, OracleAttestation, OracleEvent,
23};
24pub use lightning;
25pub use lightning::util::ser::{Readable, Writeable};
26#[cfg(feature = "nostr")]
27pub use nostr;
28
29const SIGNING_KEY_PATH: &str = "m/86'/0'/0'/0/0";
31
32#[derive(Debug, Clone)]
33pub struct Oracle<S: Storage> {
34 pub storage: S,
35 key_pair: Keypair,
36 nonce_xpriv: Xpriv,
37 secp: Secp256k1<All>,
38}
39
40impl<S: Storage> Oracle<S> {
41 pub fn new(storage: S, signing_key: SecretKey, nonce_xpriv: Xpriv) -> Self {
42 let secp = Secp256k1::new();
43 Self {
44 storage,
45 key_pair: Keypair::from_secret_key(&secp, &signing_key),
46 nonce_xpriv,
47 secp,
48 }
49 }
50
51 pub fn from_xpriv(storage: S, xpriv: Xpriv) -> Result<Self, Error> {
52 let secp = Secp256k1::new();
53
54 let signing_key = derive_signing_key(&secp, xpriv)?;
55 Self::from_signing_key(storage, signing_key)
56 }
57
58 pub fn from_signing_key(storage: S, signing_key: SecretKey) -> Result<Self, Error> {
59 let secp = Secp256k1::new();
60
61 let xpriv_bytes = sha256::Hash::hash(&signing_key.secret_bytes()).to_byte_array();
62 let nonce_xpriv =
63 Xpriv::new_master(Network::Bitcoin, &xpriv_bytes).map_err(|_| Error::Internal)?;
64
65 Ok(Self {
66 storage,
67 key_pair: Keypair::from_secret_key(&secp, &signing_key),
68 nonce_xpriv,
69 secp,
70 })
71 }
72
73 pub fn public_key(&self) -> XOnlyPublicKey {
74 self.key_pair.x_only_public_key().0
75 }
76
77 #[cfg(feature = "nostr")]
79 pub fn nostr_keys(&self) -> nostr::Keys {
80 let sec = nostr::key::SecretKey::from_slice(&self.key_pair.secret_key().secret_bytes()[..])
81 .expect("just converting types");
82 nostr::Keys::new(sec)
83 }
84
85 fn get_nonce_key(&self, index: u32) -> SecretKey {
86 self.nonce_xpriv
87 .derive_priv(
88 &self.secp,
89 &[ChildNumber::from_hardened_idx(index).unwrap()],
90 )
91 .unwrap()
92 .private_key
93 }
94
95 pub async fn create_enum_event(
96 &self,
97 event_id: String,
98 outcomes: Vec<String>,
99 event_maturity_epoch: u32,
100 ) -> Result<OracleAnnouncement, Error> {
101 let indexes = self.storage.get_next_nonce_indexes(1).await?;
102 let oracle_nonces = indexes
103 .iter()
104 .map(|i| {
105 let nonce_key = self.get_nonce_key(*i);
106 nonce_key.x_only_public_key(&self.secp).0
107 })
108 .collect();
109 let event_descriptor = EventDescriptor::EnumEvent(EnumEventDescriptor { outcomes });
110 let oracle_event = OracleEvent {
111 oracle_nonces,
112 event_id,
113 event_maturity_epoch,
114 event_descriptor,
115 };
116 oracle_event.validate().map_err(|_| Error::Internal)?;
117
118 let msg = ddk_messages::oracle_msgs::tagged_announcement_msg(&oracle_event);
120 let announcement_signature = self.secp.sign_schnorr_no_aux_rand(&msg, &self.key_pair);
121
122 let ann = OracleAnnouncement {
123 oracle_event,
124 oracle_public_key: self.public_key(),
125 announcement_signature,
126 };
127 ann.validate(&self.secp).map_err(|_| Error::Internal)?;
128 let _ = self.storage.save_announcement(ann.clone(), indexes).await?;
129
130 Ok(ann)
131 }
132
133 pub async fn sign_enum_event(
134 &self,
135 event_id: String,
136 outcome: String,
137 ) -> Result<OracleAttestation, Error> {
138 let Some(data) = self.storage.get_event(event_id.clone()).await? else {
139 return Err(Error::NotFound);
140 };
141 if !data.signatures.is_empty() {
142 return Err(Error::EventAlreadySigned);
143 }
144 if data.indexes.len() != 1 {
145 return Err(Error::Internal);
146 }
147 let descriptor = match &data.announcement.oracle_event.event_descriptor {
148 EventDescriptor::EnumEvent(desc) => desc,
149 _ => return Err(Error::Internal),
150 };
151 if !descriptor.outcomes.contains(&outcome) {
152 return Err(Error::InvalidOutcome);
153 }
154
155 let nonce_index = data.indexes.first().expect("Already checked length");
156 let nonce_key = self.get_nonce_key(*nonce_index);
157
158 let msg = ddk_messages::oracle_msgs::tagged_attestation_msg(&outcome);
159
160 let sig = ddk_dlc::secp_utils::schnorrsig_sign_with_nonce(
161 &self.secp,
162 &msg,
163 &self.key_pair,
164 &nonce_key.secret_bytes(),
165 );
166
167 debug_assert!(
169 sig.encode()[..32] == data.announcement.oracle_event.oracle_nonces[0].serialize()
170 );
171
172 if self
174 .secp
175 .verify_schnorr(&sig, &msg, &self.key_pair.x_only_public_key().0)
176 .is_err()
177 {
178 return Err(Error::Internal);
179 };
180
181 let sigs = vec![(outcome.clone(), sig)];
182
183 self.storage
184 .save_signatures(event_id.to_string(), sigs)
185 .await?;
186
187 let attestation = OracleAttestation {
188 event_id: data.announcement.oracle_event.event_id,
189 oracle_public_key: self.public_key(),
190 signatures: vec![sig],
191 outcomes: vec![outcome],
192 };
193
194 Ok(attestation)
195 }
196
197 pub async fn create_numeric_event(
198 &self,
199 event_id: String,
200 num_digits: u16,
201 is_signed: bool,
202 precision: i32,
203 unit: String,
204 event_maturity_epoch: u32,
205 ) -> Result<OracleAnnouncement, Error> {
206 if num_digits == 0 {
207 return Err(Error::InvalidArgument);
208 }
209
210 let num_nonces = if is_signed {
211 num_digits as usize + 1
212 } else {
213 num_digits as usize
214 };
215
216 let indexes = self.storage.get_next_nonce_indexes(num_nonces).await?;
217 let oracle_nonces = indexes
218 .iter()
219 .map(|i| {
220 let nonce_key = self.get_nonce_key(*i);
221 nonce_key.x_only_public_key(&self.secp).0
222 })
223 .collect();
224 let event_descriptor =
225 EventDescriptor::DigitDecompositionEvent(DigitDecompositionEventDescriptor {
226 base: 2,
227 is_signed,
228 unit,
229 precision,
230 nb_digits: num_digits,
231 });
232 let oracle_event = OracleEvent {
233 oracle_nonces,
234 event_id,
235 event_maturity_epoch,
236 event_descriptor,
237 };
238 oracle_event.validate().map_err(|_| Error::Internal)?;
239
240 let msg = ddk_messages::oracle_msgs::tagged_announcement_msg(&oracle_event);
242 let announcement_signature = self.secp.sign_schnorr_no_aux_rand(&msg, &self.key_pair);
243
244 let ann = OracleAnnouncement {
245 oracle_event,
246 oracle_public_key: self.public_key(),
247 announcement_signature,
248 };
249 ann.validate(&self.secp).map_err(|_| Error::Internal)?;
250
251 let _ = self.storage.save_announcement(ann.clone(), indexes).await?;
252
253 Ok(ann)
254 }
255
256 pub async fn sign_numeric_event(
257 &self,
258 event_id: String,
259 outcome: i64,
260 ) -> Result<OracleAttestation, Error> {
261 let Some(data) = self.storage.get_event(event_id.clone()).await? else {
262 return Err(Error::NotFound);
263 };
264 if !data.signatures.is_empty() {
265 return Err(Error::EventAlreadySigned);
266 }
267 let descriptor = match &data.announcement.oracle_event.event_descriptor {
268 EventDescriptor::DigitDecompositionEvent(desc) => desc,
269 _ => return Err(Error::Internal),
270 };
271 if descriptor.base != 2 {
272 return Err(Error::Internal);
273 }
274 let max_value = (descriptor.base as i64).pow(descriptor.nb_digits as u32) - 1;
275 let min_value = if descriptor.is_signed { -max_value } else { 0 };
276 if outcome < min_value || outcome > max_value {
277 return Err(Error::InvalidOutcome);
278 }
279
280 let digits = format!(
281 "{:0width$b}",
282 outcome.abs(),
283 width = descriptor.nb_digits as usize
284 )
285 .chars()
286 .map(|char| char.to_string())
287 .collect::<Vec<_>>();
288
289 let outcomes = if descriptor.is_signed {
290 let mut sign = vec![if outcome < 0 {
291 "-".to_string()
292 } else {
293 "+".to_string()
294 }];
295 sign.extend(digits);
296 sign
297 } else {
298 digits
299 };
300
301 if data.indexes.len() != outcomes.len() {
302 return Err(Error::Internal);
303 }
304
305 let nonce_keys = data.indexes.iter().map(|i| self.get_nonce_key(*i));
306
307 let mut sigs: Vec<(String, Signature)> = vec![];
308
309 let signatures = outcomes
310 .iter()
311 .zip(nonce_keys)
312 .enumerate()
313 .map(|(idx, (outcome, nonce_key))| {
314 let msg = ddk_messages::oracle_msgs::tagged_attestation_msg(outcome);
315 let sig = ddk_dlc::secp_utils::schnorrsig_sign_with_nonce(
316 &self.secp,
317 &msg,
318 &self.key_pair,
319 &nonce_key.secret_bytes(),
320 );
321 debug_assert!(
323 sig.encode()[..32]
324 == data.announcement.oracle_event.oracle_nonces[idx].serialize()
325 );
326 if self
328 .secp
329 .verify_schnorr(&sig, &msg, &self.key_pair.x_only_public_key().0)
330 .is_err()
331 {
332 return Err(Error::Internal);
333 };
334 sigs.push((outcome.clone(), sig));
335 Ok(sig)
336 })
337 .collect::<Result<Vec<_>, Error>>()?;
338
339 self.storage.save_signatures(event_id, sigs).await?;
340
341 let attestation = OracleAttestation {
342 event_id: data.announcement.oracle_event.event_id,
343 oracle_public_key: self.public_key(),
344 signatures,
345 outcomes,
346 };
347
348 Ok(attestation)
349 }
350}
351
352pub fn derive_signing_key(secp: &Secp256k1<All>, xpriv: Xpriv) -> Result<SecretKey, Error> {
353 let signing_key = xpriv
354 .derive_priv(
355 secp,
356 &DerivationPath::from_str(SIGNING_KEY_PATH).map_err(|_| Error::Internal)?,
357 )
358 .map_err(|_| Error::Internal)?
359 .private_key;
360 Ok(signing_key)
361}
362
363#[cfg(test)]
364mod test {
365 use super::*;
366 use crate::storage::MemoryStorage;
367 use bitcoin::secp256k1::rand::{thread_rng, Rng};
368
369 fn create_oracle() -> Oracle<MemoryStorage> {
370 let mut seed: [u8; 64] = [0; 64];
371 thread_rng().fill(&mut seed);
372 let xpriv = Xpriv::new_master(Network::Regtest, &seed).unwrap();
373 Oracle::from_xpriv(MemoryStorage::default(), xpriv).unwrap()
374 }
375
376 #[tokio::test]
377 async fn test_create_enum_event() {
378 let oracle = create_oracle();
379
380 let event_id = "test".to_string();
381 let outcomes = vec!["a".to_string(), "b".to_string()];
382 let event_maturity_epoch = 100;
383 let ann = oracle
384 .create_enum_event(event_id.clone(), outcomes.clone(), event_maturity_epoch)
385 .await
386 .unwrap();
387
388 assert!(ann.validate(&oracle.secp).is_ok());
389 assert_eq!(ann.oracle_event.event_id, event_id);
390 assert_eq!(ann.oracle_event.event_maturity_epoch, event_maturity_epoch);
391 assert_eq!(
392 ann.oracle_event.event_descriptor,
393 EventDescriptor::EnumEvent(EnumEventDescriptor { outcomes })
394 );
395 }
396
397 #[tokio::test]
398 async fn test_sign_enum_event() {
399 let oracle = create_oracle();
400
401 let event_id = "test".to_string();
402 let outcomes = vec!["a".to_string(), "b".to_string()];
403 let event_maturity_epoch = std::time::SystemTime::now()
404 .duration_since(std::time::UNIX_EPOCH)
405 .unwrap()
406 .as_secs() as u32
407 + 86400;
408 let ann = oracle
409 .create_enum_event(event_id.clone(), outcomes.clone(), event_maturity_epoch)
410 .await
411 .unwrap();
412
413 println!("{}", hex::encode(ann.encode()));
414
415 let attestation = oracle
416 .sign_enum_event(event_id, "a".to_string())
417 .await
418 .unwrap();
419 assert!(attestation.outcomes.contains(&"a".to_string()));
420 assert_eq!(attestation.oracle_public_key, oracle.public_key());
421 assert_eq!(attestation.signatures.len(), 1);
422 assert_eq!(attestation.outcomes.len(), 1);
423 let sig = attestation.signatures.first().unwrap();
424
425 let expected_nonce = ann.oracle_event.oracle_nonces.first().unwrap().serialize();
427 let bytes = sig.encode();
428 let (rx, _sig) = bytes.split_at(32);
429
430 println!("{}", hex::encode(attestation.encode()));
431
432 assert_eq!(rx, expected_nonce)
433 }
434
435 #[tokio::test]
436 async fn test_create_unsigned_numeric_event() {
437 let oracle = create_oracle();
438
439 let event_id = "test_unsigned_numeric".to_string();
440 let num_digits = 20;
441
442 let event_maturity_epoch = 100;
443 let ann = oracle
444 .create_numeric_event(
445 event_id.clone(),
446 num_digits,
447 false,
448 0,
449 "m/s".into(),
450 event_maturity_epoch,
451 )
452 .await
453 .unwrap();
454
455 assert!(ann.validate(&oracle.secp).is_ok());
456 assert_eq!(ann.oracle_event.event_id, event_id);
457 assert_eq!(ann.oracle_event.event_maturity_epoch, event_maturity_epoch);
458 assert_eq!(
459 ann.oracle_event.event_descriptor,
460 EventDescriptor::DigitDecompositionEvent(DigitDecompositionEventDescriptor {
461 base: 2,
462 is_signed: false,
463 unit: "m/s".into(),
464 precision: 0,
465 nb_digits: 20,
466 })
467 );
468 }
469
470 #[tokio::test]
471 async fn create_oracle_test_vectors() {
472 let oracle = create_oracle();
473 let ann = oracle
474 .create_enum_event(
475 "Test".to_string(),
476 vec![
477 "a".to_string(),
478 "b".to_string(),
479 "c".to_string(),
480 "d".to_string(),
481 ],
482 1623133104,
483 )
484 .await
485 .unwrap();
486 println!("{}", serde_json::to_string_pretty(&ann).unwrap())
487 }
488
489 #[tokio::test]
490 async fn test_sign_unsigned_numeric_event() {
491 let oracle = create_oracle();
492
493 let event_id = "test_unsigned_numeric".to_string();
494 let num_digits = 16;
495
496 let event_maturity_epoch = 100;
497 let ann = oracle
498 .create_numeric_event(
499 event_id.clone(),
500 num_digits,
501 false,
502 0,
503 "m/s".into(),
504 event_maturity_epoch,
505 )
506 .await
507 .unwrap();
508
509 println!("{}", hex::encode(ann.encode()));
510 let res = oracle.sign_numeric_event(event_id.clone(), 0x55555).await;
511 assert!(res.is_err());
512 let attestation = oracle
513 .sign_numeric_event(event_id.clone(), 0x5555)
514 .await
515 .unwrap();
516 assert_eq!(
517 attestation.outcomes,
518 vec!["0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1"]
519 .iter()
520 .map(|x| x.to_string())
521 .collect::<Vec<_>>()
522 );
523 assert_eq!(attestation.oracle_public_key, oracle.public_key());
524 assert_eq!(attestation.signatures.len(), 16);
525 assert_eq!(attestation.outcomes.len(), 16);
526
527 for i in 0..attestation.signatures.len() {
528 let sig = attestation.signatures[i];
529
530 let expected_nonce = ann.oracle_event.oracle_nonces[i].serialize();
532 let bytes = sig.encode();
533 let (rx, _sig) = bytes.split_at(32);
534
535 assert_eq!(rx, expected_nonce)
536 }
537
538 println!("{}", hex::encode(attestation.encode()));
539 }
540
541 #[tokio::test]
542 async fn test_create_signed_numeric_event() {
543 let oracle = create_oracle();
544
545 let event_id = "test_signed_numeric".to_string();
546 let num_digits = 20;
547
548 let event_maturity_epoch = 100;
549 let ann = oracle
550 .create_numeric_event(
551 event_id.clone(),
552 num_digits,
553 true,
554 0,
555 "m/s".into(),
556 event_maturity_epoch,
557 )
558 .await
559 .unwrap();
560
561 assert!(ann.validate(&oracle.secp).is_ok());
562 assert_eq!(ann.oracle_event.event_id, event_id);
563 assert_eq!(ann.oracle_event.event_maturity_epoch, event_maturity_epoch);
564 assert_eq!(
565 ann.oracle_event.event_descriptor,
566 EventDescriptor::DigitDecompositionEvent(DigitDecompositionEventDescriptor {
567 base: 2,
568 is_signed: true,
569 unit: "m/s".into(),
570 precision: 0,
571 nb_digits: 20,
572 })
573 );
574 }
575
576 #[tokio::test]
577 async fn test_sign_signed_positive_numeric_event() {
578 let oracle = create_oracle();
579
580 let event_id = "test_signed_numeric".to_string();
581 let num_digits = 16;
582
583 let event_maturity_epoch = 100;
584 let ann = oracle
585 .create_numeric_event(
586 event_id.clone(),
587 num_digits,
588 true,
589 0,
590 "m/s".into(),
591 event_maturity_epoch,
592 )
593 .await
594 .unwrap();
595
596 println!("{}", hex::encode(ann.encode()));
597 let res = oracle.sign_numeric_event(event_id.clone(), 0x55555).await;
598 assert!(res.is_err());
599 let attestation = oracle.sign_numeric_event(event_id, 0x5555).await.unwrap();
600 assert_eq!(
601 attestation.outcomes,
602 vec![
603 "+", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1"
604 ]
605 .iter()
606 .map(|x| x.to_string())
607 .collect::<Vec<_>>()
608 );
609 assert_eq!(attestation.oracle_public_key, oracle.public_key());
610 assert_eq!(attestation.signatures.len(), 16 + 1);
611 assert_eq!(attestation.outcomes.len(), 16 + 1);
612
613 for i in 0..attestation.signatures.len() {
614 let sig = attestation.signatures[i];
615
616 let expected_nonce = ann.oracle_event.oracle_nonces[i].serialize();
618 let bytes = sig.encode();
619 let (rx, _sig) = bytes.split_at(32);
620
621 assert_eq!(rx, expected_nonce)
622 }
623
624 println!("{}", hex::encode(attestation.encode()));
625 }
626
627 #[tokio::test]
628 async fn test_sign_signed_negative_numeric_event() {
629 let oracle = create_oracle();
630
631 let event_id = "test_signed_numeric".to_string();
632 let num_digits = 16;
633
634 let event_maturity_epoch = 100;
635 let ann = oracle
636 .create_numeric_event(
637 event_id.clone(),
638 num_digits,
639 true,
640 0,
641 "m/s".into(),
642 event_maturity_epoch,
643 )
644 .await
645 .unwrap();
646
647 println!("{}", hex::encode(ann.encode()));
648 let res = oracle.sign_numeric_event(event_id.clone(), -0x55555).await;
649 assert!(res.is_err());
650 let attestation = oracle.sign_numeric_event(event_id, -0x5555).await.unwrap();
651 assert_eq!(
652 attestation.outcomes,
653 vec![
654 "-", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1"
655 ]
656 .iter()
657 .map(|x| x.to_string())
658 .collect::<Vec<_>>()
659 );
660 assert_eq!(attestation.oracle_public_key, oracle.public_key());
661 assert_eq!(attestation.signatures.len(), 16 + 1);
662 assert_eq!(attestation.outcomes.len(), 16 + 1);
663
664 for i in 0..attestation.signatures.len() {
665 let sig = attestation.signatures[i];
666
667 let expected_nonce = ann.oracle_event.oracle_nonces[i].serialize();
669 let bytes = sig.encode();
670 let (rx, _sig) = bytes.split_at(32);
671
672 assert_eq!(rx, expected_nonce)
673 }
674
675 println!("{}", hex::encode(attestation.encode()));
676 }
677}