mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
Lightning Loop initial version
This commit is contained in:
parent
c5eecda492
commit
21fcd8d94e
60 changed files with 9236 additions and 8 deletions
300
cmd/swapcli/main.go
Normal file
300
cmd/swapcli/main.go
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/lightninglabs/nautilus/utils"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
|
||||
"github.com/lightninglabs/nautilus/cmd/swapd/rpc"
|
||||
"github.com/urfave/cli"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var (
|
||||
swapdAddress = "localhost:11010"
|
||||
|
||||
// Define route independent max routing fees. We have currently no way
|
||||
// to get a reliable estimate of the routing fees. Best we can do is the
|
||||
// minimum routing fees, which is not very indicative.
|
||||
maxRoutingFeeBase = btcutil.Amount(10)
|
||||
maxRoutingFeeRate = int64(50000)
|
||||
)
|
||||
|
||||
var unchargeCommand = cli.Command{
|
||||
Name: "uncharge",
|
||||
Usage: "perform an off-chain to on-chain swap",
|
||||
ArgsUsage: "amt [addr]",
|
||||
Description: `
|
||||
Send the amount in satoshis specified by the amt argument on-chain.
|
||||
|
||||
Optionally a BASE58 encoded bitcoin destination address may be
|
||||
specified. If not specified, a new wallet address will be generated.`,
|
||||
Flags: []cli.Flag{
|
||||
cli.Uint64Flag{
|
||||
Name: "channel",
|
||||
Usage: "the 8-byte compact channel ID of the channel to uncharge",
|
||||
},
|
||||
},
|
||||
Action: uncharge,
|
||||
}
|
||||
|
||||
var termsCommand = cli.Command{
|
||||
Name: "terms",
|
||||
Usage: "show current server swap terms",
|
||||
Action: terms,
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Version = "0.0.1"
|
||||
app.Usage = "command line interface to swapd"
|
||||
app.Commands = []cli.Command{unchargeCommand, termsCommand}
|
||||
app.Action = monitor
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func terms(ctx *cli.Context) error {
|
||||
client, cleanup, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
terms, err := client.GetUnchargeTerms(
|
||||
context.Background(), &rpc.TermsRequest{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Amount: %d - %d\n",
|
||||
btcutil.Amount(terms.MinSwapAmount),
|
||||
btcutil.Amount(terms.MaxSwapAmount),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printTerms := func(terms *rpc.TermsResponse) {
|
||||
fmt.Printf("Amount: %d - %d\n",
|
||||
btcutil.Amount(terms.MinSwapAmount),
|
||||
btcutil.Amount(terms.MaxSwapAmount),
|
||||
)
|
||||
fmt.Printf("Fee: %d + %.4f %% (%d prepaid)\n",
|
||||
btcutil.Amount(terms.SwapFeeBase),
|
||||
utils.FeeRateAsPercentage(terms.SwapFeeRate),
|
||||
btcutil.Amount(terms.PrepayAmt),
|
||||
)
|
||||
|
||||
fmt.Printf("Cltv delta: %v blocks\n", terms.CltvDelta)
|
||||
}
|
||||
|
||||
fmt.Println("Uncharge")
|
||||
fmt.Println("--------")
|
||||
printTerms(terms)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func monitor(ctx *cli.Context) error {
|
||||
client, cleanup, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
stream, err := client.Monitor(
|
||||
context.Background(), &rpc.MonitorRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
swap, err := stream.Recv()
|
||||
if err != nil {
|
||||
return fmt.Errorf("recv: %v", err)
|
||||
}
|
||||
logSwap(swap)
|
||||
}
|
||||
}
|
||||
|
||||
func getClient(ctx *cli.Context) (rpc.SwapClientClient, func(), error) {
|
||||
conn, err := getSwapCliConn(swapdAddress)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
cleanup := func() { conn.Close() }
|
||||
|
||||
swapCliClient := rpc.NewSwapClientClient(conn)
|
||||
return swapCliClient, cleanup, nil
|
||||
}
|
||||
|
||||
func getMaxRoutingFee(amt btcutil.Amount) btcutil.Amount {
|
||||
return utils.CalcFee(amt, maxRoutingFeeBase, maxRoutingFeeRate)
|
||||
}
|
||||
|
||||
type limits struct {
|
||||
maxSwapRoutingFee btcutil.Amount
|
||||
maxPrepayRoutingFee btcutil.Amount
|
||||
maxMinerFee btcutil.Amount
|
||||
maxSwapFee btcutil.Amount
|
||||
maxPrepayAmt btcutil.Amount
|
||||
}
|
||||
|
||||
func getLimits(amt btcutil.Amount, quote *rpc.QuoteResponse) *limits {
|
||||
return &limits{
|
||||
maxSwapRoutingFee: getMaxRoutingFee(btcutil.Amount(amt)),
|
||||
maxPrepayRoutingFee: getMaxRoutingFee(btcutil.Amount(
|
||||
quote.PrepayAmt,
|
||||
)),
|
||||
|
||||
// Apply a multiplier to the estimated miner fee, to not get the swap
|
||||
// canceled because fees increased in the mean time.
|
||||
maxMinerFee: btcutil.Amount(quote.MinerFee) * 3,
|
||||
|
||||
maxSwapFee: btcutil.Amount(quote.SwapFee),
|
||||
maxPrepayAmt: btcutil.Amount(quote.PrepayAmt),
|
||||
}
|
||||
}
|
||||
|
||||
func displayLimits(amt btcutil.Amount, l *limits) error {
|
||||
totalSuccessMax := l.maxSwapRoutingFee + l.maxPrepayRoutingFee +
|
||||
l.maxMinerFee + l.maxSwapFee
|
||||
|
||||
fmt.Printf("Max swap fees for %d uncharge: %d\n",
|
||||
btcutil.Amount(amt), totalSuccessMax,
|
||||
)
|
||||
fmt.Printf("CONTINUE SWAP? (y/n), expand fee detail (x): ")
|
||||
var answer string
|
||||
fmt.Scanln(&answer)
|
||||
switch answer {
|
||||
case "y":
|
||||
return nil
|
||||
case "x":
|
||||
fmt.Println()
|
||||
fmt.Printf("Max on-chain fee: %d\n", l.maxMinerFee)
|
||||
fmt.Printf("Max off-chain swap routing fee: %d\n",
|
||||
l.maxSwapRoutingFee)
|
||||
fmt.Printf("Max off-chain prepay routing fee: %d\n",
|
||||
l.maxPrepayRoutingFee)
|
||||
fmt.Printf("Max swap fee: %d\n", l.maxSwapFee)
|
||||
fmt.Printf("Max no show penalty: %d\n",
|
||||
l.maxPrepayAmt)
|
||||
|
||||
fmt.Printf("CONTINUE SWAP? (y/n): ")
|
||||
fmt.Scanln(&answer)
|
||||
if answer == "y" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("swap canceled")
|
||||
}
|
||||
|
||||
func parseAmt(text string) (btcutil.Amount, error) {
|
||||
amtInt64, err := strconv.ParseInt(text, 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid amt value")
|
||||
}
|
||||
return btcutil.Amount(amtInt64), nil
|
||||
}
|
||||
|
||||
func uncharge(ctx *cli.Context) error {
|
||||
// Show command help if no arguments and flags were provided.
|
||||
if ctx.NArg() < 1 {
|
||||
cli.ShowCommandHelp(ctx, "uncharge")
|
||||
return nil
|
||||
}
|
||||
|
||||
args := ctx.Args()
|
||||
|
||||
amt, err := parseAmt(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var destAddr string
|
||||
args = args.Tail()
|
||||
if args.Present() {
|
||||
destAddr = args.First()
|
||||
}
|
||||
|
||||
client, cleanup, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
quote, err := client.GetUnchargeQuote(
|
||||
context.Background(),
|
||||
&rpc.QuoteRequest{
|
||||
Amt: int64(amt),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
limits := getLimits(amt, quote)
|
||||
|
||||
if err := displayLimits(amt, limits); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var unchargeChannel uint64
|
||||
if ctx.IsSet("channel") {
|
||||
unchargeChannel = ctx.Uint64("channel")
|
||||
}
|
||||
|
||||
resp, err := client.Uncharge(context.Background(), &rpc.UnchargeRequest{
|
||||
Amt: int64(amt),
|
||||
Dest: destAddr,
|
||||
MaxMinerFee: int64(limits.maxMinerFee),
|
||||
MaxPrepayAmt: int64(limits.maxPrepayAmt),
|
||||
MaxSwapFee: int64(limits.maxSwapFee),
|
||||
MaxPrepayRoutingFee: int64(limits.maxPrepayRoutingFee),
|
||||
MaxSwapRoutingFee: int64(limits.maxSwapRoutingFee),
|
||||
UnchargeChannel: unchargeChannel,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Swap initiated with id: %v\n", resp.Id[:8])
|
||||
fmt.Printf("Run swapcli without a command to monitor progress.\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func logSwap(swap *rpc.SwapStatus) {
|
||||
fmt.Printf("%v %v %v %v - %v\n",
|
||||
time.Unix(0, swap.LastUpdateTime).Format(time.RFC3339),
|
||||
swap.Type, swap.State, btcutil.Amount(swap.Amt),
|
||||
swap.HtlcAddress,
|
||||
)
|
||||
}
|
||||
|
||||
func getSwapCliConn(address string) (*grpc.ClientConn, error) {
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithInsecure(),
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(address, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to connect to RPC server: %v", err)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
156
cmd/swapd/daemon.go
Normal file
156
cmd/swapd/daemon.go
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/lightninglabs/nautilus/client"
|
||||
clientrpc "github.com/lightninglabs/nautilus/cmd/swapd/rpc"
|
||||
"github.com/urfave/cli"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// daemon runs swapd in daemon mode. It will listen for grpc connections,
|
||||
// execute commands and pass back swap status information.
|
||||
func daemon(ctx *cli.Context) error {
|
||||
lnd, err := getLnd(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lnd.Close()
|
||||
|
||||
swapClient, cleanup, err := getClient(ctx, &lnd.LndServices)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
// Before starting the client, build an in-memory view of all swaps.
|
||||
// This view is used to update newly connected clients with the most
|
||||
// recent swaps.
|
||||
storedSwaps, err := swapClient.GetUnchargeSwaps()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, swap := range storedSwaps {
|
||||
swaps[swap.Hash] = client.SwapInfo{
|
||||
SwapType: client.SwapTypeUncharge,
|
||||
SwapContract: swap.Contract.SwapContract,
|
||||
State: swap.State(),
|
||||
SwapHash: swap.Hash,
|
||||
LastUpdate: swap.LastUpdateTime(),
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate the swapd gRPC server.
|
||||
server := swapClientServer{
|
||||
impl: swapClient,
|
||||
lnd: &lnd.LndServices,
|
||||
}
|
||||
|
||||
serverOpts := []grpc.ServerOption{}
|
||||
grpcServer := grpc.NewServer(serverOpts...)
|
||||
clientrpc.RegisterSwapClientServer(grpcServer, &server)
|
||||
|
||||
// Next, Start the gRPC server listening for HTTP/2 connections.
|
||||
logger.Infof("Starting RPC listener")
|
||||
lis, err := net.Listen("tcp", defaultListenAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("RPC server unable to listen on %s",
|
||||
defaultListenAddr)
|
||||
|
||||
}
|
||||
defer lis.Close()
|
||||
|
||||
statusChan := make(chan client.SwapInfo)
|
||||
|
||||
mainCtx, cancel := context.WithCancel(context.Background())
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Start the swap client itself.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
logger.Infof("Starting swap client")
|
||||
err := swapClient.Run(mainCtx, statusChan)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
}
|
||||
logger.Infof("Swap client stopped")
|
||||
|
||||
logger.Infof("Stopping gRPC server")
|
||||
grpcServer.Stop()
|
||||
|
||||
cancel()
|
||||
}()
|
||||
|
||||
// Start a goroutine that broadcasts swap updates to clients.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
logger.Infof("Waiting for updates")
|
||||
for {
|
||||
select {
|
||||
case swap := <-statusChan:
|
||||
swapsLock.Lock()
|
||||
swaps[swap.SwapHash] = swap
|
||||
|
||||
for _, subscriber := range subscribers {
|
||||
select {
|
||||
case subscriber <- swap:
|
||||
case <-mainCtx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
swapsLock.Unlock()
|
||||
case <-mainCtx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the grpc server.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
logger.Infof("RPC server listening on %s", lis.Addr())
|
||||
|
||||
err = grpcServer.Serve(lis)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
}
|
||||
}()
|
||||
|
||||
interruptChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(interruptChannel, os.Interrupt)
|
||||
|
||||
// Run until the users terminates swapd or an error occurred.
|
||||
select {
|
||||
case <-interruptChannel:
|
||||
logger.Infof("Received SIGINT (Ctrl+C).")
|
||||
|
||||
// TODO: Remove debug code.
|
||||
// Debug code to dump goroutines on hanging exit.
|
||||
go func() {
|
||||
time.Sleep(5 * time.Second)
|
||||
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
||||
}()
|
||||
|
||||
cancel()
|
||||
case <-mainCtx.Done():
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
24
cmd/swapd/log.go
Normal file
24
cmd/swapd/log.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/btcsuite/btclog"
|
||||
)
|
||||
|
||||
// log is a logger that is initialized with no output filters. This
|
||||
// means the package will not perform any logging by default until the caller
|
||||
// requests it.
|
||||
var (
|
||||
backendLog = btclog.NewBackend(logWriter{})
|
||||
logger = backendLog.Logger("SWAPD")
|
||||
)
|
||||
|
||||
// logWriter implements an io.Writer that outputs to both standard output and
|
||||
// the write-end pipe of an initialized log rotator.
|
||||
type logWriter struct{}
|
||||
|
||||
func (logWriter) Write(p []byte) (n int, err error) {
|
||||
os.Stdout.Write(p)
|
||||
return len(p), nil
|
||||
}
|
||||
70
cmd/swapd/main.go
Normal file
70
cmd/swapd/main.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightninglabs/nautilus/client"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultListenPort = 11010
|
||||
defaultConfTarget = int32(2)
|
||||
)
|
||||
|
||||
var (
|
||||
defaultListenAddr = fmt.Sprintf("localhost:%d", defaultListenPort)
|
||||
defaultSwapletDir = btcutil.AppDataDir("swaplet", false)
|
||||
|
||||
swaps = make(map[lntypes.Hash]client.SwapInfo)
|
||||
subscribers = make(map[int]chan<- interface{})
|
||||
nextSubscriberID int
|
||||
swapsLock sync.Mutex
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "network",
|
||||
Value: "mainnet",
|
||||
Usage: "network to run on (regtest, testnet, mainnet)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "lnd",
|
||||
Value: "localhost:10009",
|
||||
Usage: "lnd instance rpc address host:port",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "swapserver",
|
||||
Value: "swap.lightning.today:11009",
|
||||
Usage: "swap server address host:port",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "macaroonpath",
|
||||
Usage: "path to lnd macaroon",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tlspath",
|
||||
Usage: "path to lnd tls certificate",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "insecure",
|
||||
Usage: "disable tls",
|
||||
},
|
||||
}
|
||||
app.Version = "0.0.1"
|
||||
app.Usage = "swaps execution daemon"
|
||||
app.Commands = []cli.Command{viewCommand}
|
||||
app.Action = daemon
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
7
cmd/swapd/rpc/gen_protos.sh
Executable file
7
cmd/swapd/rpc/gen_protos.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Generate the protos.
|
||||
protoc -I/usr/local/include -I. \
|
||||
-I$GOPATH/src \
|
||||
--go_out=plugins=grpc:. \
|
||||
swapclient.proto
|
||||
925
cmd/swapd/rpc/swapclient.pb.go
Normal file
925
cmd/swapd/rpc/swapclient.pb.go
Normal file
|
|
@ -0,0 +1,925 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: swapclient.proto
|
||||
|
||||
package rpc
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type SwapType int32
|
||||
|
||||
const (
|
||||
// UNCHARGE indicates an uncharge swap (off-chain to on-chain)
|
||||
SwapType_UNCHARGE SwapType = 0
|
||||
)
|
||||
|
||||
var SwapType_name = map[int32]string{
|
||||
0: "UNCHARGE",
|
||||
}
|
||||
var SwapType_value = map[string]int32{
|
||||
"UNCHARGE": 0,
|
||||
}
|
||||
|
||||
func (x SwapType) String() string {
|
||||
return proto.EnumName(SwapType_name, int32(x))
|
||||
}
|
||||
func (SwapType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{0}
|
||||
}
|
||||
|
||||
type SwapState int32
|
||||
|
||||
const (
|
||||
// *
|
||||
// INITIATED is the initial state of a swap. At that point, the initiation
|
||||
// call to the server has been made and the payment process has been started
|
||||
// for the swap and prepayment invoices.
|
||||
SwapState_INITIATED SwapState = 0
|
||||
// *
|
||||
// PREIMAGE_REVEALED is reached when the sweep tx publication is first
|
||||
// attempted. From that point on, we should consider the preimage to no
|
||||
// longer be secret and we need to do all we can to get the sweep confirmed.
|
||||
// This state will mostly coalesce with StateHtlcConfirmed, except in the
|
||||
// case where we wait for fees to come down before we sweep.
|
||||
SwapState_PREIMAGE_REVEALED SwapState = 1
|
||||
// *
|
||||
// SUCCESS is the final swap state that is reached when the sweep tx has
|
||||
// the required confirmation depth.
|
||||
SwapState_SUCCESS SwapState = 3
|
||||
// *
|
||||
// FAILED is the final swap state for a failed swap with or without loss of
|
||||
// the swap amount.
|
||||
SwapState_FAILED SwapState = 4
|
||||
)
|
||||
|
||||
var SwapState_name = map[int32]string{
|
||||
0: "INITIATED",
|
||||
1: "PREIMAGE_REVEALED",
|
||||
3: "SUCCESS",
|
||||
4: "FAILED",
|
||||
}
|
||||
var SwapState_value = map[string]int32{
|
||||
"INITIATED": 0,
|
||||
"PREIMAGE_REVEALED": 1,
|
||||
"SUCCESS": 3,
|
||||
"FAILED": 4,
|
||||
}
|
||||
|
||||
func (x SwapState) String() string {
|
||||
return proto.EnumName(SwapState_name, int32(x))
|
||||
}
|
||||
func (SwapState) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{1}
|
||||
}
|
||||
|
||||
type UnchargeRequest struct {
|
||||
// *
|
||||
// Requested swap amount in sat. This does not include the swap and miner
|
||||
// fee.
|
||||
Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"`
|
||||
// *
|
||||
// Base58 encoded destination address for the swap.
|
||||
Dest string `protobuf:"bytes,2,opt,name=dest,proto3" json:"dest,omitempty"`
|
||||
// *
|
||||
// Maximum off-chain fee in msat that may be paid for payment to the server.
|
||||
// This limit is applied during path finding. Typically this value is taken
|
||||
// from the response of the GetQuote call.
|
||||
MaxSwapRoutingFee int64 `protobuf:"varint,3,opt,name=max_swap_routing_fee,json=maxSwapRoutingFee,proto3" json:"max_swap_routing_fee,omitempty"`
|
||||
// *
|
||||
// Maximum off-chain fee in msat that may be paid for payment to the server.
|
||||
// This limit is applied during path finding. Typically this value is taken
|
||||
// from the response of the GetQuote call.
|
||||
MaxPrepayRoutingFee int64 `protobuf:"varint,4,opt,name=max_prepay_routing_fee,json=maxPrepayRoutingFee,proto3" json:"max_prepay_routing_fee,omitempty"`
|
||||
// *
|
||||
// Maximum we are willing to pay the server for the swap. This value is not
|
||||
// disclosed in the swap initiation call, but if the server asks for a
|
||||
// higher fee, we abort the swap. Typically this value is taken from the
|
||||
// response of the GetQuote call. It includes the prepay amount.
|
||||
MaxSwapFee int64 `protobuf:"varint,5,opt,name=max_swap_fee,json=maxSwapFee,proto3" json:"max_swap_fee,omitempty"`
|
||||
// *
|
||||
// Maximum amount of the swap fee that may be charged as a prepayment.
|
||||
MaxPrepayAmt int64 `protobuf:"varint,6,opt,name=max_prepay_amt,json=maxPrepayAmt,proto3" json:"max_prepay_amt,omitempty"`
|
||||
// *
|
||||
// Maximum in on-chain fees that we are willing to spent. If we want to
|
||||
// sweep the on-chain htlc and the fee estimate turns out higher than this
|
||||
// value, we cancel the swap. If the fee estimate is lower, we publish the
|
||||
// sweep tx.
|
||||
//
|
||||
// If the sweep tx isn't confirmed, we are forced to ratchet up fees until
|
||||
// it is swept. Possibly even exceeding max_miner_fee if we get close to the
|
||||
// htlc timeout. Because the initial publication revealed the preimage, we
|
||||
// have no other choice. The server may already have pulled the off-chain
|
||||
// htlc. Only when the fee becomes higher than the swap amount, we can only
|
||||
// wait for fees to come down and hope - if we are past the timeout - that
|
||||
// the server isn't publishing the revocation.
|
||||
//
|
||||
// max_miner_fee is typically taken from the response of the GetQuote call.
|
||||
MaxMinerFee int64 `protobuf:"varint,7,opt,name=max_miner_fee,json=maxMinerFee,proto3" json:"max_miner_fee,omitempty"`
|
||||
// *
|
||||
// The channel to uncharge. If zero, the channel to uncharge is selected based
|
||||
// on the lowest routing fee for the swap payment to the server.
|
||||
UnchargeChannel uint64 `protobuf:"varint,8,opt,name=uncharge_channel,json=unchargeChannel,proto3" json:"uncharge_channel,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) Reset() { *m = UnchargeRequest{} }
|
||||
func (m *UnchargeRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*UnchargeRequest) ProtoMessage() {}
|
||||
func (*UnchargeRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{0}
|
||||
}
|
||||
func (m *UnchargeRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_UnchargeRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *UnchargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_UnchargeRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *UnchargeRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_UnchargeRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *UnchargeRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_UnchargeRequest.Size(m)
|
||||
}
|
||||
func (m *UnchargeRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_UnchargeRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_UnchargeRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *UnchargeRequest) GetAmt() int64 {
|
||||
if m != nil {
|
||||
return m.Amt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetDest() string {
|
||||
if m != nil {
|
||||
return m.Dest
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetMaxSwapRoutingFee() int64 {
|
||||
if m != nil {
|
||||
return m.MaxSwapRoutingFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetMaxPrepayRoutingFee() int64 {
|
||||
if m != nil {
|
||||
return m.MaxPrepayRoutingFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetMaxSwapFee() int64 {
|
||||
if m != nil {
|
||||
return m.MaxSwapFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetMaxPrepayAmt() int64 {
|
||||
if m != nil {
|
||||
return m.MaxPrepayAmt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetMaxMinerFee() int64 {
|
||||
if m != nil {
|
||||
return m.MaxMinerFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *UnchargeRequest) GetUnchargeChannel() uint64 {
|
||||
if m != nil {
|
||||
return m.UnchargeChannel
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type SwapResponse struct {
|
||||
// *
|
||||
// Swap identifier to track status in the update stream that is returned from
|
||||
// the Start() call. Currently this is the hash that locks the htlcs.
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SwapResponse) Reset() { *m = SwapResponse{} }
|
||||
func (m *SwapResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SwapResponse) ProtoMessage() {}
|
||||
func (*SwapResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{1}
|
||||
}
|
||||
func (m *SwapResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SwapResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SwapResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SwapResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *SwapResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SwapResponse.Merge(dst, src)
|
||||
}
|
||||
func (m *SwapResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_SwapResponse.Size(m)
|
||||
}
|
||||
func (m *SwapResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SwapResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SwapResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *SwapResponse) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MonitorRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *MonitorRequest) Reset() { *m = MonitorRequest{} }
|
||||
func (m *MonitorRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*MonitorRequest) ProtoMessage() {}
|
||||
func (*MonitorRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{2}
|
||||
}
|
||||
func (m *MonitorRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_MonitorRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *MonitorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_MonitorRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *MonitorRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_MonitorRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *MonitorRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_MonitorRequest.Size(m)
|
||||
}
|
||||
func (m *MonitorRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_MonitorRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_MonitorRequest proto.InternalMessageInfo
|
||||
|
||||
type SwapStatus struct {
|
||||
// *
|
||||
// Requested swap amount in sat. This does not include the swap and miner
|
||||
// fee.
|
||||
Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"`
|
||||
// *
|
||||
// Swap identifier to track status in the update stream that is returned from
|
||||
// the Start() call. Currently this is the hash that locks the htlcs.
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
// *
|
||||
// Swap type
|
||||
Type SwapType `protobuf:"varint,3,opt,name=type,proto3,enum=rpc.SwapType" json:"type,omitempty"`
|
||||
// *
|
||||
// State the swap is currently in, see State enum.
|
||||
State SwapState `protobuf:"varint,4,opt,name=state,proto3,enum=rpc.SwapState" json:"state,omitempty"`
|
||||
// *
|
||||
// Initiation time of the swap.
|
||||
InitiationTime int64 `protobuf:"varint,5,opt,name=initiation_time,json=initiationTime,proto3" json:"initiation_time,omitempty"`
|
||||
// *
|
||||
// Initiation time of the swap.
|
||||
LastUpdateTime int64 `protobuf:"varint,6,opt,name=last_update_time,json=lastUpdateTime,proto3" json:"last_update_time,omitempty"`
|
||||
// *
|
||||
// Htlc address.
|
||||
HtlcAddress string `protobuf:"bytes,7,opt,name=htlc_address,json=htlcAddress,proto3" json:"htlc_address,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SwapStatus) Reset() { *m = SwapStatus{} }
|
||||
func (m *SwapStatus) String() string { return proto.CompactTextString(m) }
|
||||
func (*SwapStatus) ProtoMessage() {}
|
||||
func (*SwapStatus) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{3}
|
||||
}
|
||||
func (m *SwapStatus) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SwapStatus.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SwapStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SwapStatus.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *SwapStatus) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SwapStatus.Merge(dst, src)
|
||||
}
|
||||
func (m *SwapStatus) XXX_Size() int {
|
||||
return xxx_messageInfo_SwapStatus.Size(m)
|
||||
}
|
||||
func (m *SwapStatus) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SwapStatus.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SwapStatus proto.InternalMessageInfo
|
||||
|
||||
func (m *SwapStatus) GetAmt() int64 {
|
||||
if m != nil {
|
||||
return m.Amt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetType() SwapType {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return SwapType_UNCHARGE
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetState() SwapState {
|
||||
if m != nil {
|
||||
return m.State
|
||||
}
|
||||
return SwapState_INITIATED
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetInitiationTime() int64 {
|
||||
if m != nil {
|
||||
return m.InitiationTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetLastUpdateTime() int64 {
|
||||
if m != nil {
|
||||
return m.LastUpdateTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *SwapStatus) GetHtlcAddress() string {
|
||||
if m != nil {
|
||||
return m.HtlcAddress
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TermsRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TermsRequest) Reset() { *m = TermsRequest{} }
|
||||
func (m *TermsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*TermsRequest) ProtoMessage() {}
|
||||
func (*TermsRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{4}
|
||||
}
|
||||
func (m *TermsRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_TermsRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *TermsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_TermsRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *TermsRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_TermsRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *TermsRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_TermsRequest.Size(m)
|
||||
}
|
||||
func (m *TermsRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_TermsRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_TermsRequest proto.InternalMessageInfo
|
||||
|
||||
type TermsResponse struct {
|
||||
// *
|
||||
// The node pubkey where the swap payment needs to be paid
|
||||
// to. This can be used to test connectivity before initiating the swap.
|
||||
SwapPaymentDest string `protobuf:"bytes,1,opt,name=swap_payment_dest,json=swapPaymentDest,proto3" json:"swap_payment_dest,omitempty"`
|
||||
// *
|
||||
// The base fee for a swap (sat)
|
||||
SwapFeeBase int64 `protobuf:"varint,2,opt,name=swap_fee_base,json=swapFeeBase,proto3" json:"swap_fee_base,omitempty"`
|
||||
// *
|
||||
// The fee rate for a swap (parts per million)
|
||||
SwapFeeRate int64 `protobuf:"varint,3,opt,name=swap_fee_rate,json=swapFeeRate,proto3" json:"swap_fee_rate,omitempty"`
|
||||
// *
|
||||
// Required prepay amount
|
||||
PrepayAmt int64 `protobuf:"varint,4,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"`
|
||||
// *
|
||||
// Minimum swap amount (sat)
|
||||
MinSwapAmount int64 `protobuf:"varint,5,opt,name=min_swap_amount,json=minSwapAmount,proto3" json:"min_swap_amount,omitempty"`
|
||||
// *
|
||||
// Maximum swap amount (sat)
|
||||
MaxSwapAmount int64 `protobuf:"varint,6,opt,name=max_swap_amount,json=maxSwapAmount,proto3" json:"max_swap_amount,omitempty"`
|
||||
// *
|
||||
// On-chain cltv expiry delta
|
||||
CltvDelta int32 `protobuf:"varint,7,opt,name=cltv_delta,json=cltvDelta,proto3" json:"cltv_delta,omitempty"`
|
||||
// *
|
||||
// Maximum cltv expiry delta
|
||||
MaxCltv int32 `protobuf:"varint,8,opt,name=max_cltv,json=maxCltv,proto3" json:"max_cltv,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TermsResponse) Reset() { *m = TermsResponse{} }
|
||||
func (m *TermsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*TermsResponse) ProtoMessage() {}
|
||||
func (*TermsResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{5}
|
||||
}
|
||||
func (m *TermsResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_TermsResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *TermsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_TermsResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *TermsResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_TermsResponse.Merge(dst, src)
|
||||
}
|
||||
func (m *TermsResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_TermsResponse.Size(m)
|
||||
}
|
||||
func (m *TermsResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_TermsResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_TermsResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *TermsResponse) GetSwapPaymentDest() string {
|
||||
if m != nil {
|
||||
return m.SwapPaymentDest
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetSwapFeeBase() int64 {
|
||||
if m != nil {
|
||||
return m.SwapFeeBase
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetSwapFeeRate() int64 {
|
||||
if m != nil {
|
||||
return m.SwapFeeRate
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetPrepayAmt() int64 {
|
||||
if m != nil {
|
||||
return m.PrepayAmt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetMinSwapAmount() int64 {
|
||||
if m != nil {
|
||||
return m.MinSwapAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetMaxSwapAmount() int64 {
|
||||
if m != nil {
|
||||
return m.MaxSwapAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetCltvDelta() int32 {
|
||||
if m != nil {
|
||||
return m.CltvDelta
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TermsResponse) GetMaxCltv() int32 {
|
||||
if m != nil {
|
||||
return m.MaxCltv
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type QuoteRequest struct {
|
||||
// *
|
||||
// Requested swap amount in sat.
|
||||
Amt int64 `protobuf:"varint,1,opt,name=amt,proto3" json:"amt,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *QuoteRequest) Reset() { *m = QuoteRequest{} }
|
||||
func (m *QuoteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*QuoteRequest) ProtoMessage() {}
|
||||
func (*QuoteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{6}
|
||||
}
|
||||
func (m *QuoteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_QuoteRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *QuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_QuoteRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *QuoteRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_QuoteRequest.Merge(dst, src)
|
||||
}
|
||||
func (m *QuoteRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_QuoteRequest.Size(m)
|
||||
}
|
||||
func (m *QuoteRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_QuoteRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_QuoteRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *QuoteRequest) GetAmt() int64 {
|
||||
if m != nil {
|
||||
return m.Amt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type QuoteResponse struct {
|
||||
// *
|
||||
// The fee that the swap server is charging for the swap.
|
||||
SwapFee int64 `protobuf:"varint,1,opt,name=swap_fee,json=swapFee,proto3" json:"swap_fee,omitempty"`
|
||||
// *
|
||||
// The part of the swap fee that is requested as a
|
||||
// prepayment.
|
||||
PrepayAmt int64 `protobuf:"varint,2,opt,name=prepay_amt,json=prepayAmt,proto3" json:"prepay_amt,omitempty"`
|
||||
// *
|
||||
// An estimate of the on-chain fee that needs to be paid to
|
||||
// sweep the htlc.
|
||||
MinerFee int64 `protobuf:"varint,3,opt,name=miner_fee,json=minerFee,proto3" json:"miner_fee,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *QuoteResponse) Reset() { *m = QuoteResponse{} }
|
||||
func (m *QuoteResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*QuoteResponse) ProtoMessage() {}
|
||||
func (*QuoteResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_swapclient_d9c5a6779b6644af, []int{7}
|
||||
}
|
||||
func (m *QuoteResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_QuoteResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *QuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_QuoteResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *QuoteResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_QuoteResponse.Merge(dst, src)
|
||||
}
|
||||
func (m *QuoteResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_QuoteResponse.Size(m)
|
||||
}
|
||||
func (m *QuoteResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_QuoteResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_QuoteResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *QuoteResponse) GetSwapFee() int64 {
|
||||
if m != nil {
|
||||
return m.SwapFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *QuoteResponse) GetPrepayAmt() int64 {
|
||||
if m != nil {
|
||||
return m.PrepayAmt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *QuoteResponse) GetMinerFee() int64 {
|
||||
if m != nil {
|
||||
return m.MinerFee
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*UnchargeRequest)(nil), "rpc.UnchargeRequest")
|
||||
proto.RegisterType((*SwapResponse)(nil), "rpc.SwapResponse")
|
||||
proto.RegisterType((*MonitorRequest)(nil), "rpc.MonitorRequest")
|
||||
proto.RegisterType((*SwapStatus)(nil), "rpc.SwapStatus")
|
||||
proto.RegisterType((*TermsRequest)(nil), "rpc.TermsRequest")
|
||||
proto.RegisterType((*TermsResponse)(nil), "rpc.TermsResponse")
|
||||
proto.RegisterType((*QuoteRequest)(nil), "rpc.QuoteRequest")
|
||||
proto.RegisterType((*QuoteResponse)(nil), "rpc.QuoteResponse")
|
||||
proto.RegisterEnum("rpc.SwapType", SwapType_name, SwapType_value)
|
||||
proto.RegisterEnum("rpc.SwapState", SwapState_name, SwapState_value)
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// SwapClientClient is the client API for SwapClient service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type SwapClientClient interface {
|
||||
// *
|
||||
// Uncharge initiates an uncharge swap with the given parameters. The call
|
||||
// returns after the swap has been set up with the swap server. From that
|
||||
// point onwards, progress can be tracked via the SwapStatus stream
|
||||
// that is returned from Monitor().
|
||||
Uncharge(ctx context.Context, in *UnchargeRequest, opts ...grpc.CallOption) (*SwapResponse, error)
|
||||
// *
|
||||
// Monitor will return a stream of swap updates for currently active swaps.
|
||||
Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (SwapClient_MonitorClient, error)
|
||||
// *
|
||||
// GetTerms returns the terms that the server enforces for swaps.
|
||||
GetUnchargeTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error)
|
||||
// *
|
||||
// GetQuote returns a quote for a swap with the provided parameters.
|
||||
GetUnchargeQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error)
|
||||
}
|
||||
|
||||
type swapClientClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewSwapClientClient(cc *grpc.ClientConn) SwapClientClient {
|
||||
return &swapClientClient{cc}
|
||||
}
|
||||
|
||||
func (c *swapClientClient) Uncharge(ctx context.Context, in *UnchargeRequest, opts ...grpc.CallOption) (*SwapResponse, error) {
|
||||
out := new(SwapResponse)
|
||||
err := c.cc.Invoke(ctx, "/rpc.SwapClient/Uncharge", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *swapClientClient) Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (SwapClient_MonitorClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_SwapClient_serviceDesc.Streams[0], "/rpc.SwapClient/Monitor", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &swapClientMonitorClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type SwapClient_MonitorClient interface {
|
||||
Recv() (*SwapStatus, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type swapClientMonitorClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *swapClientMonitorClient) Recv() (*SwapStatus, error) {
|
||||
m := new(SwapStatus)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *swapClientClient) GetUnchargeTerms(ctx context.Context, in *TermsRequest, opts ...grpc.CallOption) (*TermsResponse, error) {
|
||||
out := new(TermsResponse)
|
||||
err := c.cc.Invoke(ctx, "/rpc.SwapClient/GetUnchargeTerms", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *swapClientClient) GetUnchargeQuote(ctx context.Context, in *QuoteRequest, opts ...grpc.CallOption) (*QuoteResponse, error) {
|
||||
out := new(QuoteResponse)
|
||||
err := c.cc.Invoke(ctx, "/rpc.SwapClient/GetUnchargeQuote", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SwapClientServer is the server API for SwapClient service.
|
||||
type SwapClientServer interface {
|
||||
// *
|
||||
// Uncharge initiates an uncharge swap with the given parameters. The call
|
||||
// returns after the swap has been set up with the swap server. From that
|
||||
// point onwards, progress can be tracked via the SwapStatus stream
|
||||
// that is returned from Monitor().
|
||||
Uncharge(context.Context, *UnchargeRequest) (*SwapResponse, error)
|
||||
// *
|
||||
// Monitor will return a stream of swap updates for currently active swaps.
|
||||
Monitor(*MonitorRequest, SwapClient_MonitorServer) error
|
||||
// *
|
||||
// GetTerms returns the terms that the server enforces for swaps.
|
||||
GetUnchargeTerms(context.Context, *TermsRequest) (*TermsResponse, error)
|
||||
// *
|
||||
// GetQuote returns a quote for a swap with the provided parameters.
|
||||
GetUnchargeQuote(context.Context, *QuoteRequest) (*QuoteResponse, error)
|
||||
}
|
||||
|
||||
func RegisterSwapClientServer(s *grpc.Server, srv SwapClientServer) {
|
||||
s.RegisterService(&_SwapClient_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _SwapClient_Uncharge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnchargeRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SwapClientServer).Uncharge(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/rpc.SwapClient/Uncharge",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SwapClientServer).Uncharge(ctx, req.(*UnchargeRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SwapClient_Monitor_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(MonitorRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(SwapClientServer).Monitor(m, &swapClientMonitorServer{stream})
|
||||
}
|
||||
|
||||
type SwapClient_MonitorServer interface {
|
||||
Send(*SwapStatus) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type swapClientMonitorServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *swapClientMonitorServer) Send(m *SwapStatus) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _SwapClient_GetUnchargeTerms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TermsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SwapClientServer).GetUnchargeTerms(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/rpc.SwapClient/GetUnchargeTerms",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SwapClientServer).GetUnchargeTerms(ctx, req.(*TermsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SwapClient_GetUnchargeQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(QuoteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SwapClientServer).GetUnchargeQuote(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/rpc.SwapClient/GetUnchargeQuote",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SwapClientServer).GetUnchargeQuote(ctx, req.(*QuoteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _SwapClient_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "rpc.SwapClient",
|
||||
HandlerType: (*SwapClientServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Uncharge",
|
||||
Handler: _SwapClient_Uncharge_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUnchargeTerms",
|
||||
Handler: _SwapClient_GetUnchargeTerms_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetUnchargeQuote",
|
||||
Handler: _SwapClient_GetUnchargeQuote_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Monitor",
|
||||
Handler: _SwapClient_Monitor_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "swapclient.proto",
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("swapclient.proto", fileDescriptor_swapclient_d9c5a6779b6644af) }
|
||||
|
||||
var fileDescriptor_swapclient_d9c5a6779b6644af = []byte{
|
||||
// 744 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0x5d, 0x4f, 0xe3, 0x46,
|
||||
0x14, 0x25, 0xdf, 0xf1, 0x4d, 0xe2, 0x38, 0x03, 0xad, 0x02, 0x15, 0x55, 0xb0, 0x50, 0x9b, 0xf2,
|
||||
0x40, 0x5b, 0x78, 0xea, 0xa3, 0x9b, 0x18, 0x9a, 0x6a, 0x41, 0xec, 0x24, 0xd9, 0x57, 0x6b, 0x48,
|
||||
0x06, 0xb0, 0x94, 0xb1, 0xbd, 0x9e, 0x31, 0x24, 0xff, 0x69, 0x1f, 0xf7, 0x57, 0xad, 0xb4, 0xff,
|
||||
0x61, 0x35, 0x1f, 0x36, 0x09, 0xda, 0x7d, 0xb3, 0xce, 0x3d, 0xf7, 0x8c, 0xef, 0x99, 0x73, 0x07,
|
||||
0x1c, 0xfe, 0x42, 0x92, 0xc5, 0x2a, 0xa4, 0x91, 0x38, 0x4f, 0xd2, 0x58, 0xc4, 0xa8, 0x92, 0x26,
|
||||
0x0b, 0xf7, 0x73, 0x19, 0xba, 0xf3, 0x68, 0xf1, 0x44, 0xd2, 0x47, 0x8a, 0xe9, 0xc7, 0x8c, 0x72,
|
||||
0x81, 0x1c, 0xa8, 0x10, 0x26, 0xfa, 0xa5, 0x41, 0x69, 0x58, 0xc1, 0xf2, 0x13, 0x21, 0xa8, 0x2e,
|
||||
0x29, 0x17, 0xfd, 0xf2, 0xa0, 0x34, 0xb4, 0xb0, 0xfa, 0x46, 0x7f, 0xc2, 0x01, 0x23, 0xeb, 0x40,
|
||||
0xca, 0x06, 0x69, 0x9c, 0x89, 0x30, 0x7a, 0x0c, 0x1e, 0x28, 0xed, 0x57, 0x54, 0x5b, 0x8f, 0x91,
|
||||
0xf5, 0xf4, 0x85, 0x24, 0x58, 0x57, 0xae, 0x28, 0x45, 0x97, 0xf0, 0xb3, 0x6c, 0x48, 0x52, 0x9a,
|
||||
0x90, 0xcd, 0x4e, 0x4b, 0x55, 0xb5, 0xec, 0x33, 0xb2, 0xbe, 0x53, 0xc5, 0xad, 0xa6, 0x01, 0xb4,
|
||||
0x8b, 0x53, 0x24, 0xb5, 0xa6, 0xa8, 0x60, 0xd4, 0x25, 0xe3, 0x14, 0xec, 0x2d, 0x59, 0xf9, 0xe3,
|
||||
0x75, 0xc5, 0x69, 0x17, 0x72, 0x1e, 0x13, 0xc8, 0x85, 0x8e, 0x64, 0xb1, 0x30, 0xa2, 0xa9, 0x12,
|
||||
0x6a, 0x28, 0x52, 0x8b, 0x91, 0xf5, 0x8d, 0xc4, 0xa4, 0xd2, 0x1f, 0xe0, 0x64, 0xc6, 0x8a, 0x60,
|
||||
0xf1, 0x44, 0xa2, 0x88, 0xae, 0xfa, 0xcd, 0x41, 0x69, 0x58, 0xc5, 0xdd, 0x1c, 0x1f, 0x69, 0xd8,
|
||||
0xfd, 0x15, 0xda, 0x6a, 0x3a, 0xca, 0x93, 0x38, 0xe2, 0x14, 0xd9, 0x50, 0x0e, 0x97, 0xca, 0x31,
|
||||
0x0b, 0x97, 0xc3, 0xa5, 0xeb, 0x80, 0x7d, 0x13, 0x47, 0xa1, 0x88, 0x53, 0x63, 0xaa, 0xfb, 0xb5,
|
||||
0x04, 0x20, 0x5b, 0xa6, 0x82, 0x88, 0x8c, 0x7f, 0xc7, 0x63, 0x2d, 0x51, 0xce, 0x25, 0xd0, 0x09,
|
||||
0x54, 0xc5, 0x26, 0xd1, 0x7e, 0xda, 0x17, 0x9d, 0xf3, 0x34, 0x59, 0x9c, 0x4b, 0x81, 0xd9, 0x26,
|
||||
0xa1, 0x58, 0x95, 0xd0, 0x29, 0xd4, 0xb8, 0x20, 0x42, 0x1b, 0x68, 0x5f, 0xd8, 0x05, 0x47, 0x1e,
|
||||
0x42, 0xb1, 0x2e, 0xa2, 0xdf, 0xa1, 0x1b, 0x46, 0xa1, 0x08, 0x89, 0x08, 0xe3, 0x28, 0x10, 0x21,
|
||||
0xcb, 0x5d, 0xb4, 0x5f, 0xe1, 0x59, 0xc8, 0x28, 0x1a, 0x82, 0xb3, 0x22, 0x5c, 0x04, 0x59, 0xb2,
|
||||
0x24, 0x82, 0x6a, 0xa6, 0xf6, 0xd2, 0x96, 0xf8, 0x5c, 0xc1, 0x8a, 0x79, 0x02, 0xed, 0x27, 0xb1,
|
||||
0x5a, 0x04, 0x64, 0xb9, 0x4c, 0x29, 0xe7, 0xca, 0x4c, 0x0b, 0xb7, 0x24, 0xe6, 0x69, 0xc8, 0xb5,
|
||||
0xa1, 0x3d, 0xa3, 0x29, 0xe3, 0xf9, 0xfc, 0x9f, 0xca, 0xd0, 0x31, 0x80, 0xf1, 0xec, 0x0c, 0x7a,
|
||||
0xea, 0x5a, 0x13, 0xb2, 0x61, 0x34, 0x12, 0x81, 0x4a, 0x98, 0xb6, 0xb0, 0x2b, 0x0b, 0x77, 0x1a,
|
||||
0x1f, 0xcb, 0xb0, 0xb9, 0xd0, 0xc9, 0x23, 0x10, 0xdc, 0x13, 0x4e, 0x95, 0x4f, 0x15, 0xdc, 0xe2,
|
||||
0x3a, 0x04, 0xff, 0x12, 0x4e, 0x77, 0x38, 0xa9, 0x74, 0xa5, 0xb2, 0xc3, 0xc1, 0xd2, 0x8b, 0x63,
|
||||
0x80, 0xad, 0xa0, 0xe8, 0xdc, 0x59, 0x49, 0x91, 0x92, 0xdf, 0xa0, 0xcb, 0xc2, 0x48, 0xa7, 0x8d,
|
||||
0xb0, 0x38, 0x8b, 0x84, 0xb1, 0xaa, 0xc3, 0xc2, 0x48, 0x1a, 0xeb, 0x29, 0x50, 0xf1, 0xf2, 0x54,
|
||||
0x1a, 0x5e, 0xdd, 0xf0, 0x74, 0x30, 0x0d, 0xef, 0x18, 0x60, 0xb1, 0x12, 0xcf, 0xc1, 0x92, 0xae,
|
||||
0x04, 0x51, 0x2e, 0xd5, 0xb0, 0x25, 0x91, 0xb1, 0x04, 0xd0, 0x21, 0x34, 0xa5, 0x8c, 0x04, 0x54,
|
||||
0xd0, 0x6a, 0xb8, 0xc1, 0xc8, 0x7a, 0xb4, 0x12, 0xcf, 0xee, 0x00, 0xda, 0xef, 0xb3, 0x58, 0xfc,
|
||||
0x78, 0x27, 0xdd, 0x07, 0xe8, 0x18, 0x86, 0xf1, 0xf3, 0x10, 0x9a, 0xc5, 0x9a, 0x68, 0x5e, 0xc3,
|
||||
0x8c, 0xfe, 0x66, 0xec, 0xf2, 0xdb, 0xb1, 0x7f, 0x01, 0xeb, 0x75, 0x31, 0xb4, 0x6b, 0x4d, 0x66,
|
||||
0xb6, 0xe2, 0xac, 0x0f, 0xcd, 0x3c, 0x76, 0xa8, 0x0d, 0xcd, 0xf9, 0xed, 0xe8, 0x3f, 0x0f, 0x5f,
|
||||
0xfb, 0xce, 0xde, 0xd9, 0xff, 0x60, 0x15, 0x61, 0x43, 0x1d, 0xb0, 0x26, 0xb7, 0x93, 0xd9, 0xc4,
|
||||
0x9b, 0xf9, 0x63, 0x67, 0x0f, 0xfd, 0x04, 0xbd, 0x3b, 0xec, 0x4f, 0x6e, 0xbc, 0x6b, 0x3f, 0xc0,
|
||||
0xfe, 0x07, 0xdf, 0x7b, 0xe7, 0x8f, 0x9d, 0x12, 0x6a, 0x41, 0x63, 0x3a, 0x1f, 0x8d, 0xfc, 0xe9,
|
||||
0xd4, 0xa9, 0x20, 0x80, 0xfa, 0x95, 0x37, 0x91, 0x85, 0xea, 0xc5, 0x17, 0xb3, 0x1e, 0x23, 0xf5,
|
||||
0x42, 0xa1, 0x4b, 0x68, 0xe6, 0xaf, 0x12, 0x3a, 0x50, 0xb1, 0x7e, 0xf3, 0x48, 0x1d, 0xf5, 0x8a,
|
||||
0xb0, 0x17, 0x06, 0xfc, 0x0d, 0x0d, 0xb3, 0x74, 0x68, 0x5f, 0x55, 0x77, 0x57, 0xf0, 0xa8, 0xbb,
|
||||
0xb3, 0x1f, 0x19, 0xff, 0xab, 0x84, 0xfe, 0x01, 0xe7, 0x9a, 0x8a, 0x5c, 0x5b, 0xe5, 0x13, 0x69,
|
||||
0xe5, 0xed, 0xf0, 0x1e, 0xa1, 0x6d, 0xc8, 0x9c, 0xb6, 0xdb, 0xaa, 0xae, 0xc2, 0xb4, 0x6e, 0x5f,
|
||||
0x9c, 0x69, 0xdd, 0xb9, 0xa9, 0xfb, 0xba, 0x7a, 0x80, 0x2f, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff,
|
||||
0x4d, 0x46, 0x11, 0xa8, 0x94, 0x05, 0x00, 0x00,
|
||||
}
|
||||
259
cmd/swapd/rpc/swapclient.proto
Normal file
259
cmd/swapd/rpc/swapclient.proto
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package rpc;
|
||||
|
||||
message UnchargeRequest {
|
||||
/**
|
||||
Requested swap amount in sat. This does not include the swap and miner
|
||||
fee.
|
||||
*/
|
||||
int64 amt = 1;
|
||||
|
||||
/**
|
||||
Base58 encoded destination address for the swap.
|
||||
*/
|
||||
string dest = 2;
|
||||
|
||||
/**
|
||||
Maximum off-chain fee in msat that may be paid for payment to the server.
|
||||
This limit is applied during path finding. Typically this value is taken
|
||||
from the response of the GetQuote call.
|
||||
*/
|
||||
int64 max_swap_routing_fee = 3;
|
||||
|
||||
/**
|
||||
Maximum off-chain fee in msat that may be paid for payment to the server.
|
||||
This limit is applied during path finding. Typically this value is taken
|
||||
from the response of the GetQuote call.
|
||||
*/
|
||||
int64 max_prepay_routing_fee = 4;
|
||||
|
||||
/**
|
||||
Maximum we are willing to pay the server for the swap. This value is not
|
||||
disclosed in the swap initiation call, but if the server asks for a
|
||||
higher fee, we abort the swap. Typically this value is taken from the
|
||||
response of the GetQuote call. It includes the prepay amount.
|
||||
*/
|
||||
int64 max_swap_fee = 5;
|
||||
|
||||
/**
|
||||
Maximum amount of the swap fee that may be charged as a prepayment.
|
||||
*/
|
||||
int64 max_prepay_amt = 6;
|
||||
|
||||
/**
|
||||
Maximum in on-chain fees that we are willing to spent. If we want to
|
||||
sweep the on-chain htlc and the fee estimate turns out higher than this
|
||||
value, we cancel the swap. If the fee estimate is lower, we publish the
|
||||
sweep tx.
|
||||
|
||||
If the sweep tx isn't confirmed, we are forced to ratchet up fees until
|
||||
it is swept. Possibly even exceeding max_miner_fee if we get close to the
|
||||
htlc timeout. Because the initial publication revealed the preimage, we
|
||||
have no other choice. The server may already have pulled the off-chain
|
||||
htlc. Only when the fee becomes higher than the swap amount, we can only
|
||||
wait for fees to come down and hope - if we are past the timeout - that
|
||||
the server isn't publishing the revocation.
|
||||
|
||||
max_miner_fee is typically taken from the response of the GetQuote call.
|
||||
*/
|
||||
int64 max_miner_fee = 7;
|
||||
|
||||
/**
|
||||
The channel to uncharge. If zero, the channel to uncharge is selected based
|
||||
on the lowest routing fee for the swap payment to the server.
|
||||
*/
|
||||
uint64 uncharge_channel = 8;
|
||||
}
|
||||
|
||||
|
||||
message SwapResponse {
|
||||
/**
|
||||
Swap identifier to track status in the update stream that is returned from
|
||||
the Start() call. Currently this is the hash that locks the htlcs.
|
||||
*/
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message MonitorRequest{
|
||||
}
|
||||
|
||||
|
||||
message SwapStatus {
|
||||
/**
|
||||
Requested swap amount in sat. This does not include the swap and miner
|
||||
fee.
|
||||
*/
|
||||
int64 amt = 1;
|
||||
|
||||
/**
|
||||
Swap identifier to track status in the update stream that is returned from
|
||||
the Start() call. Currently this is the hash that locks the htlcs.
|
||||
*/
|
||||
string id = 2;
|
||||
|
||||
/**
|
||||
Swap type
|
||||
*/
|
||||
SwapType type = 3;
|
||||
|
||||
/**
|
||||
State the swap is currently in, see State enum.
|
||||
*/
|
||||
SwapState state = 4;
|
||||
|
||||
/**
|
||||
Initiation time of the swap.
|
||||
*/
|
||||
int64 initiation_time = 5;
|
||||
|
||||
/**
|
||||
Initiation time of the swap.
|
||||
*/
|
||||
int64 last_update_time = 6;
|
||||
|
||||
/**
|
||||
Htlc address.
|
||||
*/
|
||||
string htlc_address = 7;
|
||||
}
|
||||
|
||||
enum SwapType {
|
||||
// UNCHARGE indicates an uncharge swap (off-chain to on-chain)
|
||||
UNCHARGE = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
enum SwapState {
|
||||
/**
|
||||
INITIATED is the initial state of a swap. At that point, the initiation
|
||||
call to the server has been made and the payment process has been started
|
||||
for the swap and prepayment invoices.
|
||||
*/
|
||||
INITIATED = 0;
|
||||
|
||||
/**
|
||||
PREIMAGE_REVEALED is reached when the sweep tx publication is first
|
||||
attempted. From that point on, we should consider the preimage to no
|
||||
longer be secret and we need to do all we can to get the sweep confirmed.
|
||||
This state will mostly coalesce with StateHtlcConfirmed, except in the
|
||||
case where we wait for fees to come down before we sweep.
|
||||
*/
|
||||
PREIMAGE_REVEALED = 1;
|
||||
|
||||
/**
|
||||
SUCCESS is the final swap state that is reached when the sweep tx has
|
||||
the required confirmation depth.
|
||||
*/
|
||||
SUCCESS = 3;
|
||||
|
||||
/**
|
||||
FAILED is the final swap state for a failed swap with or without loss of
|
||||
the swap amount.
|
||||
*/
|
||||
FAILED = 4;
|
||||
}
|
||||
|
||||
message TermsRequest {
|
||||
}
|
||||
|
||||
message TermsResponse {
|
||||
/**
|
||||
The node pubkey where the swap payment needs to be paid
|
||||
to. This can be used to test connectivity before initiating the swap.
|
||||
*/
|
||||
string swap_payment_dest = 1;
|
||||
|
||||
/**
|
||||
The base fee for a swap (sat)
|
||||
*/
|
||||
int64 swap_fee_base = 2;
|
||||
|
||||
/**
|
||||
The fee rate for a swap (parts per million)
|
||||
*/
|
||||
int64 swap_fee_rate = 3;
|
||||
|
||||
/**
|
||||
Required prepay amount
|
||||
*/
|
||||
int64 prepay_amt = 4;
|
||||
|
||||
/**
|
||||
Minimum swap amount (sat)
|
||||
*/
|
||||
int64 min_swap_amount = 5;
|
||||
|
||||
/**
|
||||
Maximum swap amount (sat)
|
||||
*/
|
||||
int64 max_swap_amount = 6;
|
||||
|
||||
/**
|
||||
On-chain cltv expiry delta
|
||||
*/
|
||||
int32 cltv_delta = 7;
|
||||
|
||||
/**
|
||||
Maximum cltv expiry delta
|
||||
*/
|
||||
int32 max_cltv = 8;
|
||||
}
|
||||
|
||||
message QuoteRequest {
|
||||
/**
|
||||
Requested swap amount in sat.
|
||||
*/
|
||||
int64 amt = 1;
|
||||
}
|
||||
|
||||
message QuoteResponse {
|
||||
/**
|
||||
The fee that the swap server is charging for the swap.
|
||||
*/
|
||||
int64 swap_fee = 1;
|
||||
|
||||
/**
|
||||
The part of the swap fee that is requested as a
|
||||
prepayment.
|
||||
*/
|
||||
int64 prepay_amt = 2;
|
||||
|
||||
/**
|
||||
An estimate of the on-chain fee that needs to be paid to
|
||||
sweep the htlc.
|
||||
*/
|
||||
int64 miner_fee = 3;
|
||||
}
|
||||
|
||||
/**
|
||||
SwapClient is a service that handles the client side process of onchain/offchain
|
||||
swaps. The service is designed for a single client.
|
||||
*/
|
||||
service SwapClient {
|
||||
/**
|
||||
Uncharge initiates an uncharge swap with the given parameters. The call
|
||||
returns after the swap has been set up with the swap server. From that
|
||||
point onwards, progress can be tracked via the SwapStatus stream
|
||||
that is returned from Monitor().
|
||||
*/
|
||||
rpc Uncharge(UnchargeRequest) returns (SwapResponse);
|
||||
|
||||
|
||||
/**
|
||||
Monitor will return a stream of swap updates for currently active swaps.
|
||||
*/
|
||||
rpc Monitor(MonitorRequest) returns(stream SwapStatus);
|
||||
|
||||
/**
|
||||
GetTerms returns the terms that the server enforces for swaps.
|
||||
*/
|
||||
rpc GetUnchargeTerms(TermsRequest) returns(TermsResponse);
|
||||
|
||||
/**
|
||||
GetQuote returns a quote for a swap with the provided parameters.
|
||||
*/
|
||||
rpc GetUnchargeQuote(QuoteRequest) returns(QuoteResponse);
|
||||
}
|
||||
|
||||
247
cmd/swapd/swapclient_server.go
Normal file
247
cmd/swapd/swapclient_server.go
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/lightningnetwork/lnd/queue"
|
||||
|
||||
"github.com/lightninglabs/nautilus/lndclient"
|
||||
"github.com/lightninglabs/nautilus/utils"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightninglabs/nautilus/client"
|
||||
clientrpc "github.com/lightninglabs/nautilus/cmd/swapd/rpc"
|
||||
)
|
||||
|
||||
const completedSwapsCount = 5
|
||||
|
||||
// swapClientServer implements the grpc service exposed by swapd.
|
||||
type swapClientServer struct {
|
||||
impl *client.Client
|
||||
lnd *lndclient.LndServices
|
||||
}
|
||||
|
||||
// Uncharge initiates an uncharge swap with the given parameters. The call
|
||||
// returns after the swap has been set up with the swap server. From that point
|
||||
// onwards, progress can be tracked via the UnchargeStatus stream that is
|
||||
// returned from Monitor().
|
||||
func (s *swapClientServer) Uncharge(ctx context.Context,
|
||||
in *clientrpc.UnchargeRequest) (
|
||||
*clientrpc.SwapResponse, error) {
|
||||
|
||||
logger.Infof("Uncharge request received")
|
||||
|
||||
var sweepAddr btcutil.Address
|
||||
if in.Dest == "" {
|
||||
// Generate sweep address if none specified.
|
||||
var err error
|
||||
sweepAddr, err = s.lnd.WalletKit.NextAddr(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NextAddr error: %v", err)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
sweepAddr, err = btcutil.DecodeAddress(in.Dest, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode address: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
req := &client.UnchargeRequest{
|
||||
Amount: btcutil.Amount(in.Amt),
|
||||
DestAddr: sweepAddr,
|
||||
MaxMinerFee: btcutil.Amount(in.MaxMinerFee),
|
||||
MaxPrepayAmount: btcutil.Amount(in.MaxPrepayAmt),
|
||||
MaxPrepayRoutingFee: btcutil.Amount(in.MaxPrepayRoutingFee),
|
||||
MaxSwapRoutingFee: btcutil.Amount(in.MaxSwapRoutingFee),
|
||||
MaxSwapFee: btcutil.Amount(in.MaxSwapFee),
|
||||
SweepConfTarget: defaultConfTarget,
|
||||
}
|
||||
if in.UnchargeChannel != 0 {
|
||||
req.UnchargeChannel = &in.UnchargeChannel
|
||||
}
|
||||
hash, err := s.impl.Uncharge(ctx, req)
|
||||
if err != nil {
|
||||
logger.Errorf("Uncharge: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &clientrpc.SwapResponse{
|
||||
Id: hash.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *swapClientServer) marshallSwap(swap *client.SwapInfo) (
|
||||
*clientrpc.SwapStatus, error) {
|
||||
|
||||
var state clientrpc.SwapState
|
||||
switch swap.State {
|
||||
case client.StateInitiated:
|
||||
state = clientrpc.SwapState_INITIATED
|
||||
case client.StatePreimageRevealed:
|
||||
state = clientrpc.SwapState_PREIMAGE_REVEALED
|
||||
case client.StateSuccess:
|
||||
state = clientrpc.SwapState_SUCCESS
|
||||
default:
|
||||
// Return less granular status over rpc.
|
||||
state = clientrpc.SwapState_FAILED
|
||||
}
|
||||
|
||||
htlc, err := utils.NewHtlc(swap.CltvExpiry, swap.SenderKey,
|
||||
swap.ReceiverKey, swap.SwapHash,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
address, err := htlc.Address(s.lnd.ChainParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &clientrpc.SwapStatus{
|
||||
Amt: int64(swap.AmountRequested),
|
||||
Id: swap.SwapHash.String(),
|
||||
State: state,
|
||||
InitiationTime: swap.InitiationTime.UnixNano(),
|
||||
LastUpdateTime: swap.LastUpdate.UnixNano(),
|
||||
HtlcAddress: address.EncodeAddress(),
|
||||
Type: clientrpc.SwapType_UNCHARGE,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Monitor will return a stream of swap updates for currently active swaps.
|
||||
func (s *swapClientServer) Monitor(in *clientrpc.MonitorRequest,
|
||||
server clientrpc.SwapClient_MonitorServer) error {
|
||||
|
||||
logger.Infof("Monitor request received")
|
||||
|
||||
send := func(info client.SwapInfo) error {
|
||||
rpcSwap, err := s.marshallSwap(&info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return server.Send(rpcSwap)
|
||||
}
|
||||
|
||||
// Start a notification queue for this subscriber.
|
||||
queue := queue.NewConcurrentQueue(20)
|
||||
queue.Start()
|
||||
|
||||
// Add this subscriber to the global subscriber list. Also create a
|
||||
// snapshot of all pending and completed swaps within the lock, to
|
||||
// prevent subscribers from receiving duplicate updates.
|
||||
swapsLock.Lock()
|
||||
|
||||
id := nextSubscriberID
|
||||
nextSubscriberID++
|
||||
subscribers[id] = queue.ChanIn()
|
||||
|
||||
var pendingSwaps, completedSwaps []client.SwapInfo
|
||||
for _, swap := range swaps {
|
||||
if swap.State.Type() == client.StateTypePending {
|
||||
pendingSwaps = append(pendingSwaps, swap)
|
||||
} else {
|
||||
completedSwaps = append(completedSwaps, swap)
|
||||
}
|
||||
}
|
||||
|
||||
swapsLock.Unlock()
|
||||
|
||||
defer func() {
|
||||
queue.Stop()
|
||||
swapsLock.Lock()
|
||||
delete(subscribers, id)
|
||||
swapsLock.Unlock()
|
||||
}()
|
||||
|
||||
// Sort completed swaps new to old.
|
||||
sort.Slice(completedSwaps, func(i, j int) bool {
|
||||
return completedSwaps[i].LastUpdate.After(
|
||||
completedSwaps[j].LastUpdate,
|
||||
)
|
||||
})
|
||||
|
||||
// Discard all but top x latest.
|
||||
if len(completedSwaps) > completedSwapsCount {
|
||||
completedSwaps = completedSwaps[:completedSwapsCount]
|
||||
}
|
||||
|
||||
// Concatenate both sets.
|
||||
filteredSwaps := append(pendingSwaps, completedSwaps...)
|
||||
|
||||
// Sort again, but this time old to new.
|
||||
sort.Slice(filteredSwaps, func(i, j int) bool {
|
||||
return filteredSwaps[i].LastUpdate.Before(
|
||||
filteredSwaps[j].LastUpdate,
|
||||
)
|
||||
})
|
||||
|
||||
// Return swaps to caller.
|
||||
for _, swap := range filteredSwaps {
|
||||
if err := send(swap); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// As long as the client is connected, keep passing through swap
|
||||
// updates.
|
||||
for {
|
||||
select {
|
||||
case queueItem, ok := <-queue.ChanOut():
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
swap := queueItem.(client.SwapInfo)
|
||||
if err := send(swap); err != nil {
|
||||
return err
|
||||
}
|
||||
case <-server.Context().Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetTerms returns the terms that the server enforces for swaps.
|
||||
func (s *swapClientServer) GetUnchargeTerms(ctx context.Context, req *clientrpc.TermsRequest) (
|
||||
*clientrpc.TermsResponse, error) {
|
||||
|
||||
logger.Infof("Terms request received")
|
||||
|
||||
terms, err := s.impl.UnchargeTerms(ctx)
|
||||
if err != nil {
|
||||
logger.Errorf("Terms request: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &clientrpc.TermsResponse{
|
||||
MinSwapAmount: int64(terms.MinSwapAmount),
|
||||
MaxSwapAmount: int64(terms.MaxSwapAmount),
|
||||
PrepayAmt: int64(terms.PrepayAmt),
|
||||
SwapFeeBase: int64(terms.SwapFeeBase),
|
||||
SwapFeeRate: int64(terms.SwapFeeRate),
|
||||
CltvDelta: int32(terms.CltvDelta),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetQuote returns a quote for a swap with the provided parameters.
|
||||
func (s *swapClientServer) GetUnchargeQuote(ctx context.Context,
|
||||
req *clientrpc.QuoteRequest) (*clientrpc.QuoteResponse, error) {
|
||||
|
||||
quote, err := s.impl.UnchargeQuote(ctx, &client.UnchargeQuoteRequest{
|
||||
Amount: btcutil.Amount(req.Amt),
|
||||
SweepConfTarget: defaultConfTarget,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &clientrpc.QuoteResponse{
|
||||
MinerFee: int64(quote.MinerFee),
|
||||
PrepayAmt: int64(quote.PrepayAmount),
|
||||
SwapFee: int64(quote.SwapFee),
|
||||
}, nil
|
||||
}
|
||||
49
cmd/swapd/utils.go
Normal file
49
cmd/swapd/utils.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/lightninglabs/nautilus/client"
|
||||
"github.com/lightninglabs/nautilus/lndclient"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// getLnd returns an instance of the lnd services proxy.
|
||||
func getLnd(ctx *cli.Context) (*lndclient.GrpcLndServices, error) {
|
||||
network := ctx.GlobalString("network")
|
||||
|
||||
return lndclient.NewLndServices(ctx.GlobalString("lnd"),
|
||||
"client", network, ctx.GlobalString("macaroonpath"),
|
||||
ctx.GlobalString("tlspath"),
|
||||
)
|
||||
}
|
||||
|
||||
// getClient returns an instance of the swap client.
|
||||
func getClient(ctx *cli.Context, lnd *lndclient.LndServices) (*client.Client, func(), error) {
|
||||
network := ctx.GlobalString("network")
|
||||
|
||||
storeDir, err := getStoreDir(network)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
swapClient, cleanUp, err := client.NewClient(
|
||||
storeDir, ctx.GlobalString("swapserver"),
|
||||
ctx.GlobalBool("insecure"), lnd,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return swapClient, cleanUp, nil
|
||||
}
|
||||
|
||||
func getStoreDir(network string) (string, error) {
|
||||
dir := filepath.Join(defaultSwapletDir, network)
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return dir, nil
|
||||
}
|
||||
89
cmd/swapd/view.go
Normal file
89
cmd/swapd/view.go
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/lightninglabs/nautilus/utils"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var viewCommand = cli.Command{
|
||||
Name: "view",
|
||||
Usage: `view all swaps in the database. This command can only be
|
||||
executed when swapd is not running.`,
|
||||
Description: `
|
||||
Show all pending and completed swaps.`,
|
||||
Action: view,
|
||||
}
|
||||
|
||||
// view prints all swaps currently in the database.
|
||||
func view(ctx *cli.Context) error {
|
||||
network := ctx.GlobalString("network")
|
||||
|
||||
chainParams, err := utils.ChainParamsFromNetwork(network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lnd, err := getLnd(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer lnd.Close()
|
||||
|
||||
swapClient, cleanup, err := getClient(ctx, &lnd.LndServices)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
swaps, err := swapClient.GetUnchargeSwaps()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range swaps {
|
||||
htlc, err := utils.NewHtlc(
|
||||
s.Contract.CltvExpiry,
|
||||
s.Contract.SenderKey,
|
||||
s.Contract.ReceiverKey,
|
||||
s.Hash,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
htlcAddress, err := htlc.Address(chainParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%v\n", s.Hash)
|
||||
fmt.Printf(" Created: %v (height %v)\n",
|
||||
s.Contract.InitiationTime, s.Contract.InitiationHeight,
|
||||
)
|
||||
fmt.Printf(" Preimage: %v\n", s.Contract.Preimage)
|
||||
fmt.Printf(" Htlc address: %v\n", htlcAddress)
|
||||
|
||||
unchargeChannel := "any"
|
||||
if s.Contract.UnchargeChannel != nil {
|
||||
unchargeChannel = strconv.FormatUint(
|
||||
*s.Contract.UnchargeChannel, 10,
|
||||
)
|
||||
}
|
||||
fmt.Printf(" Uncharge channel: %v\n", unchargeChannel)
|
||||
fmt.Printf(" Dest: %v\n", s.Contract.DestAddr)
|
||||
fmt.Printf(" Amt: %v, Expiry: %v\n",
|
||||
s.Contract.AmountRequested, s.Contract.CltvExpiry,
|
||||
)
|
||||
for i, e := range s.Events {
|
||||
fmt.Printf(" Update %v, Time %v, State: %v\n",
|
||||
i, e.Time, e.State,
|
||||
)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue