Beispiel #1
0
        protected override async Task InvokeAsyncBase(InvocationContext context)
        {
            var name = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("name")?.Trim();

            if (name is null)
            {
                throw new CommandOptionRequiredException("name");
            }
            var dlc = await GetDLC("name", name);

            if (dlc?.BuilderState is null ||
                dlc?.OracleInfo is null)
            {
                throw new CommandException("name", "This DLC does not exist");
            }
            var builder = new DLCTransactionBuilder(dlc.BuilderState.ToString(), Network);
            var psbt    = context.ParsePSBT("signedpsbt", Network);

            if (!builder.State.IsInitiator)
            {
                context.AssertState("name", dlc, false, DLCNextStep.Fund, Network);
                var fullySigned = builder.Finalize(psbt);
                dlc.BuilderState = builder.ExportStateJObject();
                await Repository.SaveDLC(dlc);

                context.WriteTransaction(fullySigned, builder.State.Funding?.FundCoin, Network);
            }
            else
            {
                context.AssertState("name", dlc, true, DLCNextStep.Fund, Network);
                var key = await Repository.GetKey(dlc.FundKeyPath !);

                try
                {
                    var sign = builder.Sign2(key, psbt);
                    dlc.Sign         = sign;
                    dlc.BuilderState = builder.ExportStateJObject();
                    await Repository.SaveDLC(dlc);

                    context.WriteObject(sign, Repository.JsonSettings);
                }
                catch (Exception ex)
                {
                    throw new CommandException("signedpsbt", $"Invalid PSBT. ({ex.Message})");
                }
            }
        }
Beispiel #2
0
        public async Task <DLCState> NewDLC(OracleInfo oracleInfo, DLCTransactionBuilder builder)
        {
            var dir = Path.Combine(RepositoryDirectory, "DLCs");

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            var s = new DLCState()
            {
                OracleInfo   = oracleInfo,
                BuilderState = builder.ExportStateJObject(),
                Id           = RandomUtils.GetUInt256()
            };
            var file = GetDLCFilePath(s.Id);
            await File.WriteAllTextAsync(file, JsonConvert.SerializeObject(s, JsonSettings));

            return(s);
        }
Beispiel #3
0
        protected override async Task InvokeAsyncBase(InvocationContext context)
        {
            var offer = DLCHelpers.GetOffer(context, Repository.JsonSettings);
            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");
            }
            if (offer.OracleInfo is null)
            {
                throw new CommandException("offer", "Missing oracleInfo");
            }
            if (offer.Timeouts is null)
            {
                throw new CommandException("offer", "Missing timeouts");
            }
            if (offer.ContractInfo is null)
            {
                throw new CommandException("offer", "Missing contractInfos");
            }

            var oracle = await Repository.GetOracle(offer.OracleInfo.PubKey);

            if (oracle is null)
            {
                throw new CommandException("offer", "Unknown oracle");
            }
            var evt = await Repository.GetEvent(offer.OracleInfo.PubKey, offer.OracleInfo.RValue);

            if (evt is null)
            {
                throw new CommandException("offer", "Unknown event");
            }

            var maturity = new LockTimeEstimation(offer.Timeouts.ContractMaturity, Network);
            var refund   = new LockTimeEstimation(offer.Timeouts.ContractTimeout, Network);

            if (!refund.UnknownEstimation)
            {
                if (refund.EstimatedRemainingBlocks == 0)
                {
                    throw new CommandException("offer", "The refund should not be immediately valid");
                }
                if (refund.EstimatedRemainingBlocks < maturity.EstimatedRemainingBlocks)
                {
                    throw new CommandException("offer", "The refund should not be valid faster than the contract execution transactions");
                }
            }

            offer.SetContractPreimages(evt.Outcomes);
            try
            {
                var builder = new DLCTransactionBuilder(false, null, null, null, Network);
                builder.Accept(offer);
                var dlc = await Repository.NewDLC(offer.OracleInfo, builder);

                dlc.BuilderState = builder.ExportStateJObject();
                dlc.Offer        = JObject.FromObject(offer, JsonSerializer.Create(Repository.JsonSettings));
                await NameRepository.AsDLCNameRepository().SetMapping(name, dlc.Id);

                await Repository.SaveDLC(dlc);

                context.Console.Out.Write($"Contract accepted, you now need to setup the DLC. For more information, run `dlc show \"{name}\"`.");
            }
            catch (Exception ex)
            {
                throw new CommandException("offer", $"Invalid offer or PSBT. ({ex.Message})");
            }
        }