protected override async Task InvokeAsyncBase(InvocationContext context) { EventFullName evt = context.GetEventName(); if (await Repository.GetEvent(evt) is Event) { throw new CommandException("name", "This event already exists"); } var outcomes = context.GetOutcomes(); var oracle = await Repository.GetOracle(evt.OracleName); if (oracle is null) { throw new CommandException("name", "This oracle does not exists"); } if (oracle.RootedKeyPath is null) { throw new CommandException("name", "You do not own the keys of this oracle"); } var k = await Repository.CreatePrivateKey(); var nonce = k.PrivateKey.ToECPrivKey().CreateSchnorrNonce(); if (!await Repository.AddEvent(evt, nonce, outcomes, k.KeyPath)) { throw new CommandException("name", "This event already exists"); } context.Console.Out.Write(nonce.ToString()); }
protected override async Task InvokeAsyncBase(InvocationContext context) { var attestation = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("attestation")?.Trim(); if (attestation is null) { throw new CommandOptionRequiredException("attestation"); } var bytes = Encoders.Hex.DecodeData(attestation); if (bytes.Length != 32) { throw new CommandException("attestation", "The attestation must be 32 bytes"); } var attestationKey = new Key(bytes); EventFullName evt = context.GetEventName(); var oracle = await Repository.GetOracle(evt.OracleName); if (oracle is null) { throw new CommandException("name", "This oracle does not exists"); } var outcome = await Repository.AddAttestation(evt, attestationKey); if (outcome?.OutcomeString is null) { throw new CommandException("attestation", "This attestation does not attest known outcomes"); } context.Console.Out.Write(outcome.OutcomeString); }
protected override async Task InvokeAsyncBase(InvocationContext context) { EventFullName evt = context.GetEventName(); if (await TryGetEvent(evt) is Event) { throw new CommandException("eventfullname", "This event already exists"); } var outcomes = context.GetOutcomes(); var oracle = await this.GetOracle("eventfullname", evt.OracleName); if (oracle.RootedKeyPath is null) { throw new CommandException("eventfullname", "You do not own the keys of this oracle"); } var k = await Repository.CreatePrivateKey(); var nonce = k.PrivateKey.ToECPrivKey().CreateSchnorrNonce(); var evtId = new OracleInfo(oracle.PubKey !, nonce); if (!await Repository.AddEvent(evtId, outcomes, k.KeyPath)) { throw new CommandException("eventfullname", "This event already exists"); } await NameRepository.AsEventRepository().SetMapping(evtId, evt.Name); context.Console.Out.Write(nonce.ToString()); }
protected override async Task InvokeAsyncBase(InvocationContext context) { EventFullName evt = context.GetEventName(); var rNonce = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("nonce")?.ToLowerInvariant().Trim(); if (rNonce is null) { throw new CommandOptionRequiredException("nonce"); } if (!SchnorrNonce.TryParse(rNonce, out var nonce) || nonce is null) { throw new CommandException("nonce", "Invalid nonce"); } var oracle = await GetOracle("eventfullname", evt.OracleName); var outcomes = context.GetOutcomes(); var evtId = new OracleInfo(oracle.PubKey !, nonce); if (!await Repository.AddEvent(evtId, outcomes.ToArray())) { throw new CommandException("eventfullname", "The specified event already exists"); } await NameRepository.AsEventRepository().SetMapping(evtId, evt.Name); }
protected override async Task InvokeAsyncBase(InvocationContext context) { var evtName = context.GetEventName(); var evt = await GetEvent("name", evtName); var oracle = await GetOracle("name", evtName.OracleName); context.Console.Out.WriteLine($"Full Name: {evtName}"); context.Console.Out.WriteLine($"Name: {evtName.Name}"); context.Console.Out.WriteLine($"Nonce: {evt.EventId!.RValue}"); context.Console.Out.WriteLine($"Can reveal: {oracle.RootedKeyPath is RootedKeyPath}"); int i = 0; foreach (var outcome in evt.Outcomes) { context.Console.Out.WriteLine($"Outcome[{i}]: {outcome}"); i++; } if (evt.Attestations is Dictionary <string, Key> ) { foreach (var kv in evt.Attestations) { context.Console.Out.WriteLine($"Attestation[\"{kv.Key}\"]: {kv.Value.ToHex()}"); } } }
protected override async Task InvokeAsyncBase(InvocationContext context) { var outcome = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("outcome")?.Trim(); var force = context.ParseResult.ValueForOption <bool>("force"); if (outcome is null) { throw new CommandOptionRequiredException("outcome"); } EventFullName evt = context.GetEventName(); var oracle = await Repository.GetOracle(evt.OracleName); if (oracle is null) { throw new CommandException("name", "This oracle does not exists"); } var discreteOutcome = new DiscreteOutcome(outcome); var evtObj = await Repository.GetEvent(evt); if (evtObj?.Nonce is null) { throw new CommandException("name", "This event does not exists"); } if (evtObj?.NonceKeyPath is null) { throw new CommandException("name", "You did not generated this event"); } outcome = evtObj.Outcomes.FirstOrDefault(o => o.Equals(outcome, StringComparison.OrdinalIgnoreCase)); if (outcome is null) { throw new CommandException("outcome", "This outcome does not exists in this event"); } var key = oracle.RootedKeyPath is RootedKeyPath ? await Repository.GetKey(oracle.RootedKeyPath) : null; if (key is null) { throw new CommandException("name", "You do not own the keys of this oracle"); } if (evtObj.Attestations?.ContainsKey(outcome) is true) { throw new CommandException("outcome", "This outcome has already been attested"); } if (evtObj.Attestations != null && evtObj.Attestations.Count > 0 && !force) { throw new CommandException("outcome", "An outcome has already been attested, attesting another one could leak the private key of your oracle. Use -f to force your action."); } var kValue = await Repository.GetKey(evtObj.NonceKeyPath); key.ToECPrivKey().TrySignBIP140(discreteOutcome.Hash, new PrecomputedNonceFunctionHardened(kValue.ToECPrivKey().ToBytes()), out var sig); var oracleAttestation = new Key(sig !.s.ToBytes()); if (await Repository.AddAttestation(evt, oracleAttestation) != outcome) { throw new InvalidOperationException("Error while validating reveal"); } context.Console.Out.Write(oracleAttestation.ToHex()); }
protected override async Task InvokeAsyncBase(InvocationContext context) { var name = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("name")?.Trim(); if (name is null) { throw new CommandOptionRequiredException("name"); } if (await this.TryGetDLC(name) != null) { throw new CommandException("name", "This DLC already exists"); } EventFullName evtName = context.GetEventName(); var oracle = await GetOracle("eventfullname", evtName.OracleName); if (oracle?.PubKey is null) { throw new CommandException("eventfullname", "The specified oracle does not exists"); } var evt = await GetEvent("eventfullname", evtName); var payoffsStr = context.ParseResult.CommandResult.GetArgumentValueOrDefault <List <string> >("payoff"); if (payoffsStr is null || payoffsStr.Count == 0) { throw new CommandOptionRequiredException("payoff"); } var payoffs = CreatePayoffs(payoffsStr); FixCasing(evt, payoffs); var builder = new DLCTransactionBuilder(true, null, null, null, Network); var timeout = new Timeouts() { ContractMaturity = 0, ContractTimeout = Constants.NeverLockTime }; if (context.ParseResult.HasOption("cetlocktime")) { timeout.ContractMaturity = new LockTime(context.ParseResult.ValueForOption <uint>("cetlocktime")); } if (context.ParseResult.HasOption("refundlocktime")) { timeout.ContractTimeout = new LockTime(context.ParseResult.ValueForOption <uint>("refundlocktime")); } var collateral = payoffs.CalculateMinimumCollateral(); builder.Offer(oracle.PubKey, evt.EventId !.RValue, payoffs, timeout); var dlc = await Repository.NewDLC(evt.EventId, builder); await NameRepository.AsDLCNameRepository().SetMapping(name, dlc.LocalId); context.Console.Out.Write($"Offer created, you now need to setup the DLC sending {collateral} BTC to yourself. For more information, run `dlc show \"{name}\"`."); }