diff --git a/app-commons/src/main/scala/org/bitcoins/commons/serializers/Picklers.scala b/app-commons/src/main/scala/org/bitcoins/commons/serializers/Picklers.scala index fbcced0c8f..124e7b94c9 100644 --- a/app-commons/src/main/scala/org/bitcoins/commons/serializers/Picklers.scala +++ b/app-commons/src/main/scala/org/bitcoins/commons/serializers/Picklers.scala @@ -416,6 +416,8 @@ object Picklers { val numericOracles = oracles.map(_.asInstanceOf[NumericSingleOracleInfo]) NumericOracleOutcome(numericOracles.zip(numericOutcomes)) + case signed: SignedNumericOutcome => + throw new IllegalArgumentException(s"Unexpected outcome $signed") } state match { diff --git a/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala b/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala index 7e01377295..790dd3f8ce 100644 --- a/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala +++ b/app/cli/src/main/scala/org/bitcoins/cli/ConsoleCli.scala @@ -1053,7 +1053,7 @@ object ConsoleCli { .text(s"Get oracle's staking address"), cmd("listevents") .action((_, conf) => conf.copy(command = ListEvents)) - .text(s"Lists all event announcements"), + .text(s"Lists all event names"), cmd("createenumevent") .action((_, conf) => conf.copy(command = CreateEnumEvent("", new Date(), Seq.empty))) diff --git a/app/oracle-server-test/src/test/scala/org/bitcoins/oracle/server/OracleRoutesSpec.scala b/app/oracle-server-test/src/test/scala/org/bitcoins/oracle/server/OracleRoutesSpec.scala index 0d5f9b215d..078451d830 100644 --- a/app/oracle-server-test/src/test/scala/org/bitcoins/oracle/server/OracleRoutesSpec.scala +++ b/app/oracle-server-test/src/test/scala/org/bitcoins/oracle/server/OracleRoutesSpec.scala @@ -10,15 +10,11 @@ import org.bitcoins.core.protocol.Bech32Address import org.bitcoins.core.protocol.dlc.SigningVersion import org.bitcoins.core.protocol.tlv.{ EnumEventDescriptorV0TLV, + NormalizedString, OracleAnnouncementV0TLV, OracleAttestmentV0TLV } -import org.bitcoins.crypto.{ - ECPublicKey, - FieldElement, - SchnorrDigitalSignature, - SchnorrPublicKey -} +import org.bitcoins.crypto._ import org.bitcoins.dlc.oracle.config.DLCOracleAppConfig import org.bitcoins.server.routes.ServerCommand import org.bitcoins.testkit.BitcoinSTestAppConfig @@ -44,18 +40,28 @@ class OracleRoutesSpec val testAddressStr = "bc1qvrctqwa6g70z5vtxsyft7xvsyyt749trlm80al" val testAddress: Bech32Address = Bech32Address.fromString(testAddressStr) - val dummyKey: ECPublicKey = ECPublicKey.freshPublicKey + val kVal: ECPrivateKey = ECPrivateKey.freshPrivateKey + + val dummyPrivKey: ECPrivateKey = ECPrivateKey.freshPrivateKey + val dummyKey: ECPublicKey = dummyPrivKey.publicKey + + val outcome: NormalizedString = EnumEventDescriptorV0TLV.dummy.outcomes.head + + val hash: Sha256Digest = CryptoUtil.sha256DLCAttestation(outcome) + + val sig: SchnorrDigitalSignature = + dummyPrivKey.schnorrSignWithNonce(hash.bytes, kVal) val dummyEventDb: EventDb = EventDb( - nonce = dummyKey.schnorrNonce, + nonce = kVal.schnorrNonce, pubkey = dummyKey.schnorrPublicKey, nonceIndex = 0, eventName = "id", numOutcomes = 2, signingVersion = SigningVersion.latest, maturationTime = Instant.ofEpochSecond(0), - attestationOpt = Some(FieldElement.one), - outcomeOpt = Some("outcome"), + attestationOpt = Some(sig.sig), + outcomeOpt = Some(outcome), announcementSignature = SchnorrDigitalSignature( "1efe41fa42ea1dcd103a0251929dd2b192d2daece8a4ce4d81f68a183b750d92d6f02d796965dc79adf4e7786e08f861a1ecc897afbba2dab9cff6eb0a81937e"), eventDescriptorTLV = EnumEventDescriptorV0TLV.dummy @@ -113,8 +119,8 @@ class OracleRoutesSpec Get() ~> route ~> check { assert(contentType == `application/json`) - assert(responseAs[ - String] == s"""{"result":["${dummyOracleEvent.announcementTLV.hex}"],"error":null}""") + assert( + responseAs[String] == s"""{"result":["${dummyOracleEvent.eventName}"],"error":null}""") } } diff --git a/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleRoutes.scala b/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleRoutes.scala index 2c91317598..b1bcb7c794 100644 --- a/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleRoutes.scala +++ b/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleRoutes.scala @@ -36,7 +36,7 @@ case class OracleRoutes(oracle: DLCOracleApi)(implicit case ServerCommand("listevents", _) => complete { oracle.listEvents().map { events => - val strs = events.map(_.announcementTLV.hex) + val strs = events.map(_.eventName) val json = Arr.from(strs) Server.httpSuccess(json) @@ -127,13 +127,6 @@ case class OracleRoutes(oracle: DLCOracleApi)(implicit case enum: EnumEventDescriptorV0TLV => enum.outcomes.map(outcome => Str(outcome.normStr)) case decomp: DigitDecompositionEventDescriptorV0TLV => - val sign = decomp match { - case _: UnsignedDigitDecompositionEventDescriptor => - Vector.empty - case _: SignedDigitDecompositionEventDescriptor => - Vector(Str("+"), Str("-")) - } - val digits = 0.until(decomp.numDigits.toInt).map { _ => 0 .until(decomp.base.toInt) @@ -141,7 +134,12 @@ case class OracleRoutes(oracle: DLCOracleApi)(implicit .toVector } - val vecs = digits :+ sign + val vecs = decomp match { + case _: UnsignedDigitDecompositionEventDescriptor => + digits + case _: SignedDigitDecompositionEventDescriptor => + Vector(Str("+"), Str("-")) +: digits + } vecs.map(vec => Arr.from(vec)) } @@ -152,6 +150,15 @@ case class OracleRoutes(oracle: DLCOracleApi)(implicit ujson.Null } + val signedOutcomeJs = event match { + case _: PendingOracleEvent => + ujson.Null + case emum: CompletedEnumV0OracleEvent => + Str(emum.outcome.outcomeString) + case decomp: CompletedDigitDecompositionV0OracleEvent => + Num(decomp.outcomeBase10.toDouble) + } + val json = Obj( "nonces" -> event.nonces.map(n => Str(n.hex)), "eventName" -> Str(event.eventName), @@ -165,7 +172,8 @@ case class OracleRoutes(oracle: DLCOracleApi)(implicit "eventTLV" -> Str(event.eventTLV.hex), "announcementTLV" -> Str(event.announcementTLV.hex), "attestations" -> attestationJson, - "outcomes" -> outcomesJson + "outcomes" -> outcomesJson, + "signedOutcome" -> signedOutcomeJs ) Server.httpSuccess(json) case None => diff --git a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/DLCAttestationType.scala b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/DLCAttestationType.scala index 9b5ffacdce..4f2e26c232 100644 --- a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/DLCAttestationType.scala +++ b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/DLCAttestationType.scala @@ -13,14 +13,16 @@ case class EnumAttestation(outcomeString: String) extends DLCAttestationType { def bytes: ByteVector = CryptoUtil.serializeForHash(outcomeString) } +sealed trait DigitDecompositionAttestationType extends DLCAttestationType + case class DigitDecompositionSignAttestation(positive: Boolean) - extends DLCAttestationType { + extends DigitDecompositionAttestationType { override def outcomeString: String = if (positive) "+" else "-" def bytes: ByteVector = CryptoUtil.serializeForHash(outcomeString) } case class DigitDecompositionAttestation(outcome: Int) - extends DLCAttestationType { + extends DigitDecompositionAttestationType { override def outcomeString: String = outcome.toString def bytes: ByteVector = CryptoUtil.serializeForHash(outcomeString) } diff --git a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala index 1b32468f0f..4373acc862 100644 --- a/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala +++ b/core/src/main/scala/org/bitcoins/core/api/dlcoracle/OracleEvent.scala @@ -4,6 +4,7 @@ import org.bitcoins.core.api.dlcoracle.db.EventDb import org.bitcoins.core.number.UInt32 import org.bitcoins.core.protocol.dlc.SigningVersion import org.bitcoins.core.protocol.tlv._ +import org.bitcoins.core.util.NumberUtil import org.bitcoins.crypto._ import java.time.Instant @@ -70,6 +71,8 @@ sealed trait CompletedOracleEvent extends OracleEvent { outcomes.map(_.outcomeString)) def outcomes: Vector[DLCAttestationType] + + def dlcOutcome: DLCOutcomeType } sealed trait EnumV0OracleEvent extends OracleEvent { @@ -102,9 +105,16 @@ case class CompletedEnumV0OracleEvent( attestation: FieldElement) extends CompletedOracleEvent with EnumV0OracleEvent { + require(OracleEvent.verifyAttestations(announcementTLV, + oracleAttestmentV0TLV, + signingVersion), + "Signatures given are invalid") + override def attestations: Vector[FieldElement] = Vector(attestation) override def outcomes: Vector[DLCAttestationType] = Vector(outcome) + + override def dlcOutcome: DLCOutcomeType = EnumOutcome(outcome.outcomeString) } sealed trait DigitDecompositionV0OracleEvent extends OracleEvent { @@ -130,10 +140,42 @@ case class CompletedDigitDecompositionV0OracleEvent( maturationTime: Instant, announcementSignature: SchnorrDigitalSignature, eventDescriptorTLV: DigitDecompositionEventDescriptorV0TLV, - outcomes: Vector[DLCAttestationType], + dlcOutcome: NumericDLCOutcomeType, attestations: Vector[FieldElement]) extends CompletedOracleEvent - with DigitDecompositionV0OracleEvent + with DigitDecompositionV0OracleEvent { + + require(OracleEvent.verifyAttestations(announcementTLV, + oracleAttestmentV0TLV, + signingVersion), + "Signatures given are invalid") + + val outcomeBase10: Long = { + val (digits, positive) = dlcOutcome match { + case UnsignedNumericOutcome(digits) => + (digits, true) + case SignedNumericOutcome(positive, digits) => + (digits, positive) + } + + val base = eventDescriptorTLV.base.toInt + val numDigits = eventDescriptorTLV.numDigits.toInt + + val num = NumberUtil.fromDigits(digits, base, numDigits) + + if (positive) num + else num * -1 + } + + override def outcomes: Vector[DigitDecompositionAttestationType] = + dlcOutcome match { + case UnsignedNumericOutcome(digits) => + digits.map(DigitDecompositionAttestation) + case SignedNumericOutcome(positive, digits) => + val sign = DigitDecompositionSignAttestation(positive) + sign +: digits.map(DigitDecompositionAttestation) + } +} object OracleEvent { @@ -172,18 +214,18 @@ object OracleEvent { val attestations = sortedEventDbs.flatMap(_.attestationOpt) - val outcomes = decomp match { + val dlcOutcome = decomp match { case _: SignedDigitDecompositionEventDescriptor => - val sign = DigitDecompositionSignAttestation( - sortedEventDbs.head.outcomeOpt.get == "+") + val positive = sortedEventDbs.head.outcomeOpt.get == "+" val digits = sortedEventDbs.tail.map { eventDb => - DigitDecompositionAttestation(eventDb.outcomeOpt.get.toInt) + eventDb.outcomeOpt.get.toInt } - sign +: digits + SignedNumericOutcome(positive, digits) case _: UnsignedDigitDecompositionEventDescriptor => - sortedEventDbs.map { eventDb => - DigitDecompositionAttestation(eventDb.outcomeOpt.get.toInt) + val digits = sortedEventDbs.map { eventDb => + eventDb.outcomeOpt.get.toInt } + UnsignedNumericOutcome(digits) } CompletedDigitDecompositionV0OracleEvent( @@ -194,7 +236,7 @@ object OracleEvent { eventDb.maturationTime, eventDb.announcementSignature, decomp, - outcomes, + dlcOutcome, attestations ) case (decomp: DigitDecompositionEventDescriptorV0TLV, None) => diff --git a/core/src/main/scala/org/bitcoins/core/protocol/dlc/CETCalculator.scala b/core/src/main/scala/org/bitcoins/core/protocol/dlc/CETCalculator.scala index 1a59854c89..f4dc5df5e3 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/dlc/CETCalculator.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/dlc/CETCalculator.scala @@ -4,6 +4,7 @@ import org.bitcoins.core.currency.Satoshis import org.bitcoins.core.protocol.tlv.{ DLCOutcomeType, EnumOutcome, + SignedNumericOutcome, UnsignedNumericOutcome } import org.bitcoins.core.util.{Indexed, NumberUtil} @@ -281,7 +282,7 @@ object CETCalculator { digits: Digits, outcomes: Vector[DLCOutcomeType]): Option[UnsignedNumericOutcome] = { searchForPrefix(digits, outcomes) { - case outcome: EnumOutcome => + case outcome @ (_: EnumOutcome | _: SignedNumericOutcome) => throw new IllegalArgumentException( s"Expected Numeric Outcome, got $outcome") case UnsignedNumericOutcome(digits) => digits diff --git a/core/src/main/scala/org/bitcoins/core/protocol/dlc/OracleInfo.scala b/core/src/main/scala/org/bitcoins/core/protocol/dlc/OracleInfo.scala index f998ebd407..9b4f0ef530 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/dlc/OracleInfo.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/dlc/OracleInfo.scala @@ -132,7 +132,7 @@ case class EnumSingleOracleInfo(announcement: OracleAnnouncementTLV) sig) } } - case UnsignedNumericOutcome(_) => + case UnsignedNumericOutcome(_) | _: SignedNumericOutcome => throw new IllegalArgumentException( s"Expected EnumOutcome, got $outcome") } @@ -177,7 +177,7 @@ case class NumericSingleOracleInfo(announcement: OracleAnnouncementTLV) s"Too many signatures (expected at most ${nonces.length}), got $sigs") outcome match { - case EnumOutcome(_) => + case EnumOutcome(_) | _: SignedNumericOutcome => throw new IllegalArgumentException( s"Expected numeric outcome, got $outcome") case UnsignedNumericOutcome(digits) => diff --git a/core/src/main/scala/org/bitcoins/core/protocol/tlv/DLCOutcomeType.scala b/core/src/main/scala/org/bitcoins/core/protocol/tlv/DLCOutcomeType.scala index bcc0c3c3ae..5435d5130c 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/tlv/DLCOutcomeType.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/tlv/DLCOutcomeType.scala @@ -17,6 +17,8 @@ case class EnumOutcome(outcome: String) extends DLCOutcomeType { Vector(CryptoUtil.serializeForHash(outcome)) } +sealed trait NumericDLCOutcomeType extends DLCOutcomeType + /** An outcome from a multi-nonce unsigned numeric event type. * * If digits.length is less than the the total number of digits to be @@ -25,8 +27,27 @@ case class EnumOutcome(outcome: String) extends DLCOutcomeType { * * I.e. the Vector[Int] is always the most significant digits. */ -case class UnsignedNumericOutcome(digits: Vector[Int]) extends DLCOutcomeType { +case class UnsignedNumericOutcome(digits: Vector[Int]) + extends NumericDLCOutcomeType { override lazy val serialized: Vector[ByteVector] = digits.map(digit => CryptoUtil.serializeForHash(digit.toString)) } + +/** An outcome from a multi-nonce signed numeric event type. + * + * If digits.length is less than the the total number of digits to be + * signed by the oracle then this outcome represents all outcomes prefixed + * by the given digits. + * + * I.e. the Vector[Int] is always the most significant digits. + */ +case class SignedNumericOutcome(positive: Boolean, digits: Vector[Int]) + extends NumericDLCOutcomeType { + + private val signOutcomeStr = if (positive) "+" else "-" + + override lazy val serialized: Vector[ByteVector] = + CryptoUtil.serializeForHash(signOutcomeStr) +: + digits.map(digit => CryptoUtil.serializeForHash(digit.toString)) +} diff --git a/db-commons/src/main/scala/org/bitcoins/db/DbCommonsColumnMappers.scala b/db-commons/src/main/scala/org/bitcoins/db/DbCommonsColumnMappers.scala index 5bcfadb49f..e68aa852af 100644 --- a/db-commons/src/main/scala/org/bitcoins/db/DbCommonsColumnMappers.scala +++ b/db-commons/src/main/scala/org/bitcoins/db/DbCommonsColumnMappers.scala @@ -278,6 +278,8 @@ class DbCommonsColumnMappers(val profile: JdbcProfile) { s"$enumStr$outcome" case UnsignedNumericOutcome(digits) => s"$unsignedNumStr" + digits.mkString("|") + case _: SignedNumericOutcome => + throw new RuntimeException("Unknown outcome type") }, str => { if (str.startsWith(enumStr)) { @@ -307,6 +309,8 @@ class DbCommonsColumnMappers(val profile: JdbcProfile) { s"$enumStr$outcome" case UnsignedNumericOutcome(digits) => s"$unsignedNumStr" + digits.mkString("|") + case _: SignedNumericOutcome => + throw new RuntimeException("Unknown outcome type") } }.mkString, str => { diff --git a/docs/oracle/oracle-election-example.md b/docs/oracle/oracle-election-example.md index 3906e422de..24af0c9cca 100644 --- a/docs/oracle/oracle-election-example.md +++ b/docs/oracle/oracle-election-example.md @@ -106,6 +106,7 @@ If you use the `getevent` rpc along the oracle announcement, you can see the eve "Republican_win", "Democrat_win", "other" - ] + ], + "signedOutcome": "Democrat_win" } ``` diff --git a/docs/oracle/oracle-price-example.md b/docs/oracle/oracle-price-example.md index 499f72f096..caf96cec3a 100644 --- a/docs/oracle/oracle-price-example.md +++ b/docs/oracle/oracle-price-example.md @@ -257,9 +257,7 @@ If you use the `getevent` rpc along the oracle announcement, you can see the eve "0", "1" ], - [ - - ] + "signedOutcome": 42069 ] } ``` diff --git a/docs/oracle/oracle-server.md b/docs/oracle/oracle-server.md index 473fc6d6c7..b1470c9e85 100644 --- a/docs/oracle/oracle-server.md +++ b/docs/oracle/oracle-server.md @@ -14,7 +14,7 @@ checkout [this page](build-oracle-server.md). - `getpublickey` - Get oracle's public key - `getstakingaddress` - Get oracle's staking address -- `listevents` - Lists all oracle announcement TLVs +- `listevents` - Lists all event names - `createenumevent` `label` `maturationtime` `outcomes` - Registers an oracle enum event - `label` - Label for this event - `maturationtime` - The earliest expected time an outcome will be signed, given in ISO 8601 format @@ -70,7 +70,8 @@ $ bitcoin-s-cli getevent test "outcome1", "outcome2", "outcome3" - ] + ], + "signedOutcome": null } @@ -87,7 +88,7 @@ $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "createenum {"result":"fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","error":null} $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getevent", "params": ["testEvent"]}' -H "Content-Type: application/json" http://127.0.0.1:9998/ -{"result":{"nonces":["80e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f"],"eventName":"test","signingVersion":"DLCOracleV0SigningVersion","maturationTime":"2030-01-03T00:30:00.000Z","announcementSignature":"ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb90","eventDescriptorTLV":"fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d6533","eventTLV":"fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","announcementTLV":"fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","attestations":["33fd84ba8eea0a75f1568149f42e8466e1bc3422ea449532d4eeffad8586d14e"],"signatures":["80e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f33fd84ba8eea0a75f1568149f42e8466e1bc3422ea449532d4eeffad8586d14e"],"outcomes":["outcome1","outcome2","outcome3"]},"error":null} +{"result":{"nonces":["80e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f"],"eventName":"test","signingVersion":"DLCOracleV0SigningVersion","maturationTime":"2030-01-03T00:30:00.000Z","announcementSignature":"ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb90","eventDescriptorTLV":"fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d6533","eventTLV":"fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","announcementTLV":"fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","attestations":["33fd84ba8eea0a75f1568149f42e8466e1bc3422ea449532d4eeffad8586d14e"],"signatures":["80e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f33fd84ba8eea0a75f1568149f42e8466e1bc3422ea449532d4eeffad8586d14e"],"outcomes":["outcome1","outcome2","outcome3",],"signedOutcome": null},"error":null} $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "signevent", "params": ["testEvent", "outcome1"]}' -H "Content-Type: application/json" http://127.0.0.1:9998/ {"result":"fdd8687004746573745f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f33fd84ba8eea0a75f1568149f42e8466e1bc3422ea449532d4eeffad8586d14e086f7574636f6d6531","error":null} @@ -162,7 +163,8 @@ $ bitcoins-cli getevent exampleNumeric "+", "-" ] - ] + ], + "signedOutcome": null } @@ -177,7 +179,7 @@ $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "createnume {"result":"fdd824fd0110647c85d333aa6fc0d7808201da9d1010b815710dc25c3d73e9cc7a7f372a7342c99144ba74d70be72920f4515daa6565bce12aedfc5a828ee37b5453454c1b575f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd822ac0004d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf37051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c47446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd4756217139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d2657131d1fdd80a0f000a0105756e697473000000000003126578616d706c6544696769744465636f6d70","error":null} $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getevent", "params": ["numericExample"]}' -H "Content-Type: application/json" http://127.0.0.1:9998/ -{"result":{"nonces":["7051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c4","7139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d2","7446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621","d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3"],"eventName":"numericExample","signingVersion":"DLCOracleV0SigningVersion","maturationTime":"2030-01-03T00:30:00.000Z","announcementSignature":"647c85d333aa6fc0d7808201da9d1010b815710dc25c3d73e9cc7a7f372a7342c99144ba74d70be72920f4515daa6565bce12aedfc5a828ee37b5453454c1b57","eventDescriptorTLV":"fdd80a0f000a0105756e697473000000000003","eventTLV":"fdd822ac00047051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c47139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d27446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3657131d1fdd80a0f000a0105756e697473000000000003126578616d706c6544696769744465636f6d70","announcementTLV":"fdd824fd0110647c85d333aa6fc0d7808201da9d1010b815710dc25c3d73e9cc7a7f372a7342c99144ba74d70be72920f4515daa6565bce12aedfc5a828ee37b5453454c1b575f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd822ac00047051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c47139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d27446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3657131d1fdd80a0f000a0105756e697473000000000003126578616d706c6544696769744465636f6d70","attestations":null,"signatures":null,"outcomes":[["0","1","2","3","4","5","6","7","8","9"],["0","1","2","3","4","5","6","7","8","9"],["0","1","2","3","4","5","6","7","8","9"],["+","-"]]},"error":null} +{"result":{"nonces":["7051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c4","7139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d2","7446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621","d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3"],"eventName":"numericExample","signingVersion":"DLCOracleV0SigningVersion","maturationTime":"2030-01-03T00:30:00.000Z","announcementSignature":"647c85d333aa6fc0d7808201da9d1010b815710dc25c3d73e9cc7a7f372a7342c99144ba74d70be72920f4515daa6565bce12aedfc5a828ee37b5453454c1b57","eventDescriptorTLV":"fdd80a0f000a0105756e697473000000000003","eventTLV":"fdd822ac00047051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c47139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d27446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3657131d1fdd80a0f000a0105756e697473000000000003126578616d706c6544696769744465636f6d70","announcementTLV":"fdd824fd0110647c85d333aa6fc0d7808201da9d1010b815710dc25c3d73e9cc7a7f372a7342c99144ba74d70be72920f4515daa6565bce12aedfc5a828ee37b5453454c1b575f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd822ac00047051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c47139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d27446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3657131d1fdd80a0f000a0105756e697473000000000003126578616d706c6544696769744465636f6d70","attestations":null,"signatures":null,"outcomes":[["0","1","2","3","4","5","6","7","8","9"],["0","1","2","3","4","5","6","7","8","9"],["0","1","2","3","4","5","6","7","8","9"],["+","-"]],"signedOutcome": null},"error":null} $ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "signdigits", "params": ["numericExample", 123]}' -H "Content-Type: application/json" http://127.0.0.1:9998/ {"result":"fdd868fd013d126578616d706c6544696769744465636f6d705f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e521150004d72282a2e9532924dc8cd79685a501202332ad0d118166328cb76138414fccf3d0646c9efd9523274014841ba24bf63219d5650d1682209d7e48af009d58e6d87051e50fd1ab30df4717da8905e400a32c5f4d793a4ac5433ed416165dd286c4c025dfd1e39de77e0418fa7d39abf2e9daf55d7fe34f8e312368cb4d45b4d4b97446ab1d71a550a0d604c3e86c40a3c9b12de8f08a86639068707822cd475621700347c52af088eda9a0245385094518134e73bb997102e11f6de0aeb36af7237139d7cabd19d6b0b9e827cdf84a4fc18c88d1882e4e096d8dfeff58759504d2f9e7a9e183b0836ad58dd646d9ab123132397109e4f51c5842958932a81bacd1012b013101320133","error":null}