diff --git a/client/balance.go b/client/balance.go index 3fd4ae8..5fe34e5 100644 --- a/client/balance.go +++ b/client/balance.go @@ -18,7 +18,7 @@ var expiryDetailsFlag = cli.BoolFlag{ var balanceCommand = cli.Command{ Name: "balance", - Usage: "Print balance of the Ark wallet", + Usage: "Shows the onchain and offchain balance of the Ark wallet", Action: balanceAction, Flags: []cli.Flag{&expiryDetailsFlag}, } diff --git a/client/common.go b/client/common.go index 2e4dc58..2339003 100644 --- a/client/common.go +++ b/client/common.go @@ -15,6 +15,7 @@ import ( arkv1 "github.com/ark-network/ark/api-spec/protobuf/gen/ark/v1" "github.com/ark-network/ark/common" "github.com/ark-network/ark/common/tree" + "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/urfave/cli/v2" @@ -596,7 +597,7 @@ func handleRoundStream( if len(output.Script) == 0 { continue } - if bytes.Equal(output.Script[2:], outputTapKey.SerializeCompressed()) { + if bytes.Equal(output.Script[2:], schnorr.SerializePubKey(outputTapKey)) { if output.Value != receiver.Amount { continue } @@ -733,6 +734,29 @@ func toCongestionTree(treeFromProto *arkv1.Tree) (tree.CongestionTree, error) { return levels, nil } +// castCongestionTree converts a tree.CongestionTree to a repeated arkv1.TreeLevel +func castCongestionTree(congestionTree tree.CongestionTree) *arkv1.Tree { + levels := make([]*arkv1.TreeLevel, 0, len(congestionTree)) + for _, level := range congestionTree { + levelProto := &arkv1.TreeLevel{ + Nodes: make([]*arkv1.Node, 0, len(level)), + } + + for _, node := range level { + levelProto.Nodes = append(levelProto.Nodes, &arkv1.Node{ + Txid: node.Txid, + Tx: node.Tx, + ParentTxid: node.ParentTxid, + }) + } + + levels = append(levels, levelProto) + } + return &arkv1.Tree{ + Levels: levels, + } +} + func decodeReceiverAddress(addr string) ( isOnChainAddress bool, onchainScript []byte, diff --git a/client/config.go b/client/config.go index 9b48d7c..15d00b6 100644 --- a/client/config.go +++ b/client/config.go @@ -6,7 +6,7 @@ import ( var configCommand = cli.Command{ Name: "config", - Usage: "Print local configuration of the Ark CLI", + Usage: "Shows configuration of the Ark wallet", Action: printConfigAction, } diff --git a/client/dump.go b/client/dump.go index 862b0f4..985a1ac 100644 --- a/client/dump.go +++ b/client/dump.go @@ -8,12 +8,12 @@ import ( var dumpCommand = cli.Command{ Name: "dump-privkey", - Usage: "Dump private key of the Ark wallet", + Usage: "Dumps private key of the Ark wallet", Action: dumpAction, } func dumpAction(ctx *cli.Context) error { - privateKey, err := privateKeyFromPassword() + privateKey, err := privateKeyFromPassword() if err != nil { return err } diff --git a/client/faucet.go b/client/faucet.go deleted file mode 100644 index 2e3ff0a..0000000 --- a/client/faucet.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io" - - arkv1 "github.com/ark-network/ark/api-spec/protobuf/gen/ark/v1" - "github.com/urfave/cli/v2" -) - -var faucetCommand = cli.Command{ - Name: "faucet", - Usage: "Faucet your wallet", - Action: faucetAction, -} - -func faucetAction(ctx *cli.Context) error { - addr, _, err := getAddress() - if err != nil { - return err - } - - client, close, err := getClientFromState(ctx) - if err != nil { - return err - } - defer close() - - _, err = client.Faucet(ctx.Context, &arkv1.FaucetRequest{ - Address: addr, - }) - if err != nil { - return err - } - - eventStream, err := client.GetEventStream(ctx.Context, &arkv1.GetEventStreamRequest{}) - if err != nil { - return err - } - - for { - event, err := eventStream.Recv() - if err == io.EOF { - break - } - if err != nil { - return err - } - - if event.GetRoundFinalization() != nil { - if _, err := client.FinalizePayment(context.Background(), &arkv1.FinalizePaymentRequest{ - SignedForfeitTxs: event.GetRoundFinalization().GetForfeitTxs(), - }); err != nil { - return err - } - } - - if event.GetRoundFailed() != nil { - return fmt.Errorf("faucet failed: %s", event.GetRoundFailed().GetReason()) - } - - if event.GetRoundFinalized() != nil { - return printJSON(map[string]interface{}{ - "pool_txid": event.GetRoundFinalized().GetPoolTxid(), - }) - } - } - - return nil -} diff --git a/client/init.go b/client/init.go index 50b1209..d31108c 100644 --- a/client/init.go +++ b/client/init.go @@ -36,7 +36,7 @@ var ( var initCommand = cli.Command{ Name: "init", - Usage: "initialize the wallet with an encryption password, and connect it to an ASP", + Usage: "Initialize your Ark wallet with an encryption password, and connect it to an ASP", Action: initAction, Flags: []cli.Flag{&passwordFlag, &privateKeyFlag, &networkFlag, &urlFlag}, } diff --git a/client/main.go b/client/main.go index 01c98b7..c33ab00 100644 --- a/client/main.go +++ b/client/main.go @@ -57,17 +57,17 @@ func main() { app.Version = version app.Name = "Ark CLI" - app.Usage = "command line interface for Ark wallet" + app.Usage = "ark wallet command line interface" app.Commands = append( app.Commands, &balanceCommand, &configCommand, &dumpCommand, - &faucetCommand, &initCommand, &receiveCommand, &redeemCommand, &sendCommand, + &onboardCommand, ) app.Before = func(ctx *cli.Context) error { diff --git a/client/onboard.go b/client/onboard.go new file mode 100644 index 0000000..398a528 --- /dev/null +++ b/client/onboard.go @@ -0,0 +1,147 @@ +package main + +import ( + "encoding/hex" + "fmt" + "time" + + arkv1 "github.com/ark-network/ark/api-spec/protobuf/gen/ark/v1" + "github.com/ark-network/ark/common/tree" + "github.com/urfave/cli/v2" + "github.com/vulpemventures/go-elements/payment" + "github.com/vulpemventures/go-elements/psetv2" +) + +const ( + minRelayFee = 30 +) + +var ( + amountOnboardFlag = cli.Uint64Flag{ + Name: "amount", + Usage: "amount to onboard in sats", + Required: true, + } +) + +var onboardCommand = cli.Command{ + Name: "onboard", + Usage: "Onboard the Ark by lifting your funds", + Action: onboardAction, + Flags: []cli.Flag{&amountOnboardFlag}, +} + +func onboardAction(ctx *cli.Context) error { + amount := ctx.Uint64("amount") + + if amount <= 0 { + return fmt.Errorf("missing amount flag (--amount)") + } + + _, net := getNetwork() + + aspPubkey, err := getServiceProviderPublicKey() + if err != nil { + return err + } + + lifetime, err := getLifetime() + if err != nil { + return err + } + + exitDelay, err := getExitDelay() + if err != nil { + return err + } + + userPubKey, err := getWalletPublicKey() + if err != nil { + return err + } + + congestionTreeLeaf := tree.Receiver{ + Pubkey: hex.EncodeToString(userPubKey.SerializeCompressed()), + Amount: amount, + } + + treeFactoryFn, sharedOutputScript, sharedOutputAmount, err := tree.CraftCongestionTree( + net.AssetID, aspPubkey, []tree.Receiver{congestionTreeLeaf}, minRelayFee, lifetime, exitDelay, + ) + if err != nil { + return err + } + + pay, err := payment.FromScript(sharedOutputScript, net, nil) + if err != nil { + return err + } + + address, err := pay.TaprootAddress() + if err != nil { + return err + } + + onchainReceiver := receiver{ + To: address, + Amount: sharedOutputAmount, + } + + pset, err := sendOnchain(ctx, []receiver{onchainReceiver}) + if err != nil { + return err + } + + txid, err := broadcastPset(pset) + if err != nil { + return err + } + + fmt.Println("onboard txid:", txid) + fmt.Println("waiting for confirmation... (this may take a while, do not cancel the process)") + + // wait for the transaction to be confirmed + if err := waitForTxConfirmation(ctx, txid); err != nil { + return err + } + + fmt.Println("transaction confirmed") + + congestionTree, err := treeFactoryFn(psetv2.InputArgs{ + Txid: txid, + TxIndex: 0, + }) + + if err != nil { + return err + } + + client, close, err := getClientFromState(ctx) + if err != nil { + return err + } + defer close() + + _, err = client.Onboard(ctx.Context, &arkv1.OnboardRequest{ + BoardingTx: pset, + CongestionTree: castCongestionTree(congestionTree), + UserPubkey: hex.EncodeToString(userPubKey.SerializeCompressed()), + }) + if err != nil { + return err + } + + return nil +} + +func waitForTxConfirmation(ctx *cli.Context, txid string) error { + isConfirmed := false + + for !isConfirmed { + time.Sleep(5 * time.Second) + + isConfirmed, _, _ = getTxBlocktime(txid) + } + + return nil +} diff --git a/client/receive.go b/client/receive.go index 0e6a30b..25db261 100644 --- a/client/receive.go +++ b/client/receive.go @@ -6,7 +6,7 @@ import ( var receiveCommand = cli.Command{ Name: "receive", - Usage: "Print the Ark address associated with your wallet and the connected Ark", + Usage: "Shows both onchain and offchain addresses", Action: receiveAction, } diff --git a/client/redeem.go b/client/redeem.go index 241610b..b605193 100644 --- a/client/redeem.go +++ b/client/redeem.go @@ -38,7 +38,7 @@ var ( var redeemCommand = cli.Command{ Name: "redeem", - Usage: "Redeem VTXO(s) to onchain", + Usage: "Redeem your offchain funds, either collaboratively or unilaterally", Flags: []cli.Flag{&addressFlag, &amountToRedeemFlag, &forceFlag}, Action: redeemAction, } diff --git a/client/send.go b/client/send.go index c90369c..f47250c 100644 --- a/client/send.go +++ b/client/send.go @@ -40,7 +40,7 @@ var ( var sendCommand = cli.Command{ Name: "send", - Usage: "Send VTXOs to a list of addresses", + Usage: "Send your onchain or offchain funds to one or many receivers", Action: sendAction, Flags: []cli.Flag{&receiversFlag, &toFlag, &amountFlag}, } @@ -83,9 +83,19 @@ func sendAction(ctx *cli.Context) error { } if len(onchainReceivers) > 0 { - if err := sendOnchain(ctx, onchainReceivers); err != nil { + pset, err := sendOnchain(ctx, onchainReceivers) + if err != nil { return err } + + txid, err := broadcastPset(pset) + if err != nil { + return err + } + + return printJSON(map[string]interface{}{ + "txid": txid, + }) } if len(offchainReceivers) > 0 { @@ -203,14 +213,14 @@ func sendOffchain(ctx *cli.Context, receivers []receiver) error { }) } -func sendOnchain(ctx *cli.Context, receivers []receiver) error { +func sendOnchain(ctx *cli.Context, receivers []receiver) (string, error) { pset, err := psetv2.New(nil, nil, nil) if err != nil { - return err + return "", err } updater, err := psetv2.NewUpdater(pset) if err != nil { - return err + return "", err } _, net := getNetwork() @@ -219,12 +229,12 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { for _, receiver := range receivers { targetAmount += receiver.Amount if receiver.Amount < DUST { - return fmt.Errorf("invalid amount (%d), must be greater than dust %d", receiver.Amount, DUST) + return "", fmt.Errorf("invalid amount (%d), must be greater than dust %d", receiver.Amount, DUST) } script, err := address.ToOutputScript(receiver.To) if err != nil { - return err + return "", err } if err := updater.AddOutputs([]psetv2.OutputArgs{ @@ -234,28 +244,28 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { Script: script, }, }); err != nil { - return err + return "", err } } selected, delayedSelected, change, err := coinSelectOnchain(targetAmount, nil) if err != nil { - return err + return "", err } if err := addInputs(updater, selected, delayedSelected, net); err != nil { - return err + return "", err } if change > 0 { _, changeAddr, err := getAddress() if err != nil { - return err + return "", err } changeScript, err := address.ToOutputScript(changeAddr) if err != nil { - return err + return "", err } if err := updater.AddOutputs([]psetv2.OutputArgs{ @@ -265,13 +275,13 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { Script: changeScript, }, }); err != nil { - return err + return "", err } } - utx, err := updater.Pset.UnsignedTx() + utx, err := pset.UnsignedTx() if err != nil { - return err + return "", err } vBytes := utx.VirtualSize() @@ -291,22 +301,22 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { append(selected, delayedSelected...), ) if err != nil { - return err + return "", err } if err := addInputs(updater, selected, delayedSelected, net); err != nil { - return err + return "", err } if newChange > 0 { _, changeAddr, err := getAddress() if err != nil { - return err + return "", err } changeScript, err := address.ToOutputScript(changeAddr) if err != nil { - return err + return "", err } if err := updater.AddOutputs([]psetv2.OutputArgs{ @@ -316,7 +326,7 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { Script: changeScript, }, }); err != nil { - return err + return "", err } } } @@ -327,40 +337,42 @@ func sendOnchain(ctx *cli.Context, receivers []receiver) error { Amount: feeAmount, }, }); err != nil { - return err + return "", err } prvKey, err := privateKeyFromPassword() if err != nil { - return err + return "", err } explorer := NewExplorer() if err := signPset(updater.Pset, explorer, prvKey); err != nil { - return err + return "", err } if err := psetv2.FinalizeAll(updater.Pset); err != nil { - return err + return "", err + } + + return updater.Pset.ToBase64() +} + +func broadcastPset(psetB64 string) (string, error) { + pset, err := psetv2.NewPsetFromBase64(psetB64) + if err != nil { + return "", err } extracted, err := psetv2.Extract(pset) if err != nil { - return err + return "", err } hex, err := extracted.ToHex() if err != nil { - return err + return "", err } - txid, err := explorer.Broadcast(hex) - if err != nil { - return err - } - - return printJSON(map[string]interface{}{ - "txid": txid, - }) + return NewExplorer().Broadcast(hex) } diff --git a/server/internal/infrastructure/tx-builder/covenant/tree.go b/common/tree/builder.go similarity index 81% rename from server/internal/infrastructure/tx-builder/covenant/tree.go rename to common/tree/builder.go index 98cd45c..464a8f1 100644 --- a/server/internal/infrastructure/tx-builder/covenant/tree.go +++ b/common/tree/builder.go @@ -1,22 +1,49 @@ -package txbuilder +package tree import ( "encoding/hex" "fmt" - "github.com/ark-network/ark/common/tree" - "github.com/ark-network/ark/internal/core/domain" + "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/vulpemventures/go-elements/psetv2" "github.com/vulpemventures/go-elements/taproot" ) -type treeFactory func(outpoint psetv2.InputArgs) (tree.CongestionTree, error) +func CraftCongestionTree( + asset string, aspPublicKey *secp256k1.PublicKey, + receivers []Receiver, feeSatsPerNode uint64, roundLifetime int64, exitDelay int64, +) ( + buildCongestionTree TreeFactory, + sharedOutputScript []byte, sharedOutputAmount uint64, err error, +) { + root, err := createPartialCongestionTree( + receivers, aspPublicKey, asset, feeSatsPerNode, roundLifetime, exitDelay, + ) + if err != nil { + return + } + + taprootKey, _, err := root.getWitnessData() + if err != nil { + return + } + + sharedOutputScript, err = taprootOutputScript(taprootKey) + if err != nil { + return + } + sharedOutputAmount = root.getAmount() + root.feeSats + buildCongestionTree = root.createFinalCongestionTree() + + return +} type node struct { sweepKey *secp256k1.PublicKey - receivers []domain.Receiver + receivers []Receiver left *node right *node asset string @@ -131,7 +158,7 @@ func (n *node) getWitnessData() ( return n._inputTaprootKey, n._inputTaprootTree, nil } - sweepClosure := &tree.CSVSigClosure{ + sweepClosure := &CSVSigClosure{ Pubkey: n.sweepKey, Seconds: uint(n.roundLifetime), } @@ -147,7 +174,7 @@ func (n *node) getWitnessData() ( return nil, nil, err } - unrollClosure := &tree.UnrollClosure{ + unrollClosure := &UnrollClosure{ LeftKey: taprootKey, LeftAmount: n.getAmount(), } @@ -163,7 +190,7 @@ func (n *node) getWitnessData() ( root := branchTaprootTree.RootNode.TapHash() inputTapkey := taproot.ComputeTaprootOutputKey( - tree.UnspendableKey(), + UnspendableKey(), root[:], ) @@ -186,7 +213,7 @@ func (n *node) getWitnessData() ( leftAmount := n.left.getAmount() + n.feeSats rightAmount := n.right.getAmount() + n.feeSats - unrollClosure := &tree.UnrollClosure{ + unrollClosure := &UnrollClosure{ LeftKey: leftKey, LeftAmount: leftAmount, RightKey: rightKey, @@ -204,7 +231,7 @@ func (n *node) getWitnessData() ( root := branchTaprootTree.RootNode.TapHash() taprootKey := taproot.ComputeTaprootOutputKey( - tree.UnspendableKey(), + UnspendableKey(), root[:], ) @@ -231,7 +258,7 @@ func (n *node) getVtxoWitnessData() ( return nil, nil, err } - redeemClosure := &tree.CSVSigClosure{ + redeemClosure := &CSVSigClosure{ Pubkey: pubkey, Seconds: uint(n.exitDelay), } @@ -241,7 +268,7 @@ func (n *node) getVtxoWitnessData() ( return nil, nil, err } - forfeitClosure := &tree.ForfeitClosure{ + forfeitClosure := &ForfeitClosure{ Pubkey: pubkey, AspPubkey: n.sweepKey, } @@ -257,7 +284,7 @@ func (n *node) getVtxoWitnessData() ( root := leafTaprootTree.RootNode.TapHash() taprootKey := taproot.ComputeTaprootOutputKey( - tree.UnspendableKey(), + UnspendableKey(), root[:], ) @@ -266,25 +293,24 @@ func (n *node) getVtxoWitnessData() ( func (n *node) getTreeNode( input psetv2.InputArgs, tapTree *taproot.IndexedElementsTapScriptTree, -) (tree.Node, error) { +) (Node, error) { pset, err := n.getTx(input, tapTree) if err != nil { - return tree.Node{}, err + return Node{}, err } txid, err := getPsetId(pset) if err != nil { - return tree.Node{}, err + return Node{}, err } tx, err := pset.ToBase64() if err != nil { - return tree.Node{}, err + return Node{}, err } - parentTxid := chainhash.Hash(pset.Inputs[0].PreviousTxid).String() - return tree.Node{ + return Node{ Txid: txid, Tx: tx, ParentTxid: parentTxid, @@ -306,7 +332,7 @@ func (n *node) getTx( } if err := addTaprootInput( - updater, input, tree.UnspendableKey(), inputTapTree, + updater, input, UnspendableKey(), inputTapTree, ); err != nil { return nil, err } @@ -328,9 +354,9 @@ func (n *node) getTx( return pset, nil } -func (n *node) createFinalCongestionTree() treeFactory { - return func(poolTxInput psetv2.InputArgs) (tree.CongestionTree, error) { - congestionTree := make(tree.CongestionTree, 0) +func (n *node) createFinalCongestionTree() TreeFactory { + return func(poolTxInput psetv2.InputArgs) (CongestionTree, error) { + congestionTree := make(CongestionTree, 0) _, taprootTree, err := n.getWitnessData() if err != nil { @@ -346,7 +372,7 @@ func (n *node) createFinalCongestionTree() treeFactory { nextInputsArgs := make([]psetv2.InputArgs, 0) nextTaprootTrees := make([]*taproot.IndexedElementsTapScriptTree, 0) - treeLevel := make([]tree.Node, 0) + treeLevel := make([]Node, 0) for i, node := range nodes { treeNode, err := node.getTreeNode(ins[i], inTrees[i]) @@ -385,38 +411,8 @@ func (n *node) createFinalCongestionTree() treeFactory { } } -func craftCongestionTree( - asset string, aspPublicKey *secp256k1.PublicKey, - payments []domain.Payment, feeSatsPerNode uint64, roundLifetime int64, exitDelay int64, -) ( - buildCongestionTree treeFactory, - sharedOutputScript []byte, sharedOutputAmount uint64, err error, -) { - receivers := getOffchainReceivers(payments) - root, err := createPartialCongestionTree( - receivers, aspPublicKey, asset, feeSatsPerNode, roundLifetime, exitDelay, - ) - if err != nil { - return - } - - taprootKey, _, err := root.getWitnessData() - if err != nil { - return - } - - sharedOutputScript, err = taprootOutputScript(taprootKey) - if err != nil { - return - } - sharedOutputAmount = root.getAmount() + root.feeSats - buildCongestionTree = root.createFinalCongestionTree() - - return -} - func createPartialCongestionTree( - receivers []domain.Receiver, + receivers []Receiver, aspPublicKey *secp256k1.PublicKey, asset string, feeSatsPerNode uint64, @@ -431,7 +427,7 @@ func createPartialCongestionTree( for _, r := range receivers { leafNode := &node{ sweepKey: aspPublicKey, - receivers: []domain.Receiver{r}, + receivers: []Receiver{r}, asset: asset, feeSats: feeSatsPerNode, roundLifetime: roundLifetime, @@ -478,3 +474,45 @@ func createUpperLevel(nodes []*node) ([]*node, error) { } return pairs, nil } + +func taprootOutputScript(taprootKey *secp256k1.PublicKey) ([]byte, error) { + return txscript.NewScriptBuilder().AddOp(txscript.OP_1).AddData(schnorr.SerializePubKey(taprootKey)).Script() +} + +func getPsetId(pset *psetv2.Pset) (string, error) { + utx, err := pset.UnsignedTx() + if err != nil { + return "", err + } + + return utx.TxHash().String(), nil +} + +// wrapper of updater methods adding a taproot input to the pset with all the necessary data to spend it via any taproot script +func addTaprootInput( + updater *psetv2.Updater, + input psetv2.InputArgs, + internalTaprootKey *secp256k1.PublicKey, + taprootTree *taproot.IndexedElementsTapScriptTree, +) error { + if err := updater.AddInputs([]psetv2.InputArgs{input}); err != nil { + return err + } + + if err := updater.AddInTapInternalKey(0, schnorr.SerializePubKey(internalTaprootKey)); err != nil { + return err + } + + for _, proof := range taprootTree.LeafMerkleProofs { + controlBlock := proof.ToControlBlock(internalTaprootKey) + + if err := updater.AddInTapLeafScript(0, psetv2.TapLeafScript{ + TapElementsLeaf: taproot.NewBaseTapElementsLeaf(proof.Script), + ControlBlock: controlBlock, + }); err != nil { + return err + } + } + + return nil +} diff --git a/common/tree/type.go b/common/tree/type.go new file mode 100644 index 0000000..239b2fa --- /dev/null +++ b/common/tree/type.go @@ -0,0 +1,10 @@ +package tree + +import "github.com/vulpemventures/go-elements/psetv2" + +type TreeFactory func(outpoint psetv2.InputArgs) (CongestionTree, error) + +type Receiver struct { + Pubkey string + Amount uint64 +} diff --git a/common/tree/validation.go b/common/tree/validation.go index 4c08a8e..f56f0dd 100644 --- a/common/tree/validation.go +++ b/common/tree/validation.go @@ -236,7 +236,7 @@ func validateNodeTransaction( switch c := close.(type) { case *CSVSigClosure: - isASP := c.Pubkey.IsEqual(expectedPublicKeyASP) + isASP := bytes.Equal(schnorr.SerializePubKey(c.Pubkey), schnorr.SerializePubKey(expectedPublicKeyASP)) isSweepDelay := int64(c.Seconds) == expectedSequenceSeconds if isASP && !isSweepDelay { diff --git a/server/README.md b/server/README.md index c760fd3..00c4721 100755 --- a/server/README.md +++ b/server/README.md @@ -71,24 +71,36 @@ This will add a `state.json` file to the following directory: **Note:** you can use a different datadir by exporting the env var `ARK_WALLET_DATADIR` like: ```bash -$ export ARK_WALLET_DATADIR=path/to/custom +$ export ARK_WALLET_DATADIR=path/to/custom $ ark init --password --ark-url localhost:6000 +``` Add funds to the ark wallet: ``` -$ ark faucet -# ark now has 10000 sats on its offchain balance +$ ark receive +{ + "offchain_address":
, + "onchain_address":
+} ``` +Fund the `onchain_address` with https://liquidtestnet.com/faucet. + +Onboard the ark: + +``` +$ ark onboard --amount 21000 +``` + +After confirmation, ark wallet will be funded and ready to spend offchain. + In **another tab**, setup another ark wallet with: ``` $ export ARK_WALLET_DATADIR=./datadir $ alias ark2=$(pwd)/build/ark-cli-- $ ark2 init --password --ark-url localhost:6000 -$ ark2 faucet -# ark2 now has 10000 sats on ark ``` **Note:** `ark2` should always run in the second tab. @@ -98,7 +110,7 @@ $ ark2 faucet You can now make ark payments between the 2 ark wallets: ``` -$ ark receive +$ ark2 receive { "offchain_address":
, "onchain_address":
, @@ -109,7 +121,7 @@ $ ark receive ``` ``` -$ ark2 send --to --amount 2100 +$ ark send --to --amount 2100 ``` Both balances should reflect the payment: @@ -117,15 +129,15 @@ Both balances should reflect the payment: ``` $ ark balance { - "offchain_balance": 12100, - "onchain_balance": 0 + "offchain_balance": 18900, + "onchain_balance": 78872 } ``` ``` $ ark2 balance { - "offchain_balance": 7900, + "offchain_balance": 2100, "onchain_balance": 0 } ``` diff --git a/server/api-spec/openapi/swagger/ark/v1/service.swagger.json b/server/api-spec/openapi/swagger/ark/v1/service.swagger.json index 111f586..72cec64 100644 --- a/server/api-spec/openapi/swagger/ark/v1/service.swagger.json +++ b/server/api-spec/openapi/swagger/ark/v1/service.swagger.json @@ -47,36 +47,6 @@ ] } }, - "/v1/faucet/{address}": { - "post": { - "operationId": "ArkService_Faucet", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/v1FaucetResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "address", - "in": "path", - "required": true, - "type": "string" - } - ], - "tags": [ - "ArkService" - ] - } - }, "/v1/info": { "get": { "operationId": "ArkService_GetInfo", @@ -99,6 +69,38 @@ ] } }, + "/v1/onboard": { + "post": { + "operationId": "ArkService_Onboard", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1OnboardResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OnboardRequest" + } + } + ], + "tags": [ + "ArkService" + ] + } + }, "/v1/payment/claim": { "post": { "operationId": "ArkService_ClaimPayment", @@ -335,9 +337,6 @@ "v1ClaimPaymentResponse": { "type": "object" }, - "v1FaucetResponse": { - "type": "object" - }, "v1FinalizePaymentRequest": { "type": "object", "properties": { @@ -429,6 +428,23 @@ } } }, + "v1OnboardRequest": { + "type": "object", + "properties": { + "boardingTx": { + "type": "string" + }, + "congestionTree": { + "$ref": "#/definitions/v1Tree" + }, + "userPubkey": { + "type": "string" + } + } + }, + "v1OnboardResponse": { + "type": "object" + }, "v1Output": { "type": "object", "properties": { diff --git a/server/api-spec/protobuf/ark/v1/service.proto b/server/api-spec/protobuf/ark/v1/service.proto index 7edd7be..4e487c3 100755 --- a/server/api-spec/protobuf/ark/v1/service.proto +++ b/server/api-spec/protobuf/ark/v1/service.proto @@ -38,11 +38,6 @@ service ArkService { get: "/v1/ping/{payment_id}" }; }; - rpc Faucet(FaucetRequest) returns (FaucetResponse) { - option (google.api.http) = { - post: "/v1/faucet/{address}" - }; - } rpc ListVtxos(ListVtxosRequest) returns (ListVtxosResponse) { option (google.api.http) = { get: "/v1/vtxos/{address}" @@ -53,6 +48,21 @@ service ArkService { get: "/v1/info" }; } + rpc Onboard(OnboardRequest) returns (OnboardResponse) { + option (google.api.http) = { + post: "/v1/onboard" + body: "*" + }; + } +} + +message OnboardRequest { + string boarding_tx = 1; + Tree congestion_tree = 2; + string user_pubkey = 3; +} + +message OnboardResponse { } message RegisterPaymentRequest { @@ -151,12 +161,6 @@ message PingRequest { message PingResponse {} -message FaucetRequest { - string address = 1; -} - -message FaucetResponse {} - message ListVtxosRequest { string address = 1; } diff --git a/server/api-spec/protobuf/gen/ark/v1/service.pb.go b/server/api-spec/protobuf/gen/ark/v1/service.pb.go index 9f65c51..513ab32 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service.pb.go +++ b/server/api-spec/protobuf/gen/ark/v1/service.pb.go @@ -21,6 +21,107 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type OnboardRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BoardingTx string `protobuf:"bytes,1,opt,name=boarding_tx,json=boardingTx,proto3" json:"boarding_tx,omitempty"` + CongestionTree *Tree `protobuf:"bytes,2,opt,name=congestion_tree,json=congestionTree,proto3" json:"congestion_tree,omitempty"` + UserPubkey string `protobuf:"bytes,3,opt,name=user_pubkey,json=userPubkey,proto3" json:"user_pubkey,omitempty"` +} + +func (x *OnboardRequest) Reset() { + *x = OnboardRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OnboardRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OnboardRequest) ProtoMessage() {} + +func (x *OnboardRequest) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OnboardRequest.ProtoReflect.Descriptor instead. +func (*OnboardRequest) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{0} +} + +func (x *OnboardRequest) GetBoardingTx() string { + if x != nil { + return x.BoardingTx + } + return "" +} + +func (x *OnboardRequest) GetCongestionTree() *Tree { + if x != nil { + return x.CongestionTree + } + return nil +} + +func (x *OnboardRequest) GetUserPubkey() string { + if x != nil { + return x.UserPubkey + } + return "" +} + +type OnboardResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *OnboardResponse) Reset() { + *x = OnboardResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ark_v1_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OnboardResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OnboardResponse) ProtoMessage() {} + +func (x *OnboardResponse) ProtoReflect() protoreflect.Message { + mi := &file_ark_v1_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OnboardResponse.ProtoReflect.Descriptor instead. +func (*OnboardResponse) Descriptor() ([]byte, []int) { + return file_ark_v1_service_proto_rawDescGZIP(), []int{1} +} + type RegisterPaymentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -32,7 +133,7 @@ type RegisterPaymentRequest struct { func (x *RegisterPaymentRequest) Reset() { *x = RegisterPaymentRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[0] + mi := &file_ark_v1_service_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -45,7 +146,7 @@ func (x *RegisterPaymentRequest) String() string { func (*RegisterPaymentRequest) ProtoMessage() {} func (x *RegisterPaymentRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[0] + mi := &file_ark_v1_service_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -58,7 +159,7 @@ func (x *RegisterPaymentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterPaymentRequest.ProtoReflect.Descriptor instead. func (*RegisterPaymentRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{0} + return file_ark_v1_service_proto_rawDescGZIP(), []int{2} } func (x *RegisterPaymentRequest) GetInputs() []*Input { @@ -80,7 +181,7 @@ type RegisterPaymentResponse struct { func (x *RegisterPaymentResponse) Reset() { *x = RegisterPaymentResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[1] + mi := &file_ark_v1_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -93,7 +194,7 @@ func (x *RegisterPaymentResponse) String() string { func (*RegisterPaymentResponse) ProtoMessage() {} func (x *RegisterPaymentResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[1] + mi := &file_ark_v1_service_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -106,7 +207,7 @@ func (x *RegisterPaymentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterPaymentResponse.ProtoReflect.Descriptor instead. func (*RegisterPaymentResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{1} + return file_ark_v1_service_proto_rawDescGZIP(), []int{3} } func (x *RegisterPaymentResponse) GetId() string { @@ -130,7 +231,7 @@ type ClaimPaymentRequest struct { func (x *ClaimPaymentRequest) Reset() { *x = ClaimPaymentRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[2] + mi := &file_ark_v1_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -143,7 +244,7 @@ func (x *ClaimPaymentRequest) String() string { func (*ClaimPaymentRequest) ProtoMessage() {} func (x *ClaimPaymentRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[2] + mi := &file_ark_v1_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -156,7 +257,7 @@ func (x *ClaimPaymentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimPaymentRequest.ProtoReflect.Descriptor instead. func (*ClaimPaymentRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{2} + return file_ark_v1_service_proto_rawDescGZIP(), []int{4} } func (x *ClaimPaymentRequest) GetId() string { @@ -182,7 +283,7 @@ type ClaimPaymentResponse struct { func (x *ClaimPaymentResponse) Reset() { *x = ClaimPaymentResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[3] + mi := &file_ark_v1_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -195,7 +296,7 @@ func (x *ClaimPaymentResponse) String() string { func (*ClaimPaymentResponse) ProtoMessage() {} func (x *ClaimPaymentResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[3] + mi := &file_ark_v1_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -208,7 +309,7 @@ func (x *ClaimPaymentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimPaymentResponse.ProtoReflect.Descriptor instead. func (*ClaimPaymentResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{3} + return file_ark_v1_service_proto_rawDescGZIP(), []int{5} } type FinalizePaymentRequest struct { @@ -223,7 +324,7 @@ type FinalizePaymentRequest struct { func (x *FinalizePaymentRequest) Reset() { *x = FinalizePaymentRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[4] + mi := &file_ark_v1_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -236,7 +337,7 @@ func (x *FinalizePaymentRequest) String() string { func (*FinalizePaymentRequest) ProtoMessage() {} func (x *FinalizePaymentRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[4] + mi := &file_ark_v1_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -249,7 +350,7 @@ func (x *FinalizePaymentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizePaymentRequest.ProtoReflect.Descriptor instead. func (*FinalizePaymentRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{4} + return file_ark_v1_service_proto_rawDescGZIP(), []int{6} } func (x *FinalizePaymentRequest) GetSignedForfeitTxs() []string { @@ -268,7 +369,7 @@ type FinalizePaymentResponse struct { func (x *FinalizePaymentResponse) Reset() { *x = FinalizePaymentResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[5] + mi := &file_ark_v1_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -281,7 +382,7 @@ func (x *FinalizePaymentResponse) String() string { func (*FinalizePaymentResponse) ProtoMessage() {} func (x *FinalizePaymentResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[5] + mi := &file_ark_v1_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -294,7 +395,7 @@ func (x *FinalizePaymentResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizePaymentResponse.ProtoReflect.Descriptor instead. func (*FinalizePaymentResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{5} + return file_ark_v1_service_proto_rawDescGZIP(), []int{7} } type GetRoundRequest struct { @@ -308,7 +409,7 @@ type GetRoundRequest struct { func (x *GetRoundRequest) Reset() { *x = GetRoundRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[6] + mi := &file_ark_v1_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -321,7 +422,7 @@ func (x *GetRoundRequest) String() string { func (*GetRoundRequest) ProtoMessage() {} func (x *GetRoundRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[6] + mi := &file_ark_v1_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -334,7 +435,7 @@ func (x *GetRoundRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoundRequest.ProtoReflect.Descriptor instead. func (*GetRoundRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{6} + return file_ark_v1_service_proto_rawDescGZIP(), []int{8} } func (x *GetRoundRequest) GetTxid() string { @@ -355,7 +456,7 @@ type GetRoundResponse struct { func (x *GetRoundResponse) Reset() { *x = GetRoundResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[7] + mi := &file_ark_v1_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -368,7 +469,7 @@ func (x *GetRoundResponse) String() string { func (*GetRoundResponse) ProtoMessage() {} func (x *GetRoundResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[7] + mi := &file_ark_v1_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -381,7 +482,7 @@ func (x *GetRoundResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoundResponse.ProtoReflect.Descriptor instead. func (*GetRoundResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{7} + return file_ark_v1_service_proto_rawDescGZIP(), []int{9} } func (x *GetRoundResponse) GetRound() *Round { @@ -406,7 +507,7 @@ type Round struct { func (x *Round) Reset() { *x = Round{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[8] + mi := &file_ark_v1_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -419,7 +520,7 @@ func (x *Round) String() string { func (*Round) ProtoMessage() {} func (x *Round) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[8] + mi := &file_ark_v1_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -432,7 +533,7 @@ func (x *Round) ProtoReflect() protoreflect.Message { // Deprecated: Use Round.ProtoReflect.Descriptor instead. func (*Round) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{8} + return file_ark_v1_service_proto_rawDescGZIP(), []int{10} } func (x *Round) GetId() string { @@ -482,7 +583,7 @@ type Input struct { func (x *Input) Reset() { *x = Input{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[9] + mi := &file_ark_v1_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -495,7 +596,7 @@ func (x *Input) String() string { func (*Input) ProtoMessage() {} func (x *Input) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[9] + mi := &file_ark_v1_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -508,7 +609,7 @@ func (x *Input) ProtoReflect() protoreflect.Message { // Deprecated: Use Input.ProtoReflect.Descriptor instead. func (*Input) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{9} + return file_ark_v1_service_proto_rawDescGZIP(), []int{11} } func (x *Input) GetTxid() string { @@ -539,7 +640,7 @@ type Output struct { func (x *Output) Reset() { *x = Output{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[10] + mi := &file_ark_v1_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -552,7 +653,7 @@ func (x *Output) String() string { func (*Output) ProtoMessage() {} func (x *Output) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[10] + mi := &file_ark_v1_service_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -565,7 +666,7 @@ func (x *Output) ProtoReflect() protoreflect.Message { // Deprecated: Use Output.ProtoReflect.Descriptor instead. func (*Output) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{10} + return file_ark_v1_service_proto_rawDescGZIP(), []int{12} } func (x *Output) GetAddress() string { @@ -596,7 +697,7 @@ type RoundFinalizationEvent struct { func (x *RoundFinalizationEvent) Reset() { *x = RoundFinalizationEvent{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[11] + mi := &file_ark_v1_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -609,7 +710,7 @@ func (x *RoundFinalizationEvent) String() string { func (*RoundFinalizationEvent) ProtoMessage() {} func (x *RoundFinalizationEvent) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[11] + mi := &file_ark_v1_service_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -622,7 +723,7 @@ func (x *RoundFinalizationEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFinalizationEvent.ProtoReflect.Descriptor instead. func (*RoundFinalizationEvent) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{11} + return file_ark_v1_service_proto_rawDescGZIP(), []int{13} } func (x *RoundFinalizationEvent) GetId() string { @@ -664,7 +765,7 @@ type Tree struct { func (x *Tree) Reset() { *x = Tree{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[12] + mi := &file_ark_v1_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -677,7 +778,7 @@ func (x *Tree) String() string { func (*Tree) ProtoMessage() {} func (x *Tree) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[12] + mi := &file_ark_v1_service_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -690,7 +791,7 @@ func (x *Tree) ProtoReflect() protoreflect.Message { // Deprecated: Use Tree.ProtoReflect.Descriptor instead. func (*Tree) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{12} + return file_ark_v1_service_proto_rawDescGZIP(), []int{14} } func (x *Tree) GetLevels() []*TreeLevel { @@ -711,7 +812,7 @@ type TreeLevel struct { func (x *TreeLevel) Reset() { *x = TreeLevel{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[13] + mi := &file_ark_v1_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -724,7 +825,7 @@ func (x *TreeLevel) String() string { func (*TreeLevel) ProtoMessage() {} func (x *TreeLevel) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[13] + mi := &file_ark_v1_service_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -737,7 +838,7 @@ func (x *TreeLevel) ProtoReflect() protoreflect.Message { // Deprecated: Use TreeLevel.ProtoReflect.Descriptor instead. func (*TreeLevel) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{13} + return file_ark_v1_service_proto_rawDescGZIP(), []int{15} } func (x *TreeLevel) GetNodes() []*Node { @@ -760,7 +861,7 @@ type Node struct { func (x *Node) Reset() { *x = Node{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[14] + mi := &file_ark_v1_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -773,7 +874,7 @@ func (x *Node) String() string { func (*Node) ProtoMessage() {} func (x *Node) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[14] + mi := &file_ark_v1_service_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -786,7 +887,7 @@ func (x *Node) ProtoReflect() protoreflect.Message { // Deprecated: Use Node.ProtoReflect.Descriptor instead. func (*Node) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{14} + return file_ark_v1_service_proto_rawDescGZIP(), []int{16} } func (x *Node) GetTxid() string { @@ -822,7 +923,7 @@ type RoundFinalizedEvent struct { func (x *RoundFinalizedEvent) Reset() { *x = RoundFinalizedEvent{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[15] + mi := &file_ark_v1_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -835,7 +936,7 @@ func (x *RoundFinalizedEvent) String() string { func (*RoundFinalizedEvent) ProtoMessage() {} func (x *RoundFinalizedEvent) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[15] + mi := &file_ark_v1_service_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -848,7 +949,7 @@ func (x *RoundFinalizedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFinalizedEvent.ProtoReflect.Descriptor instead. func (*RoundFinalizedEvent) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{15} + return file_ark_v1_service_proto_rawDescGZIP(), []int{17} } func (x *RoundFinalizedEvent) GetId() string { @@ -877,7 +978,7 @@ type RoundFailed struct { func (x *RoundFailed) Reset() { *x = RoundFailed{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[16] + mi := &file_ark_v1_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -890,7 +991,7 @@ func (x *RoundFailed) String() string { func (*RoundFailed) ProtoMessage() {} func (x *RoundFailed) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[16] + mi := &file_ark_v1_service_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -903,7 +1004,7 @@ func (x *RoundFailed) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundFailed.ProtoReflect.Descriptor instead. func (*RoundFailed) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{16} + return file_ark_v1_service_proto_rawDescGZIP(), []int{18} } func (x *RoundFailed) GetId() string { @@ -929,7 +1030,7 @@ type GetEventStreamRequest struct { func (x *GetEventStreamRequest) Reset() { *x = GetEventStreamRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[17] + mi := &file_ark_v1_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -942,7 +1043,7 @@ func (x *GetEventStreamRequest) String() string { func (*GetEventStreamRequest) ProtoMessage() {} func (x *GetEventStreamRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[17] + mi := &file_ark_v1_service_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -955,7 +1056,7 @@ func (x *GetEventStreamRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventStreamRequest.ProtoReflect.Descriptor instead. func (*GetEventStreamRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{17} + return file_ark_v1_service_proto_rawDescGZIP(), []int{19} } type GetEventStreamResponse struct { @@ -974,7 +1075,7 @@ type GetEventStreamResponse struct { func (x *GetEventStreamResponse) Reset() { *x = GetEventStreamResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[18] + mi := &file_ark_v1_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -987,7 +1088,7 @@ func (x *GetEventStreamResponse) String() string { func (*GetEventStreamResponse) ProtoMessage() {} func (x *GetEventStreamResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[18] + mi := &file_ark_v1_service_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1000,7 +1101,7 @@ func (x *GetEventStreamResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetEventStreamResponse.ProtoReflect.Descriptor instead. func (*GetEventStreamResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{18} + return file_ark_v1_service_proto_rawDescGZIP(), []int{20} } func (m *GetEventStreamResponse) GetEvent() isGetEventStreamResponse_Event { @@ -1064,7 +1165,7 @@ type PingRequest struct { func (x *PingRequest) Reset() { *x = PingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[19] + mi := &file_ark_v1_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1077,7 +1178,7 @@ func (x *PingRequest) String() string { func (*PingRequest) ProtoMessage() {} func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[19] + mi := &file_ark_v1_service_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1090,7 +1191,7 @@ func (x *PingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. func (*PingRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{19} + return file_ark_v1_service_proto_rawDescGZIP(), []int{21} } func (x *PingRequest) GetPaymentId() string { @@ -1109,7 +1210,7 @@ type PingResponse struct { func (x *PingResponse) Reset() { *x = PingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[20] + mi := &file_ark_v1_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1223,7 @@ func (x *PingResponse) String() string { func (*PingResponse) ProtoMessage() {} func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[20] + mi := &file_ark_v1_service_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,91 +1236,6 @@ func (x *PingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. func (*PingResponse) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{20} -} - -type FaucetRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` -} - -func (x *FaucetRequest) Reset() { - *x = FaucetRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FaucetRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FaucetRequest) ProtoMessage() {} - -func (x *FaucetRequest) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FaucetRequest.ProtoReflect.Descriptor instead. -func (*FaucetRequest) Descriptor() ([]byte, []int) { - return file_ark_v1_service_proto_rawDescGZIP(), []int{21} -} - -func (x *FaucetRequest) GetAddress() string { - if x != nil { - return x.Address - } - return "" -} - -type FaucetResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *FaucetResponse) Reset() { - *x = FaucetResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_ark_v1_service_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FaucetResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FaucetResponse) ProtoMessage() {} - -func (x *FaucetResponse) ProtoReflect() protoreflect.Message { - mi := &file_ark_v1_service_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FaucetResponse.ProtoReflect.Descriptor instead. -func (*FaucetResponse) Descriptor() ([]byte, []int) { return file_ark_v1_service_proto_rawDescGZIP(), []int{22} } @@ -1495,191 +1511,197 @@ var file_ark_v1_service_proto_rawDesc = []byte{ 0x0a, 0x14, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3f, 0x0a, 0x16, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x89, 0x01, 0x0a, + 0x0e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x78, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x78, + 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x72, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x73, + 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x11, 0x0a, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x0a, 0x16, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x22, 0x29, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x22, 0x29, 0x0a, - 0x17, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x13, 0x43, 0x6c, 0x61, 0x69, - 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x28, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6c, 0x61, - 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x46, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, - 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x46, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x22, 0x37, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x23, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x05, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x8a, 0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, - 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, - 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, - 0x65, 0x22, 0x2f, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, - 0x75, 0x74, 0x22, 0x3a, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa8, - 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x6f, 0x6f, - 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x70, 0x6f, 0x6f, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x54, - 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, - 0x78, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, - 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, 0x22, 0x31, 0x0a, 0x04, 0x54, 0x72, 0x65, - 0x65, 0x12, 0x29, 0x0a, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x22, 0x2f, 0x0a, 0x09, - 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x4b, 0x0a, - 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x78, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x78, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x13, 0x52, 0x6f, - 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x22, 0x35, - 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xf4, - 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x12, 0x72, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x0f, 0x72, 0x6f, - 0x75, 0x6e, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, - 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x0e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x66, 0x61, 0x69, 0x6c, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, - 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x29, 0x0a, 0x0d, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x10, - 0x0a, 0x0e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2c, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x37, - 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, - 0x52, 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x04, 0x56, 0x74, 0x78, 0x6f, - 0x12, 0x29, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, - 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x72, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x08, 0x72, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x64, 0x0a, 0x0f, - 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x78, 0x69, 0x74, 0x44, 0x65, 0x6c, - 0x61, 0x79, 0x32, 0xf5, 0x06, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x73, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, - 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x61, - 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x12, - 0x73, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x13, 0x43, 0x6c, 0x61, 0x69, 0x6d, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, + 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, + 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6c, 0x61, 0x69, + 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x46, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, + 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, - 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x66, 0x69, 0x6e, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, - 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, - 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, - 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x65, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, - 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, - 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, - 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x55, 0x0a, 0x06, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, - 0x12, 0x15, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x46, 0x61, 0x75, 0x63, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x61, 0x75, - 0x63, 0x65, 0x74, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x5d, 0x0a, - 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78, - 0x6f, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x4c, 0x0a, 0x07, - 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, - 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, - 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, - 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x22, 0x37, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, + 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x05, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x22, 0x8a, 0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, + 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, + 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, + 0x22, 0x2f, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x76, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x76, 0x6f, 0x75, + 0x74, 0x22, 0x3a, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa8, 0x01, + 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x6f, 0x6f, 0x6c, + 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x70, 0x6f, 0x6f, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x78, + 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x5f, 0x74, 0x78, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, + 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x72, 0x65, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x72, 0x65, 0x65, 0x22, 0x31, 0x0a, 0x04, 0x54, 0x72, 0x65, 0x65, + 0x12, 0x29, 0x0a, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x65, 0x65, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x22, 0x2f, 0x0a, 0x09, 0x54, + 0x72, 0x65, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x4b, 0x0a, 0x04, + 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x78, 0x69, 0x64, 0x22, 0x42, 0x0a, 0x13, 0x52, 0x6f, 0x75, + 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x22, 0x35, 0x0a, + 0x0b, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xf4, 0x01, + 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x12, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, + 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x0f, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, + 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, + 0x00, 0x52, 0x0e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0b, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x22, 0x37, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, + 0x78, 0x6f, 0x52, 0x05, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x04, 0x56, 0x74, + 0x78, 0x6f, 0x12, 0x29, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2a, 0x0a, + 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, + 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x54, 0x78, 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x64, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x66, + 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x69, 0x66, + 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x64, 0x65, + 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x78, 0x69, 0x74, 0x44, + 0x65, 0x6c, 0x61, 0x79, 0x32, 0xf2, 0x06, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, + 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x0c, 0x43, 0x6c, 0x61, 0x69, + 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6c, 0x61, 0x69, 0x6d, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x12, 0x73, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, + 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, + 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, + 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, + 0x65, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x13, + 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, + 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, + 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x2f, 0x7b, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x4c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x07, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, + 0x31, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x42, 0x92, 0x01, 0x0a, 0x0a, 0x63, 0x6f, + 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x76, + 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, + 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1696,29 +1718,29 @@ func file_ark_v1_service_proto_rawDescGZIP() []byte { var file_ark_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 28) var file_ark_v1_service_proto_goTypes = []interface{}{ - (*RegisterPaymentRequest)(nil), // 0: ark.v1.RegisterPaymentRequest - (*RegisterPaymentResponse)(nil), // 1: ark.v1.RegisterPaymentResponse - (*ClaimPaymentRequest)(nil), // 2: ark.v1.ClaimPaymentRequest - (*ClaimPaymentResponse)(nil), // 3: ark.v1.ClaimPaymentResponse - (*FinalizePaymentRequest)(nil), // 4: ark.v1.FinalizePaymentRequest - (*FinalizePaymentResponse)(nil), // 5: ark.v1.FinalizePaymentResponse - (*GetRoundRequest)(nil), // 6: ark.v1.GetRoundRequest - (*GetRoundResponse)(nil), // 7: ark.v1.GetRoundResponse - (*Round)(nil), // 8: ark.v1.Round - (*Input)(nil), // 9: ark.v1.Input - (*Output)(nil), // 10: ark.v1.Output - (*RoundFinalizationEvent)(nil), // 11: ark.v1.RoundFinalizationEvent - (*Tree)(nil), // 12: ark.v1.Tree - (*TreeLevel)(nil), // 13: ark.v1.TreeLevel - (*Node)(nil), // 14: ark.v1.Node - (*RoundFinalizedEvent)(nil), // 15: ark.v1.RoundFinalizedEvent - (*RoundFailed)(nil), // 16: ark.v1.RoundFailed - (*GetEventStreamRequest)(nil), // 17: ark.v1.GetEventStreamRequest - (*GetEventStreamResponse)(nil), // 18: ark.v1.GetEventStreamResponse - (*PingRequest)(nil), // 19: ark.v1.PingRequest - (*PingResponse)(nil), // 20: ark.v1.PingResponse - (*FaucetRequest)(nil), // 21: ark.v1.FaucetRequest - (*FaucetResponse)(nil), // 22: ark.v1.FaucetResponse + (*OnboardRequest)(nil), // 0: ark.v1.OnboardRequest + (*OnboardResponse)(nil), // 1: ark.v1.OnboardResponse + (*RegisterPaymentRequest)(nil), // 2: ark.v1.RegisterPaymentRequest + (*RegisterPaymentResponse)(nil), // 3: ark.v1.RegisterPaymentResponse + (*ClaimPaymentRequest)(nil), // 4: ark.v1.ClaimPaymentRequest + (*ClaimPaymentResponse)(nil), // 5: ark.v1.ClaimPaymentResponse + (*FinalizePaymentRequest)(nil), // 6: ark.v1.FinalizePaymentRequest + (*FinalizePaymentResponse)(nil), // 7: ark.v1.FinalizePaymentResponse + (*GetRoundRequest)(nil), // 8: ark.v1.GetRoundRequest + (*GetRoundResponse)(nil), // 9: ark.v1.GetRoundResponse + (*Round)(nil), // 10: ark.v1.Round + (*Input)(nil), // 11: ark.v1.Input + (*Output)(nil), // 12: ark.v1.Output + (*RoundFinalizationEvent)(nil), // 13: ark.v1.RoundFinalizationEvent + (*Tree)(nil), // 14: ark.v1.Tree + (*TreeLevel)(nil), // 15: ark.v1.TreeLevel + (*Node)(nil), // 16: ark.v1.Node + (*RoundFinalizedEvent)(nil), // 17: ark.v1.RoundFinalizedEvent + (*RoundFailed)(nil), // 18: ark.v1.RoundFailed + (*GetEventStreamRequest)(nil), // 19: ark.v1.GetEventStreamRequest + (*GetEventStreamResponse)(nil), // 20: ark.v1.GetEventStreamResponse + (*PingRequest)(nil), // 21: ark.v1.PingRequest + (*PingResponse)(nil), // 22: ark.v1.PingResponse (*ListVtxosRequest)(nil), // 23: ark.v1.ListVtxosRequest (*ListVtxosResponse)(nil), // 24: ark.v1.ListVtxosResponse (*Vtxo)(nil), // 25: ark.v1.Vtxo @@ -1726,42 +1748,43 @@ var file_ark_v1_service_proto_goTypes = []interface{}{ (*GetInfoResponse)(nil), // 27: ark.v1.GetInfoResponse } var file_ark_v1_service_proto_depIdxs = []int32{ - 9, // 0: ark.v1.RegisterPaymentRequest.inputs:type_name -> ark.v1.Input - 10, // 1: ark.v1.ClaimPaymentRequest.outputs:type_name -> ark.v1.Output - 8, // 2: ark.v1.GetRoundResponse.round:type_name -> ark.v1.Round - 12, // 3: ark.v1.Round.congestion_tree:type_name -> ark.v1.Tree - 12, // 4: ark.v1.RoundFinalizationEvent.congestion_tree:type_name -> ark.v1.Tree - 13, // 5: ark.v1.Tree.levels:type_name -> ark.v1.TreeLevel - 14, // 6: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node - 11, // 7: ark.v1.GetEventStreamResponse.round_finalization:type_name -> ark.v1.RoundFinalizationEvent - 15, // 8: ark.v1.GetEventStreamResponse.round_finalized:type_name -> ark.v1.RoundFinalizedEvent - 16, // 9: ark.v1.GetEventStreamResponse.round_failed:type_name -> ark.v1.RoundFailed - 25, // 10: ark.v1.ListVtxosResponse.vtxos:type_name -> ark.v1.Vtxo - 9, // 11: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Input - 10, // 12: ark.v1.Vtxo.receiver:type_name -> ark.v1.Output - 0, // 13: ark.v1.ArkService.RegisterPayment:input_type -> ark.v1.RegisterPaymentRequest - 2, // 14: ark.v1.ArkService.ClaimPayment:input_type -> ark.v1.ClaimPaymentRequest - 4, // 15: ark.v1.ArkService.FinalizePayment:input_type -> ark.v1.FinalizePaymentRequest - 6, // 16: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest - 17, // 17: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest - 19, // 18: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest - 21, // 19: ark.v1.ArkService.Faucet:input_type -> ark.v1.FaucetRequest + 14, // 0: ark.v1.OnboardRequest.congestion_tree:type_name -> ark.v1.Tree + 11, // 1: ark.v1.RegisterPaymentRequest.inputs:type_name -> ark.v1.Input + 12, // 2: ark.v1.ClaimPaymentRequest.outputs:type_name -> ark.v1.Output + 10, // 3: ark.v1.GetRoundResponse.round:type_name -> ark.v1.Round + 14, // 4: ark.v1.Round.congestion_tree:type_name -> ark.v1.Tree + 14, // 5: ark.v1.RoundFinalizationEvent.congestion_tree:type_name -> ark.v1.Tree + 15, // 6: ark.v1.Tree.levels:type_name -> ark.v1.TreeLevel + 16, // 7: ark.v1.TreeLevel.nodes:type_name -> ark.v1.Node + 13, // 8: ark.v1.GetEventStreamResponse.round_finalization:type_name -> ark.v1.RoundFinalizationEvent + 17, // 9: ark.v1.GetEventStreamResponse.round_finalized:type_name -> ark.v1.RoundFinalizedEvent + 18, // 10: ark.v1.GetEventStreamResponse.round_failed:type_name -> ark.v1.RoundFailed + 25, // 11: ark.v1.ListVtxosResponse.vtxos:type_name -> ark.v1.Vtxo + 11, // 12: ark.v1.Vtxo.outpoint:type_name -> ark.v1.Input + 12, // 13: ark.v1.Vtxo.receiver:type_name -> ark.v1.Output + 2, // 14: ark.v1.ArkService.RegisterPayment:input_type -> ark.v1.RegisterPaymentRequest + 4, // 15: ark.v1.ArkService.ClaimPayment:input_type -> ark.v1.ClaimPaymentRequest + 6, // 16: ark.v1.ArkService.FinalizePayment:input_type -> ark.v1.FinalizePaymentRequest + 8, // 17: ark.v1.ArkService.GetRound:input_type -> ark.v1.GetRoundRequest + 19, // 18: ark.v1.ArkService.GetEventStream:input_type -> ark.v1.GetEventStreamRequest + 21, // 19: ark.v1.ArkService.Ping:input_type -> ark.v1.PingRequest 23, // 20: ark.v1.ArkService.ListVtxos:input_type -> ark.v1.ListVtxosRequest 26, // 21: ark.v1.ArkService.GetInfo:input_type -> ark.v1.GetInfoRequest - 1, // 22: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse - 3, // 23: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse - 5, // 24: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse - 7, // 25: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse - 18, // 26: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse - 20, // 27: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse - 22, // 28: ark.v1.ArkService.Faucet:output_type -> ark.v1.FaucetResponse + 0, // 22: ark.v1.ArkService.Onboard:input_type -> ark.v1.OnboardRequest + 3, // 23: ark.v1.ArkService.RegisterPayment:output_type -> ark.v1.RegisterPaymentResponse + 5, // 24: ark.v1.ArkService.ClaimPayment:output_type -> ark.v1.ClaimPaymentResponse + 7, // 25: ark.v1.ArkService.FinalizePayment:output_type -> ark.v1.FinalizePaymentResponse + 9, // 26: ark.v1.ArkService.GetRound:output_type -> ark.v1.GetRoundResponse + 20, // 27: ark.v1.ArkService.GetEventStream:output_type -> ark.v1.GetEventStreamResponse + 22, // 28: ark.v1.ArkService.Ping:output_type -> ark.v1.PingResponse 24, // 29: ark.v1.ArkService.ListVtxos:output_type -> ark.v1.ListVtxosResponse 27, // 30: ark.v1.ArkService.GetInfo:output_type -> ark.v1.GetInfoResponse - 22, // [22:31] is the sub-list for method output_type - 13, // [13:22] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 1, // 31: ark.v1.ArkService.Onboard:output_type -> ark.v1.OnboardResponse + 23, // [23:32] is the sub-list for method output_type + 14, // [14:23] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_ark_v1_service_proto_init() } @@ -1771,7 +1794,7 @@ func file_ark_v1_service_proto_init() { } if !protoimpl.UnsafeEnabled { file_ark_v1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterPaymentRequest); i { + switch v := v.(*OnboardRequest); i { case 0: return &v.state case 1: @@ -1783,7 +1806,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterPaymentResponse); i { + switch v := v.(*OnboardResponse); i { case 0: return &v.state case 1: @@ -1795,7 +1818,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClaimPaymentRequest); i { + switch v := v.(*RegisterPaymentRequest); i { case 0: return &v.state case 1: @@ -1807,7 +1830,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClaimPaymentResponse); i { + switch v := v.(*RegisterPaymentResponse); i { case 0: return &v.state case 1: @@ -1819,7 +1842,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FinalizePaymentRequest); i { + switch v := v.(*ClaimPaymentRequest); i { case 0: return &v.state case 1: @@ -1831,7 +1854,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FinalizePaymentResponse); i { + switch v := v.(*ClaimPaymentResponse); i { case 0: return &v.state case 1: @@ -1843,7 +1866,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetRoundRequest); i { + switch v := v.(*FinalizePaymentRequest); i { case 0: return &v.state case 1: @@ -1855,7 +1878,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetRoundResponse); i { + switch v := v.(*FinalizePaymentResponse); i { case 0: return &v.state case 1: @@ -1867,7 +1890,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Round); i { + switch v := v.(*GetRoundRequest); i { case 0: return &v.state case 1: @@ -1879,7 +1902,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Input); i { + switch v := v.(*GetRoundResponse); i { case 0: return &v.state case 1: @@ -1891,7 +1914,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Output); i { + switch v := v.(*Round); i { case 0: return &v.state case 1: @@ -1903,7 +1926,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFinalizationEvent); i { + switch v := v.(*Input); i { case 0: return &v.state case 1: @@ -1915,7 +1938,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Tree); i { + switch v := v.(*Output); i { case 0: return &v.state case 1: @@ -1927,7 +1950,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TreeLevel); i { + switch v := v.(*RoundFinalizationEvent); i { case 0: return &v.state case 1: @@ -1939,7 +1962,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Node); i { + switch v := v.(*Tree); i { case 0: return &v.state case 1: @@ -1951,7 +1974,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFinalizedEvent); i { + switch v := v.(*TreeLevel); i { case 0: return &v.state case 1: @@ -1963,7 +1986,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoundFailed); i { + switch v := v.(*Node); i { case 0: return &v.state case 1: @@ -1975,7 +1998,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetEventStreamRequest); i { + switch v := v.(*RoundFinalizedEvent); i { case 0: return &v.state case 1: @@ -1987,7 +2010,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetEventStreamResponse); i { + switch v := v.(*RoundFailed); i { case 0: return &v.state case 1: @@ -1999,7 +2022,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingRequest); i { + switch v := v.(*GetEventStreamRequest); i { case 0: return &v.state case 1: @@ -2011,7 +2034,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PingResponse); i { + switch v := v.(*GetEventStreamResponse); i { case 0: return &v.state case 1: @@ -2023,7 +2046,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FaucetRequest); i { + switch v := v.(*PingRequest); i { case 0: return &v.state case 1: @@ -2035,7 +2058,7 @@ func file_ark_v1_service_proto_init() { } } file_ark_v1_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FaucetResponse); i { + switch v := v.(*PingResponse); i { case 0: return &v.state case 1: @@ -2107,7 +2130,7 @@ func file_ark_v1_service_proto_init() { } } } - file_ark_v1_service_proto_msgTypes[18].OneofWrappers = []interface{}{ + file_ark_v1_service_proto_msgTypes[20].OneofWrappers = []interface{}{ (*GetEventStreamResponse_RoundFinalization)(nil), (*GetEventStreamResponse_RoundFinalized)(nil), (*GetEventStreamResponse_RoundFailed)(nil), diff --git a/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go b/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go index d436bb8..c981689 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go +++ b/server/api-spec/protobuf/gen/ark/v1/service.pb.gw.go @@ -230,58 +230,6 @@ func local_request_ArkService_Ping_0(ctx context.Context, marshaler runtime.Mars } -func request_ArkService_Faucet_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq FaucetRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["address"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") - } - - protoReq.Address, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) - } - - msg, err := client.Faucet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_ArkService_Faucet_0(ctx context.Context, marshaler runtime.Marshaler, server ArkServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq FaucetRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["address"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") - } - - protoReq.Address, err = runtime.String(val) - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) - } - - msg, err := server.Faucet(ctx, &protoReq) - return msg, metadata, err - -} - func request_ArkService_ListVtxos_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq ListVtxosRequest var metadata runtime.ServerMetadata @@ -352,6 +300,32 @@ func local_request_ArkService_GetInfo_0(ctx context.Context, marshaler runtime.M } +func request_ArkService_Onboard_0(ctx context.Context, marshaler runtime.Marshaler, client ArkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OnboardRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Onboard(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArkService_Onboard_0(ctx context.Context, marshaler runtime.Marshaler, server ArkServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq OnboardRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Onboard(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterArkServiceHandlerServer registers the http handlers for service ArkService to "mux". // UnaryRPC :call ArkServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -490,31 +464,6 @@ func RegisterArkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) - mux.Handle("POST", pattern_ArkService_Faucet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.ArkService/Faucet", runtime.WithHTTPPathPattern("/v1/faucet/{address}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_ArkService_Faucet_0(annotatedContext, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_ArkService_Faucet_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_ArkService_ListVtxos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -565,6 +514,31 @@ func RegisterArkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_ArkService_Onboard_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/ark.v1.ArkService/Onboard", runtime.WithHTTPPathPattern("/v1/onboard")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArkService_Onboard_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_Onboard_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -738,28 +712,6 @@ func RegisterArkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) - mux.Handle("POST", pattern_ArkService_Faucet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ark.v1.ArkService/Faucet", runtime.WithHTTPPathPattern("/v1/faucet/{address}")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ArkService_Faucet_0(annotatedContext, inboundMarshaler, client, req, pathParams) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_ArkService_Faucet_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_ArkService_ListVtxos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -804,6 +756,28 @@ func RegisterArkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_ArkService_Onboard_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/ark.v1.ArkService/Onboard", runtime.WithHTTPPathPattern("/v1/onboard")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArkService_Onboard_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArkService_Onboard_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -820,11 +794,11 @@ var ( pattern_ArkService_Ping_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "ping", "payment_id"}, "")) - pattern_ArkService_Faucet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "faucet", "address"}, "")) - pattern_ArkService_ListVtxos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "vtxos", "address"}, "")) pattern_ArkService_GetInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "info"}, "")) + + pattern_ArkService_Onboard_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "onboard"}, "")) ) var ( @@ -840,9 +814,9 @@ var ( forward_ArkService_Ping_0 = runtime.ForwardResponseMessage - forward_ArkService_Faucet_0 = runtime.ForwardResponseMessage - forward_ArkService_ListVtxos_0 = runtime.ForwardResponseMessage forward_ArkService_GetInfo_0 = runtime.ForwardResponseMessage + + forward_ArkService_Onboard_0 = runtime.ForwardResponseMessage ) diff --git a/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go b/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go index 4bf44d1..12d9057 100644 --- a/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go +++ b/server/api-spec/protobuf/gen/ark/v1/service_grpc.pb.go @@ -24,9 +24,9 @@ type ArkServiceClient interface { GetRound(ctx context.Context, in *GetRoundRequest, opts ...grpc.CallOption) (*GetRoundResponse, error) GetEventStream(ctx context.Context, in *GetEventStreamRequest, opts ...grpc.CallOption) (ArkService_GetEventStreamClient, error) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - Faucet(ctx context.Context, in *FaucetRequest, opts ...grpc.CallOption) (*FaucetResponse, error) ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) GetInfo(ctx context.Context, in *GetInfoRequest, opts ...grpc.CallOption) (*GetInfoResponse, error) + Onboard(ctx context.Context, in *OnboardRequest, opts ...grpc.CallOption) (*OnboardResponse, error) } type arkServiceClient struct { @@ -114,15 +114,6 @@ func (c *arkServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...gr return out, nil } -func (c *arkServiceClient) Faucet(ctx context.Context, in *FaucetRequest, opts ...grpc.CallOption) (*FaucetResponse, error) { - out := new(FaucetResponse) - err := c.cc.Invoke(ctx, "/ark.v1.ArkService/Faucet", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *arkServiceClient) ListVtxos(ctx context.Context, in *ListVtxosRequest, opts ...grpc.CallOption) (*ListVtxosResponse, error) { out := new(ListVtxosResponse) err := c.cc.Invoke(ctx, "/ark.v1.ArkService/ListVtxos", in, out, opts...) @@ -141,6 +132,15 @@ func (c *arkServiceClient) GetInfo(ctx context.Context, in *GetInfoRequest, opts return out, nil } +func (c *arkServiceClient) Onboard(ctx context.Context, in *OnboardRequest, opts ...grpc.CallOption) (*OnboardResponse, error) { + out := new(OnboardResponse) + err := c.cc.Invoke(ctx, "/ark.v1.ArkService/Onboard", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ArkServiceServer is the server API for ArkService service. // All implementations should embed UnimplementedArkServiceServer // for forward compatibility @@ -151,9 +151,9 @@ type ArkServiceServer interface { GetRound(context.Context, *GetRoundRequest) (*GetRoundResponse, error) GetEventStream(*GetEventStreamRequest, ArkService_GetEventStreamServer) error Ping(context.Context, *PingRequest) (*PingResponse, error) - Faucet(context.Context, *FaucetRequest) (*FaucetResponse, error) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) + Onboard(context.Context, *OnboardRequest) (*OnboardResponse, error) } // UnimplementedArkServiceServer should be embedded to have forward compatible implementations. @@ -178,15 +178,15 @@ func (UnimplementedArkServiceServer) GetEventStream(*GetEventStreamRequest, ArkS func (UnimplementedArkServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } -func (UnimplementedArkServiceServer) Faucet(context.Context, *FaucetRequest) (*FaucetResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Faucet not implemented") -} func (UnimplementedArkServiceServer) ListVtxos(context.Context, *ListVtxosRequest) (*ListVtxosResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListVtxos not implemented") } func (UnimplementedArkServiceServer) GetInfo(context.Context, *GetInfoRequest) (*GetInfoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetInfo not implemented") } +func (UnimplementedArkServiceServer) Onboard(context.Context, *OnboardRequest) (*OnboardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Onboard not implemented") +} // UnsafeArkServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ArkServiceServer will @@ -310,24 +310,6 @@ func _ArkService_Ping_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } -func _ArkService_Faucet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(FaucetRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ArkServiceServer).Faucet(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ark.v1.ArkService/Faucet", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArkServiceServer).Faucet(ctx, req.(*FaucetRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _ArkService_ListVtxos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListVtxosRequest) if err := dec(in); err != nil { @@ -364,6 +346,24 @@ func _ArkService_GetInfo_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _ArkService_Onboard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OnboardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArkServiceServer).Onboard(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ark.v1.ArkService/Onboard", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArkServiceServer).Onboard(ctx, req.(*OnboardRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ArkService_ServiceDesc is the grpc.ServiceDesc for ArkService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -391,10 +391,6 @@ var ArkService_ServiceDesc = grpc.ServiceDesc{ MethodName: "Ping", Handler: _ArkService_Ping_Handler, }, - { - MethodName: "Faucet", - Handler: _ArkService_Faucet_Handler, - }, { MethodName: "ListVtxos", Handler: _ArkService_ListVtxos_Handler, @@ -403,6 +399,10 @@ var ArkService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetInfo", Handler: _ArkService_GetInfo_Handler, }, + { + MethodName: "Onboard", + Handler: _ArkService_Onboard_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/server/internal/app-config/config.go b/server/internal/app-config/config.go index f7b5839..17f5043 100644 --- a/server/internal/app-config/config.go +++ b/server/internal/app-config/config.go @@ -11,7 +11,6 @@ import ( oceanwallet "github.com/ark-network/ark/internal/infrastructure/ocean-wallet" scheduler "github.com/ark-network/ark/internal/infrastructure/scheduler/gocron" txbuilder "github.com/ark-network/ark/internal/infrastructure/tx-builder/covenant" - txbuilderdummy "github.com/ark-network/ark/internal/infrastructure/tx-builder/dummy" log "github.com/sirupsen/logrus" "github.com/vulpemventures/go-elements/network" ) @@ -24,7 +23,6 @@ var ( "gocron": {}, } supportedTxBuilders = supportedType{ - "dummy": {}, "covenant": {}, } supportedScanners = supportedType{ @@ -167,8 +165,6 @@ func (c *Config) txBuilderService() error { net := c.mainChain() switch c.TxBuilderType { - case "dummy": - svc = txbuilderdummy.NewTxBuilder(c.wallet, net) case "covenant": svc = txbuilder.NewTxBuilder(c.wallet, net, c.RoundLifetime, c.ExitDelay) default: diff --git a/server/internal/core/application/service.go b/server/internal/core/application/service.go index 99342b7..3f1eb97 100644 --- a/server/internal/core/application/service.go +++ b/server/internal/core/application/service.go @@ -8,6 +8,7 @@ import ( "time" "github.com/ark-network/ark/common" + "github.com/ark-network/ark/common/tree" "github.com/ark-network/ark/internal/core/domain" "github.com/ark-network/ark/internal/core/ports" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -20,10 +21,6 @@ import ( var ( paymentsThreshold = int64(128) dustAmount = uint64(450) - faucetVtxo = domain.VtxoKey{ - Txid: "0000000000000000000000000000000000000000000000000000000000000000", - VOut: 0, - } ) type Service interface { @@ -32,12 +29,12 @@ type Service interface { SpendVtxos(ctx context.Context, inputs []domain.VtxoKey) (string, error) ClaimVtxos(ctx context.Context, creds string, receivers []domain.Receiver) error SignVtxos(ctx context.Context, forfeitTxs []string) error - FaucetVtxos(ctx context.Context, pubkey *secp256k1.PublicKey) error GetRoundByTxid(ctx context.Context, poolTxid string) (*domain.Round, error) GetEventsChannel(ctx context.Context) <-chan domain.RoundEvent UpdatePaymentStatus(ctx context.Context, id string) error ListVtxos(ctx context.Context, pubkey *secp256k1.PublicKey) ([]domain.Vtxo, error) GetInfo(ctx context.Context) (string, int64, int64, error) + Onboard(ctx context.Context, boardingTx string, congestionTree tree.CongestionTree, userPubkey *secp256k1.PublicKey) error } type service struct { @@ -88,8 +85,9 @@ func NewService( } repoManager.RegisterEventsHandler( func(round *domain.Round) { - svc.updateProjectionStore(round) - svc.propagateEvents(round) + go svc.updateVtxoSet(round) + go svc.propagateEvents(round) + go svc.scheduleSweepVtxosForRound(round) }, ) @@ -165,43 +163,6 @@ func (s *service) UpdatePaymentStatus(_ context.Context, id string) error { return s.paymentRequests.updatePingTimestamp(id) } -func (s *service) FaucetVtxos(ctx context.Context, userPubkey *secp256k1.PublicKey) error { - pubkey := hex.EncodeToString(userPubkey.SerializeCompressed()) - - payment, err := domain.NewPayment([]domain.Vtxo{ - { - VtxoKey: faucetVtxo, - Receiver: domain.Receiver{ - Pubkey: pubkey, - Amount: 10000, - }, - }, - }) - if err != nil { - return err - } - - if err := payment.AddReceivers([]domain.Receiver{ - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - {Pubkey: pubkey, Amount: 1000}, - }); err != nil { - return err - } - - if err := s.paymentRequests.push(*payment); err != nil { - return err - } - return s.paymentRequests.updatePingTimestamp(payment.Id) -} - func (s *service) SignVtxos(ctx context.Context, forfeitTxs []string) error { return s.forfeitTxs.sign(forfeitTxs) } @@ -223,6 +184,40 @@ func (s *service) GetInfo(ctx context.Context) (string, int64, int64, error) { return hex.EncodeToString(s.pubkey.SerializeCompressed()), s.roundLifetime, s.exitDelay, nil } +func (s *service) Onboard( + ctx context.Context, boardingTx string, + congestionTree tree.CongestionTree, userPubkey *secp256k1.PublicKey, +) error { + if err := tree.ValidateCongestionTree( + congestionTree, boardingTx, s.pubkey, s.roundLifetime, + ); err != nil { + return err + } + ptx, err := psetv2.NewPsetFromBase64(boardingTx) + if err != nil { + return fmt.Errorf("failed to parse boarding tx: %s", err) + } + + utx, _ := ptx.UnsignedTx() + txid := utx.TxHash().String() + + isConfirmed, _, err := s.wallet.IsTransactionConfirmed(ctx, txid) + if err != nil { + return fmt.Errorf("failed to fetch confirmation info for boaridng tx: %s", err) + } + if !isConfirmed { + return fmt.Errorf("boarding tx not confirmed yet, please retry later") + } + + pubkey := hex.EncodeToString(userPubkey.SerializeCompressed()) + payments := getPaymentsFromOnboarding(congestionTree, pubkey) + round := domain.NewFinalizedRound( + dustAmount, pubkey, txid, boardingTx, congestionTree, payments, + ) + + return s.saveEvents(ctx, round.Id, round.Events()) +} + func (s *service) start() { s.startRound() } @@ -365,15 +360,6 @@ func (s *service) finalizeRound() { return } - now := time.Now().Unix() - expirationTimestamp := now + s.roundLifetime + 30 // add 30 secs to be sure that the tx is confirmed - - if err := s.sweeper.schedule(expirationTimestamp, txid, round.CongestionTree); err != nil { - changes = round.Fail(fmt.Errorf("failed to schedule sweep tx: %s", err)) - log.WithError(err).Warn("failed to schedule sweep tx") - return - } - changes, _ = round.EndFinalization(forfeitTxs, txid) log.Debugf("finalized round %s with pool tx %s", round.Id, round.Txid) @@ -403,49 +389,50 @@ func (s *service) listenToRedemptions() { } } -func (s *service) updateProjectionStore(round *domain.Round) { - ctx := context.Background() - lastChange := round.Events()[len(round.Events())-1] +func (s *service) updateVtxoSet(round *domain.Round) { // Update the vtxo set only after a round is finalized. - if _, ok := lastChange.(domain.RoundFinalized); ok { - repo := s.repoManager.Vtxos() - spentVtxos := getSpentVtxos(round.Payments) - if len(spentVtxos) > 0 { - for { - if err := repo.SpendVtxos(ctx, spentVtxos); err != nil { - log.WithError(err).Warn("failed to add new vtxos, retrying soon") - time.Sleep(100 * time.Millisecond) - continue - } - log.Debugf("spent %d vtxos", len(spentVtxos)) - break - } - } + if !round.IsEnded() { + return + } - newVtxos := s.getNewVtxos(round) + ctx := context.Background() + repo := s.repoManager.Vtxos() + spentVtxos := getSpentVtxos(round.Payments) + if len(spentVtxos) > 0 { for { - if err := repo.AddVtxos(ctx, newVtxos); err != nil { + if err := repo.SpendVtxos(ctx, spentVtxos); err != nil { log.WithError(err).Warn("failed to add new vtxos, retrying soon") time.Sleep(100 * time.Millisecond) continue } - log.Debugf("added %d new vtxos", len(newVtxos)) + log.Debugf("spent %d vtxos", len(spentVtxos)) break } - - go func() { - for { - if err := s.startWatchingVtxos(newVtxos); err != nil { - log.WithError(err).Warn( - "failed to start watching vtxos, retrying in a moment...", - ) - continue - } - log.Debugf("started watching %d vtxos", len(newVtxos)) - return - } - }() } + + newVtxos := s.getNewVtxos(round) + for { + if err := repo.AddVtxos(ctx, newVtxos); err != nil { + log.WithError(err).Warn("failed to add new vtxos, retrying soon") + time.Sleep(100 * time.Millisecond) + continue + } + log.Debugf("added %d new vtxos", len(newVtxos)) + break + } + + go func() { + for { + if err := s.startWatchingVtxos(newVtxos); err != nil { + log.WithError(err).Warn( + "failed to start watching vtxos, retrying in a moment...", + ) + continue + } + log.Debugf("started watching %d vtxos", len(newVtxos)) + return + } + }() } func (s *service) propagateEvents(round *domain.Round) { @@ -465,6 +452,23 @@ func (s *service) propagateEvents(round *domain.Round) { } } +func (s *service) scheduleSweepVtxosForRound(round *domain.Round) { + // Schedule the sweeping procedure only for completed round. + if !round.IsEnded() { + return + } + + expirationTimestamp := time.Now().Add( + time.Duration(s.roundLifetime+30) * time.Second, + ) + + if err := s.sweeper.schedule( + expirationTimestamp.Unix(), round.Txid, round.CongestionTree, + ); err != nil { + log.WithError(err).Warn("failed to schedule sweep tx") + } +} + func (s *service) getNewVtxos(round *domain.Round) []domain.Vtxo { leaves := round.CongestionTree.Leaves() vtxos := make([]domain.Vtxo, 0) @@ -590,11 +594,25 @@ func getSpentVtxos(payments map[string]domain.Payment) []domain.VtxoKey { vtxos := make([]domain.VtxoKey, 0) for _, p := range payments { for _, vtxo := range p.Inputs { - if vtxo.VtxoKey == faucetVtxo { - continue - } vtxos = append(vtxos, vtxo.VtxoKey) } } return vtxos } + +func getPaymentsFromOnboarding( + congestionTree tree.CongestionTree, userKey string, +) []domain.Payment { + leaves := congestionTree.Leaves() + receivers := make([]domain.Receiver, 0, len(leaves)) + for _, node := range leaves { + ptx, _ := psetv2.NewPsetFromBase64(node.Tx) + receiver := domain.Receiver{ + Pubkey: userKey, + Amount: ptx.Outputs[0].Value, + } + receivers = append(receivers, receiver) + } + payment := domain.NewPaymentUnsafe(nil, receivers) + return []domain.Payment{*payment} +} diff --git a/server/internal/core/application/sweeper.go b/server/internal/core/application/sweeper.go index 1ac1f3a..7165743 100644 --- a/server/internal/core/application/sweeper.go +++ b/server/internal/core/application/sweeper.go @@ -82,7 +82,7 @@ func (s *sweeper) schedule( task := s.createTask(roundTxid, congestionTree) fancyTime := time.Unix(expirationTimestamp, 0).Format("2006-01-02 15:04:05") - log.Debugf("scheduled sweep task at %s", fancyTime) + log.Debugf("scheduled sweep for round %s at %s", roundTxid, fancyTime) if err := s.scheduler.ScheduleTaskOnce(expirationTimestamp, task); err != nil { return err } @@ -290,7 +290,7 @@ func (s *sweeper) findSweepableOutputs( newNodesToCheck := make([]tree.Node, 0) for _, node := range nodesToCheck { - isPublished, blocktime, err := s.wallet.IsTransactionPublished(ctx, node.Txid) + isConfirmed, blocktime, err := s.wallet.IsTransactionConfirmed(ctx, node.Txid) if err != nil { return nil, err } @@ -298,10 +298,10 @@ func (s *sweeper) findSweepableOutputs( var expirationTime int64 var sweepInputs []ports.SweepInput - if !isPublished { + if !isConfirmed { if _, ok := blocktimeCache[node.ParentTxid]; !ok { - isPublished, blocktime, err := s.wallet.IsTransactionPublished(ctx, node.ParentTxid) - if !isPublished || err != nil { + isConfirmed, blocktime, err := s.wallet.IsTransactionConfirmed(ctx, node.ParentTxid) + if !isConfirmed || err != nil { return nil, fmt.Errorf("tx %s not found", node.Txid) } diff --git a/server/internal/core/application/utils.go b/server/internal/core/application/utils.go index d6575c2..b421a39 100644 --- a/server/internal/core/application/utils.go +++ b/server/internal/core/application/utils.go @@ -1,8 +1,6 @@ package application import ( - "bytes" - "encoding/hex" "fmt" "sort" "sync" @@ -154,23 +152,13 @@ func (m *forfeitTxsMap) push(txs []string) { m.lock.Lock() defer m.lock.Unlock() - faucetTxID, _ := hex.DecodeString(faucetVtxo.Txid) - for _, tx := range txs { ptx, _ := psetv2.NewPsetFromBase64(tx) utx, _ := ptx.UnsignedTx() - + txid := utx.TxHash().String() signed := false - // find the faucet vtxos, and mark them as signed - for _, input := range ptx.Inputs { - if bytes.Equal(input.PreviousTxid, faucetTxID) { - signed = true - break - } - } - - m.forfeitTxs[utx.TxHash().String()] = &signedTx{tx, signed} + m.forfeitTxs[txid] = &signedTx{tx, signed} } } diff --git a/server/internal/core/domain/payment.go b/server/internal/core/domain/payment.go index b8c3207..71b4cd8 100644 --- a/server/internal/core/domain/payment.go +++ b/server/internal/core/domain/payment.go @@ -28,6 +28,14 @@ func NewPayment(inputs []Vtxo) (*Payment, error) { return p, nil } +func NewPaymentUnsafe(inputs []Vtxo, receivers []Receiver) *Payment { + return &Payment{ + Id: uuid.New().String(), + Inputs: inputs, + Receivers: receivers, + } +} + func (p *Payment) AddReceivers(receivers []Receiver) (err error) { if p.Receivers == nil { p.Receivers = make([]Receiver, 0) diff --git a/server/internal/core/domain/round.go b/server/internal/core/domain/round.go index ca64634..87ae6a1 100644 --- a/server/internal/core/domain/round.go +++ b/server/internal/core/domain/round.go @@ -59,6 +59,39 @@ func NewRound(dustAmount uint64) *Round { } } +func NewFinalizedRound( + dustAmount uint64, userKey, poolTxid, poolTx string, + congestionTree tree.CongestionTree, payments []Payment, +) *Round { + r := NewRound(dustAmount) + events := []RoundEvent{ + RoundStarted{ + Id: r.Id, + Timestamp: time.Now().Unix(), + }, + PaymentsRegistered{ + Id: r.Id, + Payments: payments, + }, + RoundFinalizationStarted{ + Id: r.Id, + CongestionTree: congestionTree, + PoolTx: poolTx, + }, + RoundFinalized{ + Id: r.Id, + Txid: poolTxid, + Timestamp: time.Now().Unix(), + }, + } + + for _, event := range events { + r.raise(event) + } + + return r +} + func NewRoundFromEvents(events []RoundEvent) *Round { r := &Round{} diff --git a/server/internal/core/ports/wallet.go b/server/internal/core/ports/wallet.go index baa15b2..3963055 100644 --- a/server/internal/core/ports/wallet.go +++ b/server/internal/core/ports/wallet.go @@ -17,7 +17,7 @@ type WalletService interface { SelectUtxos(ctx context.Context, asset string, amount uint64) ([]TxInput, uint64, error) BroadcastTransaction(ctx context.Context, txHex string) (string, error) SignPsetWithKey(ctx context.Context, pset string, inputIndexes []int) (string, error) // inputIndexes == nil means sign all inputs - IsTransactionPublished(ctx context.Context, txid string) (isPublished bool, blocktime int64, err error) + IsTransactionConfirmed(ctx context.Context, txid string) (isConfirmed bool, blocktime int64, err error) EstimateFees(ctx context.Context, pset string) (uint64, error) Close() } diff --git a/server/internal/infrastructure/ocean-wallet/transaction.go b/server/internal/infrastructure/ocean-wallet/transaction.go index c644e3e..bfafb51 100644 --- a/server/internal/infrastructure/ocean-wallet/transaction.go +++ b/server/internal/infrastructure/ocean-wallet/transaction.go @@ -117,7 +117,7 @@ func (s *service) BroadcastTransaction( return res.GetTxid(), nil } -func (s *service) IsTransactionPublished( +func (s *service) IsTransactionConfirmed( ctx context.Context, txid string, ) (bool, int64, error) { _, blocktime, err := s.GetTransaction(ctx, txid) diff --git a/server/internal/infrastructure/tx-builder/covenant/builder.go b/server/internal/infrastructure/tx-builder/covenant/builder.go index f5f6e9c..6534021 100644 --- a/server/internal/infrastructure/tx-builder/covenant/builder.go +++ b/server/internal/infrastructure/tx-builder/covenant/builder.go @@ -113,8 +113,8 @@ func (b *txBuilder) BuildPoolTx( // generated in the process and takes the shared utxo outpoint as argument. // This is safe as the memory allocated for `craftCongestionTree` is freed // only after `BuildPoolTx` returns. - treeFactoryFn, sharedOutputScript, sharedOutputAmount, err := craftCongestionTree( - b.net.AssetID, aspPubkey, payments, minRelayFee, b.roundLifetime, b.exitDelay, + treeFactoryFn, sharedOutputScript, sharedOutputAmount, err := tree.CraftCongestionTree( + b.net.AssetID, aspPubkey, getOffchainReceivers(payments), minRelayFee, b.roundLifetime, b.exitDelay, ) if err != nil { return diff --git a/server/internal/infrastructure/tx-builder/covenant/mocks_test.go b/server/internal/infrastructure/tx-builder/covenant/mocks_test.go index 574d251..9c38874 100644 --- a/server/internal/infrastructure/tx-builder/covenant/mocks_test.go +++ b/server/internal/infrastructure/tx-builder/covenant/mocks_test.go @@ -97,7 +97,7 @@ func (m *mockedWallet) EstimateFees(ctx context.Context, pset string) (uint64, e return res, args.Error(1) } -func (m *mockedWallet) IsTransactionPublished(ctx context.Context, txid string) (bool, int64, error) { +func (m *mockedWallet) IsTransactionConfirmed(ctx context.Context, txid string) (bool, int64, error) { args := m.Called(ctx, txid) var res bool diff --git a/server/internal/infrastructure/tx-builder/covenant/utils.go b/server/internal/infrastructure/tx-builder/covenant/utils.go index 07e805e..3bbcbde 100644 --- a/server/internal/infrastructure/tx-builder/covenant/utils.go +++ b/server/internal/infrastructure/tx-builder/covenant/utils.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" + "github.com/ark-network/ark/common/tree" "github.com/ark-network/ark/internal/core/domain" "github.com/ark-network/ark/internal/core/ports" "github.com/btcsuite/btcd/btcec/v2/schnorr" @@ -14,7 +15,6 @@ import ( "github.com/vulpemventures/go-elements/network" "github.com/vulpemventures/go-elements/payment" "github.com/vulpemventures/go-elements/psetv2" - "github.com/vulpemventures/go-elements/taproot" "github.com/vulpemventures/go-elements/transaction" ) @@ -62,12 +62,15 @@ func getOnchainReceivers( func getOffchainReceivers( payments []domain.Payment, -) []domain.Receiver { - receivers := make([]domain.Receiver, 0) +) []tree.Receiver { + receivers := make([]tree.Receiver, 0) for _, payment := range payments { for _, receiver := range payment.Receivers { if !receiver.IsOnchain() { - receivers = append(receivers, receiver) + receivers = append(receivers, tree.Receiver{ + Pubkey: receiver.Pubkey, + Amount: receiver.Amount, + }) } } } @@ -133,35 +136,6 @@ func addInputs( return nil } -// wrapper of updater methods adding a taproot input to the pset with all the necessary data to spend it via any taproot script -func addTaprootInput( - updater *psetv2.Updater, - input psetv2.InputArgs, - internalTaprootKey *secp256k1.PublicKey, - taprootTree *taproot.IndexedElementsTapScriptTree, -) error { - if err := updater.AddInputs([]psetv2.InputArgs{input}); err != nil { - return err - } - - if err := updater.AddInTapInternalKey(0, schnorr.SerializePubKey(internalTaprootKey)); err != nil { - return err - } - - for _, proof := range taprootTree.LeafMerkleProofs { - controlBlock := proof.ToControlBlock(internalTaprootKey) - - if err := updater.AddInTapLeafScript(0, psetv2.TapLeafScript{ - TapElementsLeaf: taproot.NewBaseTapElementsLeaf(proof.Script), - ControlBlock: controlBlock, - }); err != nil { - return err - } - } - - return nil -} - func taprootOutputScript(taprootKey *secp256k1.PublicKey) ([]byte, error) { return txscript.NewScriptBuilder().AddOp(txscript.OP_1).AddData(schnorr.SerializePubKey(taprootKey)).Script() } diff --git a/server/internal/infrastructure/tx-builder/dummy/builder.go b/server/internal/infrastructure/tx-builder/dummy/builder.go deleted file mode 100644 index 59a98b1..0000000 --- a/server/internal/infrastructure/tx-builder/dummy/builder.go +++ /dev/null @@ -1,285 +0,0 @@ -package txbuilder - -import ( - "context" - - "github.com/ark-network/ark/common/tree" - "github.com/ark-network/ark/internal/core/domain" - "github.com/ark-network/ark/internal/core/ports" - "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/vulpemventures/go-elements/address" - "github.com/vulpemventures/go-elements/network" - "github.com/vulpemventures/go-elements/payment" - "github.com/vulpemventures/go-elements/psetv2" - "github.com/vulpemventures/go-elements/transaction" -) - -const ( - connectorAmount = 450 - sevenDays = 7 * 24 * 60 * 60 -) - -type txBuilder struct { - wallet ports.WalletService - net network.Network -} - -func NewTxBuilder( - wallet ports.WalletService, net network.Network, -) ports.TxBuilder { - return &txBuilder{wallet, net} -} - -// BuildSweepTx implements ports.TxBuilder. -func (*txBuilder) BuildSweepTx(wallet ports.WalletService, inputs []ports.SweepInput) (signedSweepTx string, err error) { - panic("unimplemented") -} - -// BuildForfeitTxs implements ports.TxBuilder. -func (b *txBuilder) BuildForfeitTxs( - aspPubkey *secp256k1.PublicKey, poolTx string, payments []domain.Payment, -) (connectors []string, forfeitTxs []string, err error) { - poolTxID, err := getTxid(poolTx) - if err != nil { - return nil, nil, err - } - - aspScript, err := p2wpkhScript(aspPubkey, b.net) - if err != nil { - return nil, nil, err - } - - numberOfConnectors := countSpentVtxos(payments) - - connectors, err = createConnectors( - poolTxID, - 1, - psetv2.OutputArgs{ - Asset: b.net.AssetID, - Amount: connectorAmount, - Script: aspScript, - }, - aspScript, - numberOfConnectors, - ) - if err != nil { - return nil, nil, err - } - - connectorsAsInputs, err := connectorsToInputArgs(connectors) - if err != nil { - return nil, nil, err - } - - forfeitTxs = make([]string, 0) - for _, payment := range payments { - for _, vtxo := range payment.Inputs { - for _, connector := range connectorsAsInputs { - forfeitTx, err := createForfeitTx( - connector, - psetv2.InputArgs{ - Txid: vtxo.Txid, - TxIndex: vtxo.VOut, - }, - vtxo.Amount, - aspScript, - b.net, - ) - if err != nil { - return nil, nil, err - } - - forfeitTxs = append(forfeitTxs, forfeitTx) - } - } - } - - return connectors, forfeitTxs, nil -} - -// BuildPoolTx implements ports.TxBuilder. -func (b *txBuilder) BuildPoolTx( - aspPubkey *secp256k1.PublicKey, payments []domain.Payment, minRelayFee uint64, -) (poolTx string, congestionTree tree.CongestionTree, err error) { - aspScriptBytes, err := p2wpkhScript(aspPubkey, b.net) - if err != nil { - return "", nil, err - } - - offchainReceivers, onchainReceivers := receiversFromPayments(payments) - sharedOutputAmount := sumReceivers(offchainReceivers) - - numberOfConnectors := countSpentVtxos(payments) - connectorOutputAmount := connectorAmount * numberOfConnectors - - ctx := context.Background() - - outputs := []psetv2.OutputArgs{ - { - Asset: b.net.AssetID, - Amount: sharedOutputAmount, - Script: aspScriptBytes, - }, - { - Asset: b.net.AssetID, - Amount: connectorOutputAmount, - Script: aspScriptBytes, - }, - } - - amountToSelect := sharedOutputAmount + connectorOutputAmount - - for _, receiver := range onchainReceivers { - amountToSelect += receiver.Amount - - receiverScript, err := address.ToOutputScript(receiver.OnchainAddress) - if err != nil { - return "", nil, err - } - - outputs = append(outputs, psetv2.OutputArgs{ - Asset: b.net.AssetID, - Amount: receiver.Amount, - Script: receiverScript, - }) - } - - utxos, change, err := b.wallet.SelectUtxos(ctx, b.net.AssetID, amountToSelect) - if err != nil { - return - } - - if change > 0 { - outputs = append(outputs, psetv2.OutputArgs{ - Asset: b.net.AssetID, - Amount: change, - Script: aspScriptBytes, - }) - } - - ptx, err := psetv2.New(toInputArgs(utxos), outputs, nil) - if err != nil { - return - } - - utx, err := ptx.UnsignedTx() - if err != nil { - return - } - - congestionTree, err = buildCongestionTree( - newOutputScriptFactory(aspPubkey, b.net), - b.net, - utx.TxHash().String(), - offchainReceivers, - ) - if err != nil { - return - } - - poolTx, err = ptx.ToBase64() - if err != nil { - return - } - - return poolTx, congestionTree, err -} - -func (b *txBuilder) GetVtxoScript(userPubkey, _ *secp256k1.PublicKey) ([]byte, error) { - p2wpkh := payment.FromPublicKey(userPubkey, &b.net, nil) - addr, _ := p2wpkh.WitnessPubKeyHash() - return address.ToOutputScript(addr) -} - -func (b *txBuilder) GetLeafSweepClosure( - node tree.Node, userPubKey *secp256k1.PublicKey, -) (*psetv2.TapLeafScript, int64, error) { - panic("unimplemented") -} - -func connectorsToInputArgs(connectors []string) ([]psetv2.InputArgs, error) { - inputs := make([]psetv2.InputArgs, 0, len(connectors)+1) - for i, psetb64 := range connectors { - tx, err := psetv2.NewPsetFromBase64(psetb64) - if err != nil { - return nil, err - } - utx, err := tx.UnsignedTx() - if err != nil { - return nil, err - } - txid := utx.TxHash().String() - for j := range tx.Outputs { - inputs = append(inputs, psetv2.InputArgs{ - Txid: txid, - TxIndex: uint32(j), - }) - if i != len(connectors)-1 { - break - } - } - } - return inputs, nil -} - -func getTxid(txStr string) (string, error) { - pset, err := psetv2.NewPsetFromBase64(txStr) - if err != nil { - tx, err := transaction.NewTxFromHex(txStr) - if err != nil { - return "", err - } - return tx.TxHash().String(), nil - } - - utx, err := pset.UnsignedTx() - if err != nil { - return "", err - } - - return utx.TxHash().String(), nil -} - -func countSpentVtxos(payments []domain.Payment) uint64 { - var sum uint64 - for _, payment := range payments { - sum += uint64(len(payment.Inputs)) - } - return sum -} - -func receiversFromPayments( - payments []domain.Payment, -) (offchainReceivers, onchainReceivers []domain.Receiver) { - for _, payment := range payments { - for _, receiver := range payment.Receivers { - if receiver.IsOnchain() { - onchainReceivers = append(onchainReceivers, receiver) - } else { - offchainReceivers = append(offchainReceivers, receiver) - } - } - } - return -} - -func sumReceivers(receivers []domain.Receiver) uint64 { - var sum uint64 - for _, r := range receivers { - sum += r.Amount - } - return sum -} - -func toInputArgs( - ins []ports.TxInput, -) []psetv2.InputArgs { - inputs := make([]psetv2.InputArgs, 0, len(ins)) - for _, in := range ins { - inputs = append(inputs, psetv2.InputArgs{ - Txid: in.GetTxid(), - TxIndex: in.GetIndex(), - }) - } - return inputs -} diff --git a/server/internal/infrastructure/tx-builder/dummy/builder_test.go b/server/internal/infrastructure/tx-builder/dummy/builder_test.go deleted file mode 100644 index 3de9074..0000000 --- a/server/internal/infrastructure/tx-builder/dummy/builder_test.go +++ /dev/null @@ -1,403 +0,0 @@ -package txbuilder_test - -import ( - "context" - "crypto/rand" - "encoding/hex" - "testing" - - "github.com/ark-network/ark/internal/core/domain" - "github.com/ark-network/ark/internal/core/ports" - txbuilder "github.com/ark-network/ark/internal/infrastructure/tx-builder/dummy" - "github.com/btcsuite/btcd/chaincfg/chainhash" - secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/stretchr/testify/require" - "github.com/vulpemventures/go-elements/network" - "github.com/vulpemventures/go-elements/psetv2" -) - -const ( - testingKey = "0218d5ca8b58797b7dbd65c075dd7ba7784b3f38ab71b1a5a8e3f94ba0257654a6" - fakePoolTx = "cHNldP8BAgQCAAAAAQQBAQEFAQMBBgEDAfsEAgAAAAABDiDk7dXxh4KQzgLO8i1ABtaLCe4aPL12GVhN1E9zM1ePLwEPBAAAAAABEAT/////AAEDCOgDAAAAAAAAAQQWABSNnpy01UJqd99eTg2M1IpdKId11gf8BHBzZXQCICWyUQcOKcoZBDzzPM1zJOLdqwPsxK4LXnfE/A5c9slaB/wEcHNldAgEAAAAAAABAwh4BQAAAAAAAAEEFgAUjZ6ctNVCanffXk4NjNSKXSiHddYH/ARwc2V0AiAlslEHDinKGQQ88zzNcyTi3asD7MSuC153xPwOXPbJWgf8BHBzZXQIBAAAAAAAAQMI9AEAAAAAAAABBAAH/ARwc2V0AiAlslEHDinKGQQ88zzNcyTi3asD7MSuC153xPwOXPbJWgf8BHBzZXQIBAAAAAAA" -) - -type input struct { - txid string - vout uint32 -} - -func (i *input) GetTxid() string { - return i.txid -} - -func (i *input) GetIndex() uint32 { - return i.vout -} - -func (i *input) GetScript() string { - return "a914ea9f486e82efb3dd83a69fd96e3f0113757da03c87" -} - -func (i *input) GetAsset() string { - return "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225" -} - -func (i *input) GetValue() uint64 { - return 1000 -} - -type mockedWalletService struct{} - -// BroadcastTransaction implements ports.WalletService. -func (*mockedWalletService) BroadcastTransaction(ctx context.Context, txHex string) (string, error) { - panic("unimplemented") -} - -// Close implements ports.WalletService. -func (*mockedWalletService) Close() { - panic("unimplemented") -} - -// DeriveAddresses implements ports.WalletService. -func (*mockedWalletService) DeriveAddresses(ctx context.Context, num int) ([]string, error) { - panic("unimplemented") -} - -// GetPubkey implements ports.WalletService. -func (*mockedWalletService) GetPubkey(ctx context.Context) (*secp256k1.PublicKey, error) { - panic("unimplemented") -} - -// SignPset implements ports.WalletService. -func (*mockedWalletService) SignPset(ctx context.Context, pset string, extractRawTx bool) (string, error) { - panic("unimplemented") -} - -// Status implements ports.WalletService. -func (*mockedWalletService) Status(ctx context.Context) (ports.WalletStatus, error) { - panic("unimplemented") -} - -func (*mockedWalletService) WatchScripts(ctx context.Context, scripts []string) error { - panic("unimplemented") -} - -func (*mockedWalletService) UnwatchScripts(ctx context.Context, scripts []string) error { - panic("unimplemented") -} - -func (*mockedWalletService) GetNotificationChannel(ctx context.Context) chan []domain.VtxoKey { - panic("unimplemented") -} - -func (*mockedWalletService) SelectUtxos(ctx context.Context, asset string, amount uint64) ([]ports.TxInput, uint64, error) { - // random txid - bytes := make([]byte, 32) - if _, err := rand.Read(bytes); err != nil { - return nil, 0, err - } - fakeInput := input{ - txid: hex.EncodeToString(bytes), - vout: 0, - } - - return []ports.TxInput{&fakeInput}, 0, nil -} - -func (*mockedWalletService) EstimateFees(ctx context.Context, pset string) (uint64, error) { - return 100, nil -} - -func (*mockedWalletService) SignPsetWithKey(ctx context.Context, pset string, inputIndex []int) (string, error) { - panic("unimplemented") -} - -func (*mockedWalletService) IsTransactionPublished(ctx context.Context, txid string) (bool, int64, error) { - panic("unimplemented") -} - -func TestBuildCongestionTree(t *testing.T) { - builder := txbuilder.NewTxBuilder(&mockedWalletService{}, network.Liquid) - - fixtures := []struct { - payments []domain.Payment - expectedNodesNum int // 2*len(receivers)-1 - expectedLeavesNum int - }{ - { - payments: []domain.Payment{ - { - Id: "0", - Inputs: []domain.Vtxo{ - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 0, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - }, - }, - Receivers: []domain.Receiver{ - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - }, - expectedNodesNum: 3, - expectedLeavesNum: 2, - }, - { - payments: []domain.Payment{ - { - Id: "0", - Inputs: []domain.Vtxo{ - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 0, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - }, - }, - Receivers: []domain.Receiver{ - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - { - Id: "0", - Inputs: []domain.Vtxo{ - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 0, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - }, - }, - Receivers: []domain.Receiver{ - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - { - Id: "0", - Inputs: []domain.Vtxo{ - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 0, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - }, - }, - Receivers: []domain.Receiver{ - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - }, - expectedNodesNum: 11, - expectedLeavesNum: 6, - }, - } - pubkeyBytes, _ := hex.DecodeString(testingKey) - pubkey, _ := secp256k1.ParsePubKey(pubkeyBytes) - - for _, f := range fixtures { - poolTx, tree, err := builder.BuildPoolTx(pubkey, f.payments, 30) - - require.NoError(t, err) - require.Equal(t, f.expectedNodesNum, tree.NumberOfNodes()) - require.Len(t, tree.Leaves(), f.expectedLeavesNum) - - poolPset, err := psetv2.NewPsetFromBase64(poolTx) - require.NoError(t, err) - - poolTxUnsigned, err := poolPset.UnsignedTx() - require.NoError(t, err) - - poolTxID := poolTxUnsigned.TxHash().String() - - // check the root - require.Len(t, tree[0], 1) - require.Equal(t, poolTxID, tree[0][0].ParentTxid) - - // check the leaves - for _, leaf := range tree.Leaves() { - pset, err := psetv2.NewPsetFromBase64(leaf.Tx) - require.NoError(t, err) - - require.Len(t, pset.Inputs, 1) - require.Len(t, pset.Outputs, 1) - - inputTxID := chainhash.Hash(pset.Inputs[0].PreviousTxid).String() - require.Equal(t, leaf.ParentTxid, inputTxID) - } - - // check the nodes - for _, level := range tree[:len(tree)-2] { - for _, node := range level { - pset, err := psetv2.NewPsetFromBase64(node.Tx) - require.NoError(t, err) - - require.Len(t, pset.Inputs, 1) - require.Len(t, pset.Outputs, 2) - - inputTxID := chainhash.Hash(pset.Inputs[0].PreviousTxid).String() - require.Equal(t, node.ParentTxid, inputTxID) - - children := tree.Children(node.Txid) - require.Len(t, children, 2) - } - } - } -} - -func TestBuildForfeitTxs(t *testing.T) { - builder := txbuilder.NewTxBuilder(&mockedWalletService{}, network.Liquid) - - poolPset, err := psetv2.NewPsetFromBase64(fakePoolTx) - require.NoError(t, err) - - poolTxUnsigned, err := poolPset.UnsignedTx() - require.NoError(t, err) - - poolTxID := poolTxUnsigned.TxHash().String() - - fixtures := []struct { - payments []domain.Payment - expectedNumOfForfeitTxs int - expectedNumOfConnectors int - }{ - { - payments: []domain.Payment{ - { - Id: "0", - Inputs: []domain.Vtxo{ - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 0, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - }, - { - VtxoKey: domain.VtxoKey{ - Txid: "fd68e3c5796cc7db0a8036d486d5f625b6b2f2c014810ac020e1ac23e82c59d6", - VOut: 1, - }, - Receiver: domain.Receiver{ - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - Receivers: []domain.Receiver{ - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 600, - }, - { - Pubkey: "020000000000000000000000000000000000000000000000000000000000000002", - Amount: 400, - }, - }, - }, - }, - expectedNumOfForfeitTxs: 4, - expectedNumOfConnectors: 1, - }, - } - - pubkeyBytes, _ := hex.DecodeString(testingKey) - pubkey, _ := secp256k1.ParsePubKey(pubkeyBytes) - - for _, f := range fixtures { - connectors, forfeitTxs, err := builder.BuildForfeitTxs( - pubkey, fakePoolTx, f.payments, - ) - require.NoError(t, err) - require.Len(t, connectors, f.expectedNumOfConnectors) - require.Len(t, forfeitTxs, f.expectedNumOfForfeitTxs) - - // decode and check connectors - connectorsPsets := make([]*psetv2.Pset, 0, f.expectedNumOfConnectors) - for _, pset := range connectors { - p, err := psetv2.NewPsetFromBase64(pset) - require.NoError(t, err) - connectorsPsets = append(connectorsPsets, p) - } - - for i, pset := range connectorsPsets { - require.Len(t, pset.Inputs, 1) - require.Len(t, pset.Outputs, 2) - - expectedInputTxid := poolTxID - expectedInputVout := uint32(1) - if i > 0 { - tx, err := connectorsPsets[i-1].UnsignedTx() - require.NoError(t, err) - require.NotNil(t, tx) - expectedInputTxid = tx.TxHash().String() - } - - inputTxid := chainhash.Hash(pset.Inputs[0].PreviousTxid).String() - require.Equal(t, expectedInputTxid, inputTxid) - require.Equal(t, expectedInputVout, pset.Inputs[0].PreviousTxIndex) - } - - // decode and check forfeit txs - forfeitTxsPsets := make([]*psetv2.Pset, 0, f.expectedNumOfForfeitTxs) - for _, pset := range forfeitTxs { - p, err := psetv2.NewPsetFromBase64(pset) - require.NoError(t, err) - forfeitTxsPsets = append(forfeitTxsPsets, p) - } - - // each forfeit tx should have 2 inputs and 2 outputs - for _, pset := range forfeitTxsPsets { - require.Len(t, pset.Inputs, 2) - require.Len(t, pset.Outputs, 1) - } - } -} diff --git a/server/internal/infrastructure/tx-builder/dummy/connectors.go b/server/internal/infrastructure/tx-builder/dummy/connectors.go deleted file mode 100644 index 8008295..0000000 --- a/server/internal/infrastructure/tx-builder/dummy/connectors.go +++ /dev/null @@ -1,103 +0,0 @@ -package txbuilder - -import ( - "github.com/vulpemventures/go-elements/psetv2" -) - -func createConnectors( - poolTxID string, - connectorOutputIndex uint32, - connectorOutput psetv2.OutputArgs, - changeScript []byte, - numberOfConnectors uint64, -) (connectorsPsets []string, err error) { - previousInput := psetv2.InputArgs{ - Txid: poolTxID, - TxIndex: connectorOutputIndex, - } - - if numberOfConnectors == 1 { - pset, err := psetv2.New(nil, nil, nil) - if err != nil { - return nil, err - } - updater, err := psetv2.NewUpdater(pset) - if err != nil { - return nil, err - } - - err = updater.AddInputs([]psetv2.InputArgs{previousInput}) - if err != nil { - return nil, err - } - - err = updater.AddOutputs([]psetv2.OutputArgs{connectorOutput}) - if err != nil { - return nil, err - } - - base64, err := pset.ToBase64() - if err != nil { - return nil, err - } - - return []string{base64}, nil - } - - // compute the initial amount of the connectors output in pool transaction - remainingAmount := connectorAmount * numberOfConnectors - - connectorsPset := make([]string, 0, numberOfConnectors-1) - for i := uint64(0); i < numberOfConnectors-1; i++ { - // create a new pset - pset, err := psetv2.New(nil, nil, nil) - if err != nil { - return nil, err - } - - updater, err := psetv2.NewUpdater(pset) - if err != nil { - return nil, err - } - - err = updater.AddInputs([]psetv2.InputArgs{previousInput}) - if err != nil { - return nil, err - } - - err = updater.AddOutputs([]psetv2.OutputArgs{connectorOutput}) - if err != nil { - return nil, err - } - - changeAmount := remainingAmount - connectorOutput.Amount - if changeAmount > 0 { - changeOutput := psetv2.OutputArgs{ - Asset: connectorOutput.Asset, - Amount: changeAmount, - Script: changeScript, - } - err = updater.AddOutputs([]psetv2.OutputArgs{changeOutput}) - if err != nil { - return nil, err - } - tx, _ := pset.UnsignedTx() - txid := tx.TxHash().String() - - // make the change the next previousInput - previousInput = psetv2.InputArgs{ - Txid: txid, - TxIndex: 1, - } - } - - base64, err := pset.ToBase64() - if err != nil { - return nil, err - } - - connectorsPset = append(connectorsPset, base64) - } - - return connectorsPset, nil -} diff --git a/server/internal/infrastructure/tx-builder/dummy/forfeit.go b/server/internal/infrastructure/tx-builder/dummy/forfeit.go deleted file mode 100644 index ff15c68..0000000 --- a/server/internal/infrastructure/tx-builder/dummy/forfeit.go +++ /dev/null @@ -1,42 +0,0 @@ -package txbuilder - -import ( - "github.com/vulpemventures/go-elements/network" - "github.com/vulpemventures/go-elements/psetv2" -) - -func createForfeitTx( - connectorInput psetv2.InputArgs, - vtxoInput psetv2.InputArgs, - vtxoAmount uint64, - aspScript []byte, - net network.Network, -) (forfeitTx string, err error) { - pset, err := psetv2.New(nil, nil, nil) - if err != nil { - return "", err - } - - updater, err := psetv2.NewUpdater(pset) - if err != nil { - return "", err - } - - err = updater.AddInputs([]psetv2.InputArgs{connectorInput, vtxoInput}) - if err != nil { - return "", err - } - - err = updater.AddOutputs([]psetv2.OutputArgs{ - { - Asset: net.AssetID, - Amount: vtxoAmount, - Script: aspScript, - }, - }) - if err != nil { - return "", err - } - - return pset.ToBase64() -} diff --git a/server/internal/infrastructure/tx-builder/dummy/tree.go b/server/internal/infrastructure/tx-builder/dummy/tree.go deleted file mode 100644 index e1a1940..0000000 --- a/server/internal/infrastructure/tx-builder/dummy/tree.go +++ /dev/null @@ -1,309 +0,0 @@ -package txbuilder - -import ( - "encoding/hex" - - "github.com/ark-network/ark/common/tree" - "github.com/ark-network/ark/internal/core/domain" - "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/vulpemventures/go-elements/address" - "github.com/vulpemventures/go-elements/network" - "github.com/vulpemventures/go-elements/payment" - "github.com/vulpemventures/go-elements/psetv2" -) - -const ( - sharedOutputIndex = 0 -) - -type outputScriptFactory func(leaves []domain.Receiver) ([]byte, error) - -func p2wpkhScript(publicKey *secp256k1.PublicKey, net network.Network) ([]byte, error) { - payment := payment.FromPublicKey(publicKey, &net, nil) - addr, err := payment.WitnessPubKeyHash() - if err != nil { - return nil, err - } - - return address.ToOutputScript(addr) -} - -// newOtputScriptFactory returns an output script factory func that lock funds using the ASP public key only on all branches psbt. The leaves are instead locked by the leaf public key. -func newOutputScriptFactory(aspPublicKey *secp256k1.PublicKey, net network.Network) outputScriptFactory { - return func(leaves []domain.Receiver) ([]byte, error) { - aspScript, err := p2wpkhScript(aspPublicKey, net) - if err != nil { - return nil, err - } - - switch len(leaves) { - case 0: - return nil, nil - case 1: // it's a leaf - buf, err := hex.DecodeString(leaves[0].Pubkey) - if err != nil { - return nil, err - } - key, err := secp256k1.ParsePubKey(buf) - if err != nil { - return nil, err - } - - return p2wpkhScript(key, net) - default: // it's a branch, lock funds with ASP public key - return aspScript, nil - } - } -} - -// congestionTree builder iteratively creates a binary tree of Pset from a set of receivers -// it also expect createOutputScript func managing the output script creation and the network to use (mainly for L-BTC asset id) -func buildCongestionTree( - createOutputScript outputScriptFactory, - net network.Network, - poolTxID string, - receivers []domain.Receiver, -) (congestionTree tree.CongestionTree, err error) { - var nodes []*node - - for _, r := range receivers { - nodes = append(nodes, newLeaf(createOutputScript, net, r)) - } - - for len(nodes) > 1 { - nodes, err = createTreeLevel(nodes) - if err != nil { - return nil, err - } - } - - psets, err := nodes[0].psets(psetv2.InputArgs{ - Txid: poolTxID, - TxIndex: sharedOutputIndex, - }, 0) - if err != nil { - return nil, err - } - - maxLevel := 0 - for _, psetWithLevel := range psets { - if psetWithLevel.level > maxLevel { - maxLevel = psetWithLevel.level - } - } - - congestionTree = make(tree.CongestionTree, maxLevel+1) - - for _, psetWithLevel := range psets { - utx, err := psetWithLevel.pset.UnsignedTx() - if err != nil { - return nil, err - } - - txid := utx.TxHash().String() - - psetB64, err := psetWithLevel.pset.ToBase64() - if err != nil { - return nil, err - } - - parentTxid := chainhash.Hash(psetWithLevel.pset.Inputs[0].PreviousTxid).String() - - congestionTree[psetWithLevel.level] = append(congestionTree[psetWithLevel.level], tree.Node{ - Txid: txid, - Tx: psetB64, - ParentTxid: parentTxid, - Leaf: psetWithLevel.leaf, - }) - } - - return congestionTree, nil -} - -func createTreeLevel(nodes []*node) ([]*node, error) { - if len(nodes)%2 != 0 { - last := nodes[len(nodes)-1] - pairs, err := createTreeLevel(nodes[:len(nodes)-1]) - if err != nil { - return nil, err - } - - return append(pairs, last), nil - } - - pairs := make([]*node, 0, len(nodes)/2) - for i := 0; i < len(nodes); i += 2 { - pairs = append(pairs, newBranch(nodes[i], nodes[i+1])) - } - return pairs, nil -} - -// internal struct to build a binary tree of Pset -type node struct { - receivers []domain.Receiver - left *node - right *node - createOutputScript outputScriptFactory - network network.Network -} - -// create a node from a single receiver -func newLeaf( - createOutputScript outputScriptFactory, - network network.Network, - receiver domain.Receiver, -) *node { - return &node{ - receivers: []domain.Receiver{receiver}, - createOutputScript: createOutputScript, - network: network, - left: nil, - right: nil, - } -} - -// aggregate two nodes into a branch node -func newBranch( - left *node, - right *node, -) *node { - return &node{ - receivers: append(left.receivers, right.receivers...), - createOutputScript: left.createOutputScript, - network: left.network, - left: left, - right: right, - } -} - -// is it the final node of the tree -func (n *node) isLeaf() bool { - return n.left == nil && n.right == nil -} - -// compute the output amount of a node -func (n *node) amount() uint64 { - var amount uint64 - for _, r := range n.receivers { - amount += r.Amount - } - return amount -} - -// compute the output script of a node -func (n *node) script() ([]byte, error) { - return n.createOutputScript(n.receivers) -} - -// use script & amount to create OutputArgs -func (n *node) output() (*psetv2.OutputArgs, error) { - script, err := n.script() - if err != nil { - return nil, err - } - - return &psetv2.OutputArgs{ - Asset: n.network.AssetID, - Amount: n.amount(), - Script: script, - }, nil -} - -// create the node Pset from the previous node Pset represented by input arg -// if node is a branch, it adds two outputs to the Pset, one for the left branch and one for the right branch -// if node is a leaf, it only adds one output to the Pset (the node output) -func (n *node) pset(input psetv2.InputArgs) (*psetv2.Pset, error) { - pset, err := psetv2.New(nil, nil, nil) - if err != nil { - return nil, err - } - - updater, err := psetv2.NewUpdater(pset) - if err != nil { - return nil, err - } - - err = updater.AddInputs([]psetv2.InputArgs{input}) - if err != nil { - return nil, err - } - - if n.isLeaf() { - output, err := n.output() - if err != nil { - return nil, err - } - - err = updater.AddOutputs([]psetv2.OutputArgs{*output}) - if err != nil { - return nil, err - } - return pset, nil - } - - outputLeft, err := n.left.output() - if err != nil { - return nil, err - } - - outputRight, err := n.right.output() - if err != nil { - return nil, err - } - - err = updater.AddOutputs([]psetv2.OutputArgs{*outputLeft, *outputRight}) - if err != nil { - return nil, err - } - - return pset, nil -} - -type psetWithLevel struct { - pset *psetv2.Pset - level int - leaf bool -} - -// create the node pset and all the psets of its children recursively, updating the input arg at each step -// the function stops when it reaches a leaf node -func (n *node) psets(input psetv2.InputArgs, level int) ([]psetWithLevel, error) { - pset, err := n.pset(input) - if err != nil { - return nil, err - } - - nodeResult := []psetWithLevel{ - {pset, level, n.isLeaf()}, - } - - if n.isLeaf() { - return nodeResult, nil - } - - unsignedTx, err := pset.UnsignedTx() - if err != nil { - return nil, err - } - - txID := unsignedTx.TxHash().String() - - psetsLeft, err := n.left.psets(psetv2.InputArgs{ - Txid: txID, - TxIndex: 0, - }, level+1) - if err != nil { - return nil, err - } - - psetsRight, err := n.right.psets(psetv2.InputArgs{ - Txid: txID, - TxIndex: 1, - }, level+1) - if err != nil { - return nil, err - } - - return append(nodeResult, append(psetsLeft, psetsRight...)...), nil -} diff --git a/server/internal/interface/grpc/handlers/arkservice.go b/server/internal/interface/grpc/handlers/arkservice.go index 2267eed..dbe1466 100644 --- a/server/internal/interface/grpc/handlers/arkservice.go +++ b/server/internal/interface/grpc/handlers/arkservice.go @@ -40,6 +40,37 @@ func NewHandler(service application.Service) arkv1.ArkServiceServer { return h } +func (h *handler) Onboard(ctx context.Context, req *arkv1.OnboardRequest) (*arkv1.OnboardResponse, error) { + if req.GetUserPubkey() == "" { + return nil, status.Error(codes.InvalidArgument, "missing user pubkey") + } + + pubKey, err := hex.DecodeString(req.GetUserPubkey()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid user pubkey") + } + + decodedPubKey, err := secp256k1.ParsePubKey(pubKey) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid user pubkey") + } + + if req.GetBoardingTx() == "" { + return nil, status.Error(codes.InvalidArgument, "missing boarding tx id") + } + + tree, err := toCongestionTree(req.GetCongestionTree()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + if err := h.svc.Onboard(ctx, req.GetBoardingTx(), tree, decodedPubKey); err != nil { + return nil, err + } + + return &arkv1.OnboardResponse{}, nil +} + func (h *handler) Ping(ctx context.Context, req *arkv1.PingRequest) (*arkv1.PingResponse, error) { if req.GetPaymentId() == "" { return nil, status.Error(codes.InvalidArgument, "missing payment id") @@ -96,19 +127,6 @@ func (h *handler) FinalizePayment(ctx context.Context, req *arkv1.FinalizePaymen return &arkv1.FinalizePaymentResponse{}, nil } -func (h *handler) Faucet(ctx context.Context, req *arkv1.FaucetRequest) (*arkv1.FaucetResponse, error) { - _, pubkey, _, err := parseAddress(req.GetAddress()) - if err != nil { - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if err := h.svc.FaucetVtxos(ctx, pubkey); err != nil { - return nil, err - } - - return &arkv1.FaucetResponse{}, nil -} - func (h *handler) GetRound(ctx context.Context, req *arkv1.GetRoundRequest) (*arkv1.GetRoundResponse, error) { if len(req.GetTxid()) <= 0 { return nil, status.Error(codes.InvalidArgument, "missing pool txid") @@ -305,3 +323,32 @@ func castCongestionTree(congestionTree tree.CongestionTree) *arkv1.Tree { Levels: levels, } } + +func toCongestionTree(treeFromProto *arkv1.Tree) (tree.CongestionTree, error) { + levels := make(tree.CongestionTree, 0, len(treeFromProto.Levels)) + + for _, level := range treeFromProto.Levels { + nodes := make([]tree.Node, 0, len(level.Nodes)) + + for _, node := range level.Nodes { + nodes = append(nodes, tree.Node{ + Txid: node.Txid, + Tx: node.Tx, + ParentTxid: node.ParentTxid, + Leaf: false, + }) + } + + levels = append(levels, nodes) + } + + for j, treeLvl := range levels { + for i, node := range treeLvl { + if len(levels.Children(node.Txid)) == 0 { + levels[j][i].Leaf = true + } + } + } + + return levels, nil +}