Adds a "sweep" command to kaspawallet (#2018)

* Add "sweep" command to kaspawallet

* minor linting & layout improvements.

* contain code in "sweep"

* update to sweep.go

* formatting and bugs

* clean up renaming of ExtractTransaction functions

* Nicer formating of display

* address reveiw.

* one more sweeped -> swept

* missed one reveiw comment. (extra mass).

* remove redundant code from split function.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
D-Stacks 2022-04-14 01:16:16 +02:00 committed by GitHub
parent 723aebbec9
commit 57c6118be8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1190 additions and 198 deletions

View File

@ -3,19 +3,12 @@ package main
import (
"context"
"fmt"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
)
func formatKas(amount uint64) string {
res := " "
if amount > 0 {
res = fmt.Sprintf("%19.8f", float64(amount)/constants.SompiPerKaspa)
}
return res
}
func balance(conf *balanceConfig) error {
daemonClient, tearDown, err := client.Connect(conf.DaemonAddress)
if err != nil {
@ -39,12 +32,12 @@ func balance(conf *balanceConfig) error {
println("Address Available Pending")
println("-----------------------------------------------------------------------------------------------------------")
for _, addressBalance := range response.AddressBalances {
fmt.Printf("%s %s %s\n", addressBalance.Address, formatKas(addressBalance.Available), formatKas(addressBalance.Pending))
fmt.Printf("%s %s %s\n", addressBalance.Address, utils.FormatKas(addressBalance.Available), utils.FormatKas(addressBalance.Pending))
}
println("-----------------------------------------------------------------------------------------------------------")
print(" ")
}
fmt.Printf("Total balance, KAS %s %s%s\n", formatKas(response.Available), formatKas(response.Pending), pendingSuffix)
fmt.Printf("Total balance, KAS %s %s%s\n", utils.FormatKas(response.Available), utils.FormatKas(response.Pending), pendingSuffix)
return nil
}

View File

@ -13,6 +13,7 @@ const (
createSubCmd = "create"
balanceSubCmd = "balance"
sendSubCmd = "send"
sweepSubCmd = "sweep"
createUnsignedTransactionSubCmd = "create-unsigned-transaction"
signSubCmd = "sign"
broadcastSubCmd = "broadcast"
@ -59,6 +60,12 @@ type sendConfig struct {
config.NetworkFlags
}
type sweepConfig struct {
PrivateKey string `long:"private-key" short:"k" description:"Private key in hex format"`
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
config.NetworkFlags
}
type createUnsignedTransactionConfig struct {
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
ToAddress string `long:"to-address" short:"t" description:"The public address to send Kaspa to" required:"true"`
@ -130,6 +137,10 @@ func parseCommandLine() (subCommand string, config interface{}) {
parser.AddCommand(sendSubCmd, "Sends a Kaspa transaction to a public address",
"Sends a Kaspa transaction to a public address", sendConf)
sweepConf := &sweepConfig{DaemonAddress: defaultListen}
parser.AddCommand(sweepSubCmd, "Sends all funds associated with the given private key, to a new address of the wallet",
"Sends all funds associated with the private key, to a given change address of the wallet", sweepConf)
createUnsignedTransactionConf := &createUnsignedTransactionConfig{DaemonAddress: defaultListen}
parser.AddCommand(createUnsignedTransactionSubCmd, "Create an unsigned Kaspa transaction",
"Create an unsigned Kaspa transaction", createUnsignedTransactionConf)
@ -199,6 +210,13 @@ func parseCommandLine() (subCommand string, config interface{}) {
printErrorAndExit(err)
}
config = sendConf
case sweepSubCmd:
combineNetworkFlags(&sweepConf.NetworkFlags, &cfg.NetworkFlags)
err := sweepConf.ResolveNetwork(parser)
if err != nil {
printErrorAndExit(err)
}
config = sweepConf
case createUnsignedTransactionSubCmd:
combineNetworkFlags(&createUnsignedTransactionConf.NetworkFlags, &cfg.NetworkFlags)
err := createUnsignedTransactionConf.ResolveNetwork(parser)

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.19.4
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: kaspawalletd.proto
package pb
@ -461,7 +461,8 @@ type BroadcastRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"`
IsDomain bool `protobuf:"varint,1,opt,name=isDomain,proto3" json:"isDomain,omitempty"`
Transactions [][]byte `protobuf:"bytes,2,rep,name=transactions,proto3" json:"transactions,omitempty"`
}
func (x *BroadcastRequest) Reset() {
@ -496,6 +497,13 @@ func (*BroadcastRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{9}
}
func (x *BroadcastRequest) GetIsDomain() bool {
if x != nil {
return x.IsDomain
}
return false
}
func (x *BroadcastRequest) GetTransactions() [][]byte {
if x != nil {
return x.Transactions
@ -626,6 +634,345 @@ func (*ShutdownResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{12}
}
type Outpoint struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TransactionId string `protobuf:"bytes,1,opt,name=transactionId,proto3" json:"transactionId,omitempty"`
Index uint32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"`
}
func (x *Outpoint) Reset() {
*x = Outpoint{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Outpoint) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Outpoint) ProtoMessage() {}
func (x *Outpoint) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[13]
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 Outpoint.ProtoReflect.Descriptor instead.
func (*Outpoint) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{13}
}
func (x *Outpoint) GetTransactionId() string {
if x != nil {
return x.TransactionId
}
return ""
}
func (x *Outpoint) GetIndex() uint32 {
if x != nil {
return x.Index
}
return 0
}
type UtxosByAddressesEntry struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Outpoint *Outpoint `protobuf:"bytes,2,opt,name=outpoint,proto3" json:"outpoint,omitempty"`
UtxoEntry *UtxoEntry `protobuf:"bytes,3,opt,name=utxoEntry,proto3" json:"utxoEntry,omitempty"`
}
func (x *UtxosByAddressesEntry) Reset() {
*x = UtxosByAddressesEntry{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UtxosByAddressesEntry) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UtxosByAddressesEntry) ProtoMessage() {}
func (x *UtxosByAddressesEntry) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[14]
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 UtxosByAddressesEntry.ProtoReflect.Descriptor instead.
func (*UtxosByAddressesEntry) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{14}
}
func (x *UtxosByAddressesEntry) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *UtxosByAddressesEntry) GetOutpoint() *Outpoint {
if x != nil {
return x.Outpoint
}
return nil
}
func (x *UtxosByAddressesEntry) GetUtxoEntry() *UtxoEntry {
if x != nil {
return x.UtxoEntry
}
return nil
}
type ScriptPublicKey struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
ScriptPublicKey string `protobuf:"bytes,2,opt,name=scriptPublicKey,proto3" json:"scriptPublicKey,omitempty"`
}
func (x *ScriptPublicKey) Reset() {
*x = ScriptPublicKey{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ScriptPublicKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ScriptPublicKey) ProtoMessage() {}
func (x *ScriptPublicKey) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[15]
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 ScriptPublicKey.ProtoReflect.Descriptor instead.
func (*ScriptPublicKey) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{15}
}
func (x *ScriptPublicKey) GetVersion() uint32 {
if x != nil {
return x.Version
}
return 0
}
func (x *ScriptPublicKey) GetScriptPublicKey() string {
if x != nil {
return x.ScriptPublicKey
}
return ""
}
type UtxoEntry struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
ScriptPublicKey *ScriptPublicKey `protobuf:"bytes,2,opt,name=scriptPublicKey,proto3" json:"scriptPublicKey,omitempty"`
BlockDaaScore uint64 `protobuf:"varint,3,opt,name=blockDaaScore,proto3" json:"blockDaaScore,omitempty"`
IsCoinbase bool `protobuf:"varint,4,opt,name=isCoinbase,proto3" json:"isCoinbase,omitempty"`
}
func (x *UtxoEntry) Reset() {
*x = UtxoEntry{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UtxoEntry) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UtxoEntry) ProtoMessage() {}
func (x *UtxoEntry) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[16]
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 UtxoEntry.ProtoReflect.Descriptor instead.
func (*UtxoEntry) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{16}
}
func (x *UtxoEntry) GetAmount() uint64 {
if x != nil {
return x.Amount
}
return 0
}
func (x *UtxoEntry) GetScriptPublicKey() *ScriptPublicKey {
if x != nil {
return x.ScriptPublicKey
}
return nil
}
func (x *UtxoEntry) GetBlockDaaScore() uint64 {
if x != nil {
return x.BlockDaaScore
}
return 0
}
func (x *UtxoEntry) GetIsCoinbase() bool {
if x != nil {
return x.IsCoinbase
}
return false
}
type GetExternalSpendableUTXOsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
}
func (x *GetExternalSpendableUTXOsRequest) Reset() {
*x = GetExternalSpendableUTXOsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetExternalSpendableUTXOsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetExternalSpendableUTXOsRequest) ProtoMessage() {}
func (x *GetExternalSpendableUTXOsRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[17]
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 GetExternalSpendableUTXOsRequest.ProtoReflect.Descriptor instead.
func (*GetExternalSpendableUTXOsRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{17}
}
func (x *GetExternalSpendableUTXOsRequest) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
type GetExternalSpendableUTXOsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Entries []*UtxosByAddressesEntry `protobuf:"bytes,1,rep,name=Entries,proto3" json:"Entries,omitempty"`
}
func (x *GetExternalSpendableUTXOsResponse) Reset() {
*x = GetExternalSpendableUTXOsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetExternalSpendableUTXOsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetExternalSpendableUTXOsResponse) ProtoMessage() {}
func (x *GetExternalSpendableUTXOsResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[18]
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 GetExternalSpendableUTXOsResponse.ProtoReflect.Descriptor instead.
func (*GetExternalSpendableUTXOsResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{18}
}
func (x *GetExternalSpendableUTXOsResponse) GetEntries() []*UtxosByAddressesEntry {
if x != nil {
return x.Entries
}
return nil
}
// Since SendRequest contains a password - this command should only be used on a trusted or secure connection
type SendRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -639,7 +986,7 @@ type SendRequest struct {
func (x *SendRequest) Reset() {
*x = SendRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[13]
mi := &file_kaspawalletd_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -652,7 +999,7 @@ func (x *SendRequest) String() string {
func (*SendRequest) ProtoMessage() {}
func (x *SendRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[13]
mi := &file_kaspawalletd_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -665,7 +1012,7 @@ func (x *SendRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SendRequest.ProtoReflect.Descriptor instead.
func (*SendRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{13}
return file_kaspawalletd_proto_rawDescGZIP(), []int{19}
}
func (x *SendRequest) GetToAddress() string {
@ -700,7 +1047,7 @@ type SendResponse struct {
func (x *SendResponse) Reset() {
*x = SendResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[14]
mi := &file_kaspawalletd_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -713,7 +1060,7 @@ func (x *SendResponse) String() string {
func (*SendResponse) ProtoMessage() {}
func (x *SendResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[14]
mi := &file_kaspawalletd_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -726,7 +1073,7 @@ func (x *SendResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SendResponse.ProtoReflect.Descriptor instead.
func (*SendResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{14}
return file_kaspawalletd_proto_rawDescGZIP(), []int{20}
}
func (x *SendResponse) GetTxIDs() []string {
@ -736,6 +1083,7 @@ func (x *SendResponse) GetTxIDs() []string {
return nil
}
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
type SignRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -748,7 +1096,7 @@ type SignRequest struct {
func (x *SignRequest) Reset() {
*x = SignRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[15]
mi := &file_kaspawalletd_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -761,7 +1109,7 @@ func (x *SignRequest) String() string {
func (*SignRequest) ProtoMessage() {}
func (x *SignRequest) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[15]
mi := &file_kaspawalletd_proto_msgTypes[21]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -774,7 +1122,7 @@ func (x *SignRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SignRequest.ProtoReflect.Descriptor instead.
func (*SignRequest) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{15}
return file_kaspawalletd_proto_rawDescGZIP(), []int{21}
}
func (x *SignRequest) GetUnsignedTransactions() [][]byte {
@ -802,7 +1150,7 @@ type SignResponse struct {
func (x *SignResponse) Reset() {
*x = SignResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_kaspawalletd_proto_msgTypes[16]
mi := &file_kaspawalletd_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -815,7 +1163,7 @@ func (x *SignResponse) String() string {
func (*SignResponse) ProtoMessage() {}
func (x *SignResponse) ProtoReflect() protoreflect.Message {
mi := &file_kaspawalletd_proto_msgTypes[16]
mi := &file_kaspawalletd_proto_msgTypes[22]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -828,7 +1176,7 @@ func (x *SignResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SignResponse.ProtoReflect.Descriptor instead.
func (*SignResponse) Descriptor() ([]byte, []int) {
return file_kaspawalletd_proto_rawDescGZIP(), []int{16}
return file_kaspawalletd_proto_rawDescGZIP(), []int{22}
}
func (x *SignResponse) GetSignedTransactions() [][]byte {
@ -880,81 +1228,132 @@ var file_kaspawalletd_proto_rawDesc = []byte{
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x36, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61,
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x29, 0x0a,
0x11, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x09, 0x52, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74,
0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53,
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x5f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c,
0x0a, 0x09, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x74, 0x6f, 0x41, 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, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x22, 0x24, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x22, 0x5d, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65,
0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0c, 0x52, 0x14, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61,
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3e, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0c, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0xb3, 0x05, 0x0a, 0x0c, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c,
0x61, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61,
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x29, 0x0a, 0x11, 0x42, 0x72, 0x6f,
0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14,
0x0a, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x74,
0x78, 0x49, 0x44, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64,
0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x08, 0x4f,
0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a,
0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x22, 0x9c, 0x01, 0x0a, 0x15, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x42, 0x79, 0x41,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 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, 0x32, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f,
0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6b, 0x61, 0x73, 0x70,
0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e,
0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x09, 0x75,
0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x55, 0x74,
0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x22, 0x55, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x28, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0xb2, 0x01, 0x0a, 0x09, 0x55, 0x74,
0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x47, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x44, 0x61, 0x61, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x44, 0x61, 0x61, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1e,
0x0a, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01,
0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x22, 0x3c,
0x0a, 0x20, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65,
0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 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, 0x62, 0x0a, 0x21,
0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64,
0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3d, 0x0a, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x64, 0x2e, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73,
0x22, 0x5f, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x41, 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, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
0x64, 0x22, 0x24, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
0x52, 0x05, 0x74, 0x78, 0x49, 0x44, 0x73, 0x22, 0x5d, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e,
0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0c, 0x52, 0x14, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3e, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64,
0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0c, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0xb3, 0x06, 0x0a, 0x0c, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61,
0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x81, 0x01, 0x0a, 0x1a, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e,
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e,
0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6b, 0x61, 0x73, 0x70,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7e, 0x0a, 0x19, 0x47, 0x65,
0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62,
0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73, 0x12, 0x2e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x54, 0x58, 0x4f, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x81, 0x01, 0x0a, 0x1a, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61,
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x2e, 0x6b, 0x61, 0x73, 0x70,
0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55,
0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a,
0x0d, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x22,
0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68,
0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x64, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0a, 0x4e, 0x65, 0x77,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6b, 0x61, 0x73,
0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a,
0x0a, 0x0d, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12,
0x22, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53,
0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x64, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0a, 0x4e, 0x65,
0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x08,
0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1d, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x61, 0x73, 0x70,
0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a,
0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1d, 0x2e, 0x6b, 0x61, 0x73, 0x70,
0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x09, 0x42, 0x72, 0x6f,
0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61,
0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53, 0x65, 0x6e,
0x64, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64,
0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6b,
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x65, 0x6e, 0x64,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53, 0x69,
0x67, 0x6e, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x64, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x69, 0x67,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e,
0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x6b, 0x61,
0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e,
0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x09, 0x42, 0x72,
0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77,
0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53, 0x65,
0x6e, 0x64, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x64, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x65, 0x6e,
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x04, 0x53,
0x69, 0x67, 0x6e, 0x12, 0x19, 0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x64, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
0x2e, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x2e, 0x53, 0x69,
0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61,
0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x6b,
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x64, 0x61, 0x65, 0x6d, 0x6f,
0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -969,7 +1368,7 @@ func file_kaspawalletd_proto_rawDescGZIP() []byte {
return file_kaspawalletd_proto_rawDescData
}
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
var file_kaspawalletd_proto_goTypes = []interface{}{
(*GetBalanceRequest)(nil), // 0: kaspawalletd.GetBalanceRequest
(*GetBalanceResponse)(nil), // 1: kaspawalletd.GetBalanceResponse
@ -984,34 +1383,46 @@ var file_kaspawalletd_proto_goTypes = []interface{}{
(*BroadcastResponse)(nil), // 10: kaspawalletd.BroadcastResponse
(*ShutdownRequest)(nil), // 11: kaspawalletd.ShutdownRequest
(*ShutdownResponse)(nil), // 12: kaspawalletd.ShutdownResponse
(*SendRequest)(nil), // 13: kaspawalletd.SendRequest
(*SendResponse)(nil), // 14: kaspawalletd.SendResponse
(*SignRequest)(nil), // 15: kaspawalletd.SignRequest
(*SignResponse)(nil), // 16: kaspawalletd.SignResponse
(*Outpoint)(nil), // 13: kaspawalletd.Outpoint
(*UtxosByAddressesEntry)(nil), // 14: kaspawalletd.UtxosByAddressesEntry
(*ScriptPublicKey)(nil), // 15: kaspawalletd.ScriptPublicKey
(*UtxoEntry)(nil), // 16: kaspawalletd.UtxoEntry
(*GetExternalSpendableUTXOsRequest)(nil), // 17: kaspawalletd.GetExternalSpendableUTXOsRequest
(*GetExternalSpendableUTXOsResponse)(nil), // 18: kaspawalletd.GetExternalSpendableUTXOsResponse
(*SendRequest)(nil), // 19: kaspawalletd.SendRequest
(*SendResponse)(nil), // 20: kaspawalletd.SendResponse
(*SignRequest)(nil), // 21: kaspawalletd.SignRequest
(*SignResponse)(nil), // 22: kaspawalletd.SignResponse
}
var file_kaspawalletd_proto_depIdxs = []int32{
2, // 0: kaspawalletd.GetBalanceResponse.addressBalances:type_name -> kaspawalletd.AddressBalances
0, // 1: kaspawalletd.kaspawalletd.GetBalance:input_type -> kaspawalletd.GetBalanceRequest
3, // 2: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:input_type -> kaspawalletd.CreateUnsignedTransactionsRequest
5, // 3: kaspawalletd.kaspawalletd.ShowAddresses:input_type -> kaspawalletd.ShowAddressesRequest
7, // 4: kaspawalletd.kaspawalletd.NewAddress:input_type -> kaspawalletd.NewAddressRequest
11, // 5: kaspawalletd.kaspawalletd.Shutdown:input_type -> kaspawalletd.ShutdownRequest
9, // 6: kaspawalletd.kaspawalletd.Broadcast:input_type -> kaspawalletd.BroadcastRequest
13, // 7: kaspawalletd.kaspawalletd.Send:input_type -> kaspawalletd.SendRequest
15, // 8: kaspawalletd.kaspawalletd.Sign:input_type -> kaspawalletd.SignRequest
1, // 9: kaspawalletd.kaspawalletd.GetBalance:output_type -> kaspawalletd.GetBalanceResponse
4, // 10: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:output_type -> kaspawalletd.CreateUnsignedTransactionsResponse
6, // 11: kaspawalletd.kaspawalletd.ShowAddresses:output_type -> kaspawalletd.ShowAddressesResponse
8, // 12: kaspawalletd.kaspawalletd.NewAddress:output_type -> kaspawalletd.NewAddressResponse
12, // 13: kaspawalletd.kaspawalletd.Shutdown:output_type -> kaspawalletd.ShutdownResponse
10, // 14: kaspawalletd.kaspawalletd.Broadcast:output_type -> kaspawalletd.BroadcastResponse
14, // 15: kaspawalletd.kaspawalletd.Send:output_type -> kaspawalletd.SendResponse
16, // 16: kaspawalletd.kaspawalletd.Sign:output_type -> kaspawalletd.SignResponse
9, // [9:17] is the sub-list for method output_type
1, // [1:9] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
13, // 1: kaspawalletd.UtxosByAddressesEntry.outpoint:type_name -> kaspawalletd.Outpoint
16, // 2: kaspawalletd.UtxosByAddressesEntry.utxoEntry:type_name -> kaspawalletd.UtxoEntry
15, // 3: kaspawalletd.UtxoEntry.scriptPublicKey:type_name -> kaspawalletd.ScriptPublicKey
14, // 4: kaspawalletd.GetExternalSpendableUTXOsResponse.Entries:type_name -> kaspawalletd.UtxosByAddressesEntry
0, // 5: kaspawalletd.kaspawalletd.GetBalance:input_type -> kaspawalletd.GetBalanceRequest
17, // 6: kaspawalletd.kaspawalletd.GetExternalSpendableUTXOs:input_type -> kaspawalletd.GetExternalSpendableUTXOsRequest
3, // 7: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:input_type -> kaspawalletd.CreateUnsignedTransactionsRequest
5, // 8: kaspawalletd.kaspawalletd.ShowAddresses:input_type -> kaspawalletd.ShowAddressesRequest
7, // 9: kaspawalletd.kaspawalletd.NewAddress:input_type -> kaspawalletd.NewAddressRequest
11, // 10: kaspawalletd.kaspawalletd.Shutdown:input_type -> kaspawalletd.ShutdownRequest
9, // 11: kaspawalletd.kaspawalletd.Broadcast:input_type -> kaspawalletd.BroadcastRequest
19, // 12: kaspawalletd.kaspawalletd.Send:input_type -> kaspawalletd.SendRequest
21, // 13: kaspawalletd.kaspawalletd.Sign:input_type -> kaspawalletd.SignRequest
1, // 14: kaspawalletd.kaspawalletd.GetBalance:output_type -> kaspawalletd.GetBalanceResponse
18, // 15: kaspawalletd.kaspawalletd.GetExternalSpendableUTXOs:output_type -> kaspawalletd.GetExternalSpendableUTXOsResponse
4, // 16: kaspawalletd.kaspawalletd.CreateUnsignedTransactions:output_type -> kaspawalletd.CreateUnsignedTransactionsResponse
6, // 17: kaspawalletd.kaspawalletd.ShowAddresses:output_type -> kaspawalletd.ShowAddressesResponse
8, // 18: kaspawalletd.kaspawalletd.NewAddress:output_type -> kaspawalletd.NewAddressResponse
12, // 19: kaspawalletd.kaspawalletd.Shutdown:output_type -> kaspawalletd.ShutdownResponse
10, // 20: kaspawalletd.kaspawalletd.Broadcast:output_type -> kaspawalletd.BroadcastResponse
20, // 21: kaspawalletd.kaspawalletd.Send:output_type -> kaspawalletd.SendResponse
22, // 22: kaspawalletd.kaspawalletd.Sign:output_type -> kaspawalletd.SignResponse
14, // [14:23] is the sub-list for method output_type
5, // [5:14] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_kaspawalletd_proto_init() }
@ -1177,7 +1588,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SendRequest); i {
switch v := v.(*Outpoint); i {
case 0:
return &v.state
case 1:
@ -1189,7 +1600,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SendResponse); i {
switch v := v.(*UtxosByAddressesEntry); i {
case 0:
return &v.state
case 1:
@ -1201,7 +1612,7 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SignRequest); i {
switch v := v.(*ScriptPublicKey); i {
case 0:
return &v.state
case 1:
@ -1213,6 +1624,78 @@ func file_kaspawalletd_proto_init() {
}
}
file_kaspawalletd_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UtxoEntry); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetExternalSpendableUTXOsRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetExternalSpendableUTXOsResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SendRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SendResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SignRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_kaspawalletd_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SignResponse); i {
case 0:
return &v.state
@ -1231,7 +1714,7 @@ func file_kaspawalletd_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_kaspawalletd_proto_rawDesc,
NumEnums: 0,
NumMessages: 17,
NumMessages: 23,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -5,6 +5,7 @@ package kaspawalletd;
service kaspawalletd {
rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {}
rpc GetExternalSpendableUTXOs (GetExternalSpendableUTXOsRequest) returns (GetExternalSpendableUTXOsResponse) {}
rpc CreateUnsignedTransactions (CreateUnsignedTransactionsRequest) returns (CreateUnsignedTransactionsResponse) {}
rpc ShowAddresses (ShowAddressesRequest) returns (ShowAddressesResponse) {}
rpc NewAddress (NewAddressRequest) returns (NewAddressResponse) {}
@ -26,9 +27,9 @@ message GetBalanceResponse {
}
message AddressBalances {
string address = 1;
uint64 available = 2;
uint64 pending = 3;
string address = 1;
uint64 available = 2;
uint64 pending = 3;
}
message CreateUnsignedTransactionsRequest {
@ -55,7 +56,8 @@ message NewAddressResponse {
}
message BroadcastRequest {
repeated bytes transactions = 1;
bool isDomain = 1;
repeated bytes transactions = 2;
}
message BroadcastResponse {
@ -68,6 +70,36 @@ message ShutdownRequest {
message ShutdownResponse {
}
message Outpoint {
string transactionId = 1;
uint32 index = 2;
}
message UtxosByAddressesEntry {
string address = 1;
Outpoint outpoint = 2;
UtxoEntry utxoEntry = 3;
}
message ScriptPublicKey {
uint32 version = 1;
string scriptPublicKey = 2;
}
message UtxoEntry {
uint64 amount = 1;
ScriptPublicKey scriptPublicKey = 2;
uint64 blockDaaScore = 3;
bool isCoinbase = 4;
}
message GetExternalSpendableUTXOsRequest{
string address = 1;
}
message GetExternalSpendableUTXOsResponse{
repeated UtxosByAddressesEntry Entries = 1;
}
// Since SendRequest contains a password - this command should only be used on a trusted or secure connection
message SendRequest{
string toAddress = 1;

View File

@ -1,4 +1,8 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.17.2
// source: kaspawalletd.proto
package pb
@ -19,12 +23,15 @@ const _ = grpc.SupportPackageIsVersion7
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type KaspawalletdClient interface {
GetBalance(ctx context.Context, in *GetBalanceRequest, opts ...grpc.CallOption) (*GetBalanceResponse, error)
GetExternalSpendableUTXOs(ctx context.Context, in *GetExternalSpendableUTXOsRequest, opts ...grpc.CallOption) (*GetExternalSpendableUTXOsResponse, error)
CreateUnsignedTransactions(ctx context.Context, in *CreateUnsignedTransactionsRequest, opts ...grpc.CallOption) (*CreateUnsignedTransactionsResponse, error)
ShowAddresses(ctx context.Context, in *ShowAddressesRequest, opts ...grpc.CallOption) (*ShowAddressesResponse, error)
NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error)
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
Broadcast(ctx context.Context, in *BroadcastRequest, opts ...grpc.CallOption) (*BroadcastResponse, error)
// Since SendRequest contains a password - this command should only be used on a trusted or secure connection
Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error)
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
}
@ -45,6 +52,15 @@ func (c *kaspawalletdClient) GetBalance(ctx context.Context, in *GetBalanceReque
return out, nil
}
func (c *kaspawalletdClient) GetExternalSpendableUTXOs(ctx context.Context, in *GetExternalSpendableUTXOsRequest, opts ...grpc.CallOption) (*GetExternalSpendableUTXOsResponse, error) {
out := new(GetExternalSpendableUTXOsResponse)
err := c.cc.Invoke(ctx, "/kaspawalletd.kaspawalletd/GetExternalSpendableUTXOs", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *kaspawalletdClient) CreateUnsignedTransactions(ctx context.Context, in *CreateUnsignedTransactionsRequest, opts ...grpc.CallOption) (*CreateUnsignedTransactionsResponse, error) {
out := new(CreateUnsignedTransactionsResponse)
err := c.cc.Invoke(ctx, "/kaspawalletd.kaspawalletd/CreateUnsignedTransactions", in, out, opts...)
@ -113,12 +129,15 @@ func (c *kaspawalletdClient) Sign(ctx context.Context, in *SignRequest, opts ...
// for forward compatibility
type KaspawalletdServer interface {
GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error)
GetExternalSpendableUTXOs(context.Context, *GetExternalSpendableUTXOsRequest) (*GetExternalSpendableUTXOsResponse, error)
CreateUnsignedTransactions(context.Context, *CreateUnsignedTransactionsRequest) (*CreateUnsignedTransactionsResponse, error)
ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error)
NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error)
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error)
// Since SendRequest contains a password - this command should only be used on a trusted or secure connection
Send(context.Context, *SendRequest) (*SendResponse, error)
// Since SignRequest contains a password - this command should only be used on a trusted or secure connection
Sign(context.Context, *SignRequest) (*SignResponse, error)
mustEmbedUnimplementedKaspawalletdServer()
}
@ -130,6 +149,9 @@ type UnimplementedKaspawalletdServer struct {
func (UnimplementedKaspawalletdServer) GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetBalance not implemented")
}
func (UnimplementedKaspawalletdServer) GetExternalSpendableUTXOs(context.Context, *GetExternalSpendableUTXOsRequest) (*GetExternalSpendableUTXOsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetExternalSpendableUTXOs not implemented")
}
func (UnimplementedKaspawalletdServer) CreateUnsignedTransactions(context.Context, *CreateUnsignedTransactionsRequest) (*CreateUnsignedTransactionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUnsignedTransactions not implemented")
}
@ -182,6 +204,24 @@ func _Kaspawalletd_GetBalance_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Kaspawalletd_GetExternalSpendableUTXOs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetExternalSpendableUTXOsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KaspawalletdServer).GetExternalSpendableUTXOs(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/kaspawalletd.kaspawalletd/GetExternalSpendableUTXOs",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KaspawalletdServer).GetExternalSpendableUTXOs(ctx, req.(*GetExternalSpendableUTXOsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Kaspawalletd_CreateUnsignedTransactions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUnsignedTransactionsRequest)
if err := dec(in); err != nil {
@ -319,6 +359,10 @@ var Kaspawalletd_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetBalance",
Handler: _Kaspawalletd_GetBalance_Handler,
},
{
MethodName: "GetExternalSpendableUTXOs",
Handler: _Kaspawalletd_GetExternalSpendableUTXOs_Handler,
},
{
MethodName: "CreateUnsignedTransactions",
Handler: _Kaspawalletd_CreateUnsignedTransactions_Handler,

View File

@ -6,13 +6,14 @@ import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/infrastructure/network/rpcclient"
"github.com/pkg/errors"
)
func (s *server) Broadcast(_ context.Context, request *pb.BroadcastRequest) (*pb.BroadcastResponse, error) {
txIDs, err := s.broadcast(request.Transactions)
txIDs, err := s.broadcast(request.Transactions, request.IsDomain)
if err != nil {
return nil, err
}
@ -20,13 +21,24 @@ func (s *server) Broadcast(_ context.Context, request *pb.BroadcastRequest) (*pb
return &pb.BroadcastResponse{TxIDs: txIDs}, nil
}
func (s *server) broadcast(transactions [][]byte) ([]string, error) {
func (s *server) broadcast(transactions [][]byte, isDomain bool) ([]string, error) {
txIDs := make([]string, len(transactions))
var tx *externalapi.DomainTransaction
var err error
for i, transaction := range transactions {
tx, err := libkaspawallet.ExtractTransaction(transaction, s.keysFile.ECDSA)
if err != nil {
return nil, err
if isDomain {
tx, err = serialization.DeserializeDomainTransaction(transaction)
if err != nil {
return nil, err
}
} else if !isDomain { //default in proto3 is false
tx, err = libkaspawallet.ExtractTransaction(transaction, s.keysFile.ECDSA)
if err != nil {
return nil, err
}
}
txIDs[i], err = sendTransaction(s.rpcClient, tx)

View File

@ -0,0 +1,63 @@
package server
import (
"context"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
"github.com/kaspanet/kaspad/util"
)
func (s *server) GetExternalSpendableUTXOs(_ context.Context, request *pb.GetExternalSpendableUTXOsRequest) (*pb.GetExternalSpendableUTXOsResponse, error) {
s.lock.RLock()
defer s.lock.RUnlock()
_, err := util.DecodeAddress(request.Address, s.params.Prefix)
if err != nil {
return nil, err
}
externalUTXOs, err := s.rpcClient.GetUTXOsByAddresses([]string{request.Address})
if err != nil {
return nil, err
}
selectedUTXOs, err := s.selectExternalSpendableUTXOs(externalUTXOs, request.Address)
if err != nil {
return nil, err
}
return &pb.GetExternalSpendableUTXOsResponse{
Entries: selectedUTXOs,
}, nil
}
func (s *server) selectExternalSpendableUTXOs(externalUTXOs *appmessage.GetUTXOsByAddressesResponseMessage, address string) ([]*pb.UtxosByAddressesEntry, error) {
dagInfo, err := s.rpcClient.GetBlockDAGInfo()
if err != nil {
return nil, err
}
daaScore := dagInfo.VirtualDAAScore
maturity := s.params.BlockCoinbaseMaturity
//we do not make because we do not know size, because of unspendable utxos
var selectedExternalUtxos []*pb.UtxosByAddressesEntry
for _, entry := range externalUTXOs.Entries {
if !isExternalUTXOSpendable(entry, daaScore, maturity) {
continue
}
selectedExternalUtxos = append(selectedExternalUtxos, libkaspawallet.AppMessageUTXOToKaspawalletdUTXO(entry))
}
return selectedExternalUtxos, nil
}
func isExternalUTXOSpendable(entry *appmessage.UTXOsByAddressesEntry, virtualDAAScore uint64, coinbaseMaturity uint64) bool {
if !entry.UTXOEntry.IsCoinbase {
return true
} else if entry.UTXOEntry.Amount <= feePerInput {
return false
}
return entry.UTXOEntry.BlockDAAScore+coinbaseMaturity < virtualDAAScore
}

View File

@ -16,7 +16,7 @@ func (s *server) Send(_ context.Context, request *pb.SendRequest) (*pb.SendRespo
return nil, err
}
txIDs, err := s.broadcast(signedTransactions)
txIDs, err := s.broadcast(signedTransactions, false)
if err != nil {
return nil, err
}

View File

@ -0,0 +1,61 @@
package libkaspawallet
import (
"encoding/hex"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
)
//KaspawalletdUTXOsTolibkaspawalletUTXOs converts a []*pb.UtxosByAddressesEntry to a []*libkaspawallet.UTXO
func KaspawalletdUTXOsTolibkaspawalletUTXOs(kaspawalletdUtxoEntires []*pb.UtxosByAddressesEntry) ([]*UTXO, error) {
UTXOs := make([]*UTXO, len(kaspawalletdUtxoEntires))
for i, entry := range kaspawalletdUtxoEntires {
script, err := hex.DecodeString(entry.UtxoEntry.ScriptPublicKey.ScriptPublicKey)
if err != nil {
return nil, err
}
transactionID, err := transactionid.FromString(entry.Outpoint.TransactionId)
if err != nil {
return nil, err
}
UTXOs[i] = &UTXO{
UTXOEntry: utxo.NewUTXOEntry(
entry.UtxoEntry.Amount,
&externalapi.ScriptPublicKey{
Script: script,
Version: uint16(entry.UtxoEntry.ScriptPublicKey.Version),
},
entry.UtxoEntry.IsCoinbase,
entry.UtxoEntry.BlockDaaScore,
),
Outpoint: &externalapi.DomainOutpoint{
TransactionID: *transactionID,
Index: entry.Outpoint.Index,
},
}
}
return UTXOs, nil
}
// AppMessageUTXOToKaspawalletdUTXO converts an appmessage.UTXOsByAddressesEntry to a pb.UtxosByAddressesEntry
func AppMessageUTXOToKaspawalletdUTXO(appUTXOsByAddressesEntry *appmessage.UTXOsByAddressesEntry) *pb.UtxosByAddressesEntry {
return &pb.UtxosByAddressesEntry{
Outpoint: &pb.Outpoint{
TransactionId: appUTXOsByAddressesEntry.Outpoint.TransactionID,
Index: appUTXOsByAddressesEntry.Outpoint.Index,
},
UtxoEntry: &pb.UtxoEntry{
Amount: appUTXOsByAddressesEntry.UTXOEntry.Amount,
ScriptPublicKey: &pb.ScriptPublicKey{
Version: uint32(appUTXOsByAddressesEntry.UTXOEntry.ScriptPublicKey.Version),
ScriptPublicKey: appUTXOsByAddressesEntry.UTXOEntry.ScriptPublicKey.Script,
},
BlockDaaScore: appUTXOsByAddressesEntry.UTXOEntry.BlockDAAScore,
IsCoinbase: appUTXOsByAddressesEntry.UTXOEntry.IsCoinbase,
},
}
}

View File

@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: wallet.proto
package protoserialization
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type PartiallySignedTransaction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@ -3,11 +3,11 @@ package serialization
import (
"math"
"github.com/golang/protobuf/proto"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization/protoserialization"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/pkg/errors"
"google.golang.org/protobuf/proto"
)
// PartiallySignedTransaction is a type that is intended
@ -88,6 +88,22 @@ func SerializePartiallySignedTransaction(partiallySignedTransaction *PartiallySi
return proto.Marshal(partiallySignedTransactionToProto(partiallySignedTransaction))
}
//DeserializeDomainTransaction Deserialize a Transaction to an *externalapi.DomainTransaction
func DeserializeDomainTransaction(serializedTransactionMessage []byte) (*externalapi.DomainTransaction, error) {
protoTransactionMessage := &protoserialization.TransactionMessage{}
err := proto.Unmarshal(serializedTransactionMessage, protoTransactionMessage)
if err != nil {
return nil, err
}
return transactionFromProto(protoTransactionMessage)
}
// SerializeDomainTransaction Serialize a *externalapi.DomainTransaction
func SerializeDomainTransaction(tx *externalapi.DomainTransaction) ([]byte, error) {
return proto.Marshal(transactionToProto(tx))
}
func partiallySignedTransactionFromProto(protoPartiallySignedTransaction *protoserialization.PartiallySignedTransaction) (*PartiallySignedTransaction, error) {
tx, err := transactionFromProto(protoPartiallySignedTransaction.Tx)
if err != nil {

View File

@ -29,6 +29,8 @@ func main() {
err = dumpUnencryptedData(config.(*dumpUnencryptedDataConfig))
case startDaemonSubCmd:
err = startDaemon(config.(*startDaemonConfig))
case sweepSubCmd:
err = sweep(config.(*sweepConfig))
default:
err = errors.Errorf("Unknown sub-command '%s'\n", subCmd)
}

242
cmd/kaspawallet/sweep.go Normal file
View File

@ -0,0 +1,242 @@
package main
import (
"context"
"encoding/hex"
"fmt"
"github.com/kaspanet/go-secp256k1"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization"
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/kaspanet/kaspad/domain/miningmanager/mempool"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/txmass"
"github.com/pkg/errors"
)
const feePerInput = 10000
func sweep(conf *sweepConfig) error {
privateKeyBytes, err := hex.DecodeString(conf.PrivateKey)
if err != nil {
return err
}
publicKeybytes, err := libkaspawallet.PublicKeyFromPrivateKey(privateKeyBytes)
if err != nil {
return err
}
addressPubKey, err := util.NewAddressPublicKey(publicKeybytes, conf.NetParams().Prefix)
if err != nil {
return err
}
address, err := util.DecodeAddress(addressPubKey.String(), conf.NetParams().Prefix)
if err != nil {
return err
}
daemonClient, tearDown, err := client.Connect(conf.DaemonAddress)
if err != nil {
return err
}
defer tearDown()
ctx, cancel := context.WithTimeout(context.Background(), daemonTimeout)
defer cancel()
getExternalSpendableUTXOsResponse, err := daemonClient.GetExternalSpendableUTXOs(ctx, &pb.GetExternalSpendableUTXOsRequest{
Address: address.String(),
})
if err != nil {
return err
}
UTXOs, err := libkaspawallet.KaspawalletdUTXOsTolibkaspawalletUTXOs(getExternalSpendableUTXOsResponse.Entries)
if err != nil {
return err
}
paymentAmount := uint64(0)
if len(UTXOs) == 0 {
return errors.Errorf("Could not find any spendable UTXOs in %s", addressPubKey)
}
for _, UTXO := range UTXOs {
paymentAmount = paymentAmount + UTXO.UTXOEntry.Amount()
}
newAddressResponse, err := daemonClient.NewAddress(ctx, &pb.NewAddressRequest{})
if err != nil {
return err
}
toAddress, err := util.DecodeAddress(newAddressResponse.Address, conf.ActiveNetParams.Prefix)
if err != nil {
return err
}
splitTransactions, err := createSplitTransactionsWithSchnorrPrivteKey(conf.NetParams(), UTXOs, toAddress, feePerInput)
if err != nil {
return err
}
serializedSplitTransactions, err := signWithSchnorrPrivateKey(conf.NetParams(), privateKeyBytes, splitTransactions)
if err != nil {
return err
}
fmt.Println("\nSweeping...")
fmt.Println("\tFrom:\t", addressPubKey)
fmt.Println("\tTo:\t", toAddress)
response, err := daemonClient.Broadcast(ctx, &pb.BroadcastRequest{
IsDomain: true,
Transactions: serializedSplitTransactions,
})
if err != nil {
return err
}
totalExtracted := uint64(0)
fmt.Println("\nTransaction ID(s):")
for i, txID := range response.TxIDs {
fmt.Printf("\t%s\n", txID)
fmt.Println("\tSwept:\t", utils.FormatKas(splitTransactions[i].Outputs[0].Value), " KAS")
totalExtracted = totalExtracted + splitTransactions[i].Outputs[0].Value
}
fmt.Println("\nTotal Funds swept (including transaction fees):")
fmt.Println("\t", utils.FormatKas(totalExtracted), " KAS")
return nil
}
func newDummyTransaction() *externalapi.DomainTransaction {
return &externalapi.DomainTransaction{
Version: constants.MaxTransactionVersion,
Inputs: make([]*externalapi.DomainTransactionInput, 0), //we create empty inputs
LockTime: 0,
Outputs: make([]*externalapi.DomainTransactionOutput, 1), // we should always have 1 output to the toAdress
SubnetworkID: subnetworks.SubnetworkIDNative,
Gas: 0,
Payload: nil,
}
}
func createSplitTransactionsWithSchnorrPrivteKey(
params *dagconfig.Params,
selectedUTXOs []*libkaspawallet.UTXO,
toAddress util.Address,
feePerInput int) ([]*externalapi.DomainTransaction, error) {
var splitTransactions []*externalapi.DomainTransaction
extraMass := uint64(7000) // Account for future signatures.
massCalculater := txmass.NewCalculator(params.MassPerTxByte, params.MassPerScriptPubKeyByte, params.MassPerSigOp)
scriptPublicKey, err := txscript.PayToAddrScript(toAddress)
if err != nil {
return nil, err
}
totalSplitAmount := uint64(0)
lastValidTx := newDummyTransaction()
currentTx := newDummyTransaction() //i.e. the tested tx
//loop through utxos commit segments that don't violate max mass
for i, currentUTXO := range selectedUTXOs {
totalSplitAmount = totalSplitAmount + currentUTXO.UTXOEntry.Amount()
currentTx.Inputs = append(
currentTx.Inputs,
&externalapi.DomainTransactionInput{
PreviousOutpoint: *currentUTXO.Outpoint,
UTXOEntry: utxo.NewUTXOEntry(
currentUTXO.UTXOEntry.Amount(),
currentUTXO.UTXOEntry.ScriptPublicKey(),
false,
constants.UnacceptedDAAScore,
),
SigOpCount: 1,
},
)
currentTx.Outputs[0] = &externalapi.DomainTransactionOutput{
Value: totalSplitAmount - uint64(len(currentTx.Inputs)*feePerInput),
ScriptPublicKey: scriptPublicKey,
}
if massCalculater.CalculateTransactionMass(currentTx)+extraMass >= mempool.MaximumStandardTransactionMass {
//in this loop we assume a transaction with one input and one output cannot violate max transaction mass, hence a sanity check.
if len(currentTx.Inputs) == 1 {
return nil, errors.Errorf("transaction with one input and one output violates transaction mass")
}
splitTransactions = append(splitTransactions, lastValidTx)
totalSplitAmount = 0
lastValidTx = newDummyTransaction()
currentTx = newDummyTransaction()
continue
}
//Special case, end of inputs, with no violation, where we can assign currentTX to split and break
if i == len(selectedUTXOs)-1 {
splitTransactions = append(splitTransactions, currentTx)
break
}
lastValidTx = currentTx.Clone()
currentTx.Outputs = make([]*externalapi.DomainTransactionOutput, 1)
}
return splitTransactions, nil
}
func signWithSchnorrPrivateKey(params *dagconfig.Params, privateKeyBytes []byte, domainTransactions []*externalapi.DomainTransaction) ([][]byte, error) {
schnorrkeyPair, err := secp256k1.DeserializeSchnorrPrivateKeyFromSlice(privateKeyBytes)
if err != nil {
return nil, err
}
serializedDomainTransactions := make([][]byte, len(domainTransactions))
for i1, domainTransaction := range domainTransactions {
sighashReusedValues := &consensushashing.SighashReusedValues{}
for i2, input := range domainTransaction.Inputs {
signature, err := txscript.SignatureScript(domainTransaction, i2, consensushashing.SigHashAll, schnorrkeyPair, sighashReusedValues)
if err != nil {
return nil, err
}
input.SignatureScript = signature
}
serializedDomainTransactions[i1], err = serialization.SerializeDomainTransaction(domainTransaction)
if err != nil {
return nil, err
}
}
return serializedDomainTransactions, nil
}

View File

@ -0,0 +1,16 @@
package utils
import (
"fmt"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
)
// FormatKas takes the amount of sompis as uint64, and returns amount of KAS with 8 decimal places
func FormatKas(amount uint64) string {
res := " "
if amount > 0 {
res = fmt.Sprintf("%19.8f", float64(amount)/constants.SompiPerKaspa)
}
return res
}

View File

@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: dbobjects.proto
package serialization
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type DbBlock struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: peer_service.proto
package pb
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type GetPeersListRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@ -1,4 +1,8 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.17.2
// source: peer_service.proto
package pb
@ -11,7 +15,8 @@ import (
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// PeerServiceClient is the client API for PeerService service.
//
@ -49,13 +54,20 @@ type PeerServiceServer interface {
type UnimplementedPeerServiceServer struct {
}
func (*UnimplementedPeerServiceServer) GetPeersList(context.Context, *GetPeersListRequest) (*GetPeersListResponse, error) {
func (UnimplementedPeerServiceServer) GetPeersList(context.Context, *GetPeersListRequest) (*GetPeersListResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPeersList not implemented")
}
func (*UnimplementedPeerServiceServer) mustEmbedUnimplementedPeerServiceServer() {}
func (UnimplementedPeerServiceServer) mustEmbedUnimplementedPeerServiceServer() {}
func RegisterPeerServiceServer(s *grpc.Server, srv PeerServiceServer) {
s.RegisterService(&_PeerService_serviceDesc, srv)
// UnsafePeerServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to PeerServiceServer will
// result in compilation errors.
type UnsafePeerServiceServer interface {
mustEmbedUnimplementedPeerServiceServer()
}
func RegisterPeerServiceServer(s grpc.ServiceRegistrar, srv PeerServiceServer) {
s.RegisterService(&PeerService_ServiceDesc, srv)
}
func _PeerService_GetPeersList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
@ -76,7 +88,10 @@ func _PeerService_GetPeersList_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
var _PeerService_serviceDesc = grpc.ServiceDesc{
// PeerService_ServiceDesc is the grpc.ServiceDesc for PeerService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var PeerService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "PeerService",
HandlerType: (*PeerServiceServer)(nil),
Methods: []grpc.MethodDesc{

View File

@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: messages.proto
package protowire
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type KaspadMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@ -1,4 +1,8 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.17.2
// source: messages.proto
package protowire
@ -11,7 +15,8 @@ import (
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// P2PClient is the client API for P2P service.
//
@ -29,7 +34,7 @@ func NewP2PClient(cc grpc.ClientConnInterface) P2PClient {
}
func (c *p2PClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (P2P_MessageStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &_P2P_serviceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...)
stream, err := c.cc.NewStream(ctx, &P2P_ServiceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...)
if err != nil {
return nil, err
}
@ -71,13 +76,20 @@ type P2PServer interface {
type UnimplementedP2PServer struct {
}
func (*UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error {
func (UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error {
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
}
func (*UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {}
func (UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {}
func RegisterP2PServer(s *grpc.Server, srv P2PServer) {
s.RegisterService(&_P2P_serviceDesc, srv)
// UnsafeP2PServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to P2PServer will
// result in compilation errors.
type UnsafeP2PServer interface {
mustEmbedUnimplementedP2PServer()
}
func RegisterP2PServer(s grpc.ServiceRegistrar, srv P2PServer) {
s.RegisterService(&P2P_ServiceDesc, srv)
}
func _P2P_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
@ -106,7 +118,10 @@ func (x *p2PMessageStreamServer) Recv() (*KaspadMessage, error) {
return m, nil
}
var _P2P_serviceDesc = grpc.ServiceDesc{
// P2P_ServiceDesc is the grpc.ServiceDesc for P2P service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var P2P_ServiceDesc = grpc.ServiceDesc{
ServiceName: "protowire.P2P",
HandlerType: (*P2PServer)(nil),
Methods: []grpc.MethodDesc{},
@ -137,7 +152,7 @@ func NewRPCClient(cc grpc.ClientConnInterface) RPCClient {
}
func (c *rPCClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (RPC_MessageStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &_RPC_serviceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...)
stream, err := c.cc.NewStream(ctx, &RPC_ServiceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...)
if err != nil {
return nil, err
}
@ -179,13 +194,20 @@ type RPCServer interface {
type UnimplementedRPCServer struct {
}
func (*UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error {
func (UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error {
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
}
func (*UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {}
func (UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {}
func RegisterRPCServer(s *grpc.Server, srv RPCServer) {
s.RegisterService(&_RPC_serviceDesc, srv)
// UnsafeRPCServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to RPCServer will
// result in compilation errors.
type UnsafeRPCServer interface {
mustEmbedUnimplementedRPCServer()
}
func RegisterRPCServer(s grpc.ServiceRegistrar, srv RPCServer) {
s.RegisterService(&RPC_ServiceDesc, srv)
}
func _RPC_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
@ -214,7 +236,10 @@ func (x *rPCMessageStreamServer) Recv() (*KaspadMessage, error) {
return m, nil
}
var _RPC_serviceDesc = grpc.ServiceDesc{
// RPC_ServiceDesc is the grpc.ServiceDesc for RPC service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var RPC_ServiceDesc = grpc.ServiceDesc{
ServiceName: "protowire.RPC",
HandlerType: (*RPCServer)(nil),
Methods: []grpc.MethodDesc{},

View File

@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: p2p.proto
package protowire
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type RequestAddressesMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@ -10,14 +10,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// protoc-gen-go v1.28.0
// protoc v3.17.2
// source: rpc.proto
package protowire
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -31,10 +30,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type SubmitBlockResponseMessage_RejectReason int32
const (