Add request balance by address to kaspactl (#1885)

* Added new RPC command for getting balance of wallet address

* small details

* Regenerate protobuffs

* fixes

* routing fix

* Add 'Message' suffix to GetBalanceByAddressRequest and GetBalanceByAddressResponse

* Add Message

* linting

* linting

* fixed name

Co-authored-by: Mike Zak <feanorr@gmail.com>
Co-authored-by: Ori Newman <>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Michael Sutton <mikisiton2@gmail.com>
This commit is contained in:
FestinaLente666 2021-12-22 22:21:33 +02:00 committed by GitHub
parent cae7faced2
commit 129e9119d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 711 additions and 251 deletions

View File

@ -124,6 +124,8 @@ const (
CmdStopNotifyingUTXOsChangedResponseMessage
CmdGetUTXOsByAddressesRequestMessage
CmdGetUTXOsByAddressesResponseMessage
CmdGetBalanceByAddressRequestMessage
CmdGetBalanceByAddressResponseMessage
CmdGetVirtualSelectedParentBlueScoreRequestMessage
CmdGetVirtualSelectedParentBlueScoreResponseMessage
CmdNotifyVirtualSelectedParentBlueScoreChangedRequestMessage
@ -243,6 +245,8 @@ var RPCMessageCommandToString = map[MessageCommand]string{
CmdStopNotifyingUTXOsChangedResponseMessage: "StopNotifyingUTXOsChangedResponse",
CmdGetUTXOsByAddressesRequestMessage: "GetUTXOsByAddressesRequest",
CmdGetUTXOsByAddressesResponseMessage: "GetUTXOsByAddressesResponse",
CmdGetBalanceByAddressRequestMessage: "GetBalanceByAddressRequest",
CmdGetBalanceByAddressResponseMessage: "GetBalancesByAddressResponse",
CmdGetVirtualSelectedParentBlueScoreRequestMessage: "GetVirtualSelectedParentBlueScoreRequest",
CmdGetVirtualSelectedParentBlueScoreResponseMessage: "GetVirtualSelectedParentBlueScoreResponse",
CmdNotifyVirtualSelectedParentBlueScoreChangedRequestMessage: "NotifyVirtualSelectedParentBlueScoreChangedRequest",

View File

@ -0,0 +1,41 @@
package appmessage
// GetBalanceByAddressRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBalanceByAddressRequestMessage struct {
baseMessage
Address string
}
// Command returns the protocol command string for the message
func (msg *GetBalanceByAddressRequestMessage) Command() MessageCommand {
return CmdGetBalanceByAddressRequestMessage
}
// NewGetBalanceByAddressRequest returns a instance of the message
func NewGetBalanceByAddressRequest(address string) *GetBalanceByAddressRequestMessage {
return &GetBalanceByAddressRequestMessage{
Address: address,
}
}
// GetBalanceByAddressResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBalanceByAddressResponseMessage struct {
baseMessage
Balance uint64
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBalanceByAddressResponseMessage) Command() MessageCommand {
return CmdGetBalanceByAddressResponseMessage
}
// NewGetBalanceByAddressResponse returns an instance of the message
func NewGetBalanceByAddressResponse(Balance uint64) *GetBalanceByAddressResponseMessage {
return &GetBalanceByAddressResponseMessage{
Balance: Balance,
}
}

View File

@ -28,6 +28,7 @@ var handlers = map[appmessage.MessageCommand]handler{
appmessage.CmdGetVirtualSelectedParentChainFromBlockRequestMessage: rpchandlers.HandleGetVirtualSelectedParentChainFromBlock,
appmessage.CmdGetBlocksRequestMessage: rpchandlers.HandleGetBlocks,
appmessage.CmdGetBlockCountRequestMessage: rpchandlers.HandleGetBlockCount,
appmessage.CmdGetBalanceByAddressRequestMessage: rpchandlers.HandleGetBalanceByAddress,
appmessage.CmdGetBlockDAGInfoRequestMessage: rpchandlers.HandleGetBlockDAGInfo,
appmessage.CmdResolveFinalityConflictRequestMessage: rpchandlers.HandleResolveFinalityConflict,
appmessage.CmdNotifyFinalityConflictsRequestMessage: rpchandlers.HandleNotifyFinalityConflicts,

View File

@ -0,0 +1,47 @@
package rpchandlers
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util"
)
// HandleGetBalanceByAddress handles the respectively named RPC command
func HandleGetBalanceByAddress(context *rpccontext.Context, _ *router.Router, request appmessage.Message) (appmessage.Message, error) {
if !context.Config.UTXOIndex {
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
errorMessage.Error = appmessage.RPCErrorf("Method unavailable when kaspad is run without --utxoindex")
return errorMessage, nil
}
getBalanceByAddressRequest := request.(*appmessage.GetBalanceByAddressRequestMessage)
var balance uint64 = 0
addressString := getBalanceByAddressRequest.Address
address, err := util.DecodeAddress(addressString, context.Config.ActiveNetParams.Prefix)
if err != nil {
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
errorMessage.Error = appmessage.RPCErrorf("Could decode address '%s': %s", addressString, err)
return errorMessage, nil
}
scriptPublicKey, err := txscript.PayToAddrScript(address)
if err != nil {
errorMessage := &appmessage.GetUTXOsByAddressesResponseMessage{}
errorMessage.Error = appmessage.RPCErrorf("Could not create a scriptPublicKey for address '%s': %s", addressString, err)
return errorMessage, nil
}
utxoOutpointEntryPairs, err := context.UTXOIndex.UTXOs(scriptPublicKey)
if err != nil {
return nil, err
}
for _, utxoOutpointEntryPair := range utxoOutpointEntryPairs {
balance += utxoOutpointEntryPair.Amount()
}
response := appmessage.NewGetBalanceByAddressResponse(balance)
return response, nil
}

View File

@ -34,6 +34,7 @@ var commandTypes = []reflect.Type{
reflect.TypeOf(protowire.KaspadMessage_SubmitTransactionRequest{}),
reflect.TypeOf(protowire.KaspadMessage_GetUtxosByAddressesRequest{}),
reflect.TypeOf(protowire.KaspadMessage_GetBalanceByAddressRequestMessage{}),
reflect.TypeOf(protowire.KaspadMessage_BanRequest{}),
reflect.TypeOf(protowire.KaspadMessage_UnbanRequest{}),

View File

@ -3,13 +3,13 @@ protowire
1. Download and place in your PATH:
https://github.com/protocolbuffers/protobuf/releases/download/v3.12.3/protoc-3.12.3-linux-x86_64.zip
2. `go get github.com/golang/protobuf/protoc-gen-go`
3. `go get google.golang.org/grpc/cmd/protoc-gen-go-grpc`
2. `go install github.com/golang/protobuf/protoc-gen-go`
3. `go install google.golang.org/grpc/cmd/protoc-gen-go-grpc`
4. In the protowire directory: `go generate .`
Documentation
-------------
To generate `rpc.md`:
1. `go get -u github.com/kaspanet/protoc-gen-doc/cmd/protoc-gen-doc`
1. `go install -u github.com/kaspanet/protoc-gen-doc/cmd/protoc-gen-doc`
2. In the protowire directory: `protoc --doc_out=. --doc_opt=markdown,rpc.md rpc.proto`

View File

@ -138,6 +138,8 @@ type KaspadMessage struct {
// *KaspadMessage_NotifyVirtualDaaScoreChangedRequest
// *KaspadMessage_NotifyVirtualDaaScoreChangedResponse
// *KaspadMessage_VirtualDaaScoreChangedNotification
// *KaspadMessage_GetBalanceByAddressRequestMessage
// *KaspadMessage_GetBalanceByAddressResponseMessage
Payload isKaspadMessage_Payload `protobuf_oneof:"payload"`
}
@ -964,6 +966,20 @@ func (x *KaspadMessage) GetVirtualDaaScoreChangedNotification() *VirtualDaaScore
return nil
}
func (x *KaspadMessage) GetGetBalanceByAddressRequestMessage() *GetBalanceByAddressRequestMessage {
if x, ok := x.GetPayload().(*KaspadMessage_GetBalanceByAddressRequestMessage); ok {
return x.GetBalanceByAddressRequestMessage
}
return nil
}
func (x *KaspadMessage) GetGetBalanceByAddressResponseMessage() *GetBalanceByAddressResponseMessage {
if x, ok := x.GetPayload().(*KaspadMessage_GetBalanceByAddressResponseMessage); ok {
return x.GetBalanceByAddressResponseMessage
}
return nil
}
type isKaspadMessage_Payload interface {
isKaspadMessage_Payload()
}
@ -1416,6 +1432,14 @@ type KaspadMessage_VirtualDaaScoreChangedNotification struct {
VirtualDaaScoreChangedNotification *VirtualDaaScoreChangedNotificationMessage `protobuf:"bytes,1076,opt,name=virtualDaaScoreChangedNotification,proto3,oneof"`
}
type KaspadMessage_GetBalanceByAddressRequestMessage struct {
GetBalanceByAddressRequestMessage *GetBalanceByAddressRequestMessage `protobuf:"bytes,1077,opt,name=getBalanceByAddressRequestMessage,proto3,oneof"`
}
type KaspadMessage_GetBalanceByAddressResponseMessage struct {
GetBalanceByAddressResponseMessage *GetBalanceByAddressResponseMessage `protobuf:"bytes,1078,opt,name=getBalanceByAddressResponseMessage,proto3,oneof"`
}
func (*KaspadMessage_Addresses) isKaspadMessage_Payload() {}
func (*KaspadMessage_Block) isKaspadMessage_Payload() {}
@ -1640,13 +1664,17 @@ func (*KaspadMessage_NotifyVirtualDaaScoreChangedResponse) isKaspadMessage_Paylo
func (*KaspadMessage_VirtualDaaScoreChangedNotification) isKaspadMessage_Payload() {}
func (*KaspadMessage_GetBalanceByAddressRequestMessage) isKaspadMessage_Payload() {}
func (*KaspadMessage_GetBalanceByAddressResponseMessage) isKaspadMessage_Payload() {}
var File_messages_proto protoreflect.FileDescriptor
var file_messages_proto_rawDesc = []byte{
0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x1a, 0x09, 0x70, 0x32, 0x70,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x09, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0xfb, 0x5d, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
0x6f, 0x22, 0xfd, 0x5f, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69,
0x72, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73,
@ -2397,21 +2425,37 @@ var file_messages_proto_rawDesc = []byte{
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00,
0x52, 0x22, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x61, 0x61, 0x53, 0x63, 0x6f, 0x72,
0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32,
0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77,
0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61,
0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30,
0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50, 0x43, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x7d, 0x0a, 0x21, 0x67, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0xb5, 0x08, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74,
0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00,
0x52, 0x21, 0x67, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x79, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x22, 0x67, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e,
0x63, 0x65, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0xb6, 0x08, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x47, 0x65,
0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x48, 0x00, 0x52, 0x22, 0x67, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x42, 0x79,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x32, 0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e,
0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28,
0x01, 0x30, 0x01, 0x42, 0x26, 0x5a, 0x24, 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, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x01, 0x30, 0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50, 0x43, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72,
0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x26, 0x5a, 0x24, 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, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -2540,6 +2584,8 @@ var file_messages_proto_goTypes = []interface{}{
(*NotifyVirtualDaaScoreChangedRequestMessage)(nil), // 109: protowire.NotifyVirtualDaaScoreChangedRequestMessage
(*NotifyVirtualDaaScoreChangedResponseMessage)(nil), // 110: protowire.NotifyVirtualDaaScoreChangedResponseMessage
(*VirtualDaaScoreChangedNotificationMessage)(nil), // 111: protowire.VirtualDaaScoreChangedNotificationMessage
(*GetBalanceByAddressRequestMessage)(nil), // 112: protowire.GetBalanceByAddressRequestMessage
(*GetBalanceByAddressResponseMessage)(nil), // 113: protowire.GetBalanceByAddressResponseMessage
}
var file_messages_proto_depIdxs = []int32{
1, // 0: protowire.KaspadMessage.addresses:type_name -> protowire.AddressesMessage
@ -2654,15 +2700,17 @@ var file_messages_proto_depIdxs = []int32{
109, // 109: protowire.KaspadMessage.notifyVirtualDaaScoreChangedRequest:type_name -> protowire.NotifyVirtualDaaScoreChangedRequestMessage
110, // 110: protowire.KaspadMessage.notifyVirtualDaaScoreChangedResponse:type_name -> protowire.NotifyVirtualDaaScoreChangedResponseMessage
111, // 111: protowire.KaspadMessage.virtualDaaScoreChangedNotification:type_name -> protowire.VirtualDaaScoreChangedNotificationMessage
0, // 112: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage
0, // 113: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage
0, // 114: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage
0, // 115: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage
114, // [114:116] is the sub-list for method output_type
112, // [112:114] is the sub-list for method input_type
112, // [112:112] is the sub-list for extension type_name
112, // [112:112] is the sub-list for extension extendee
0, // [0:112] is the sub-list for field type_name
112, // 112: protowire.KaspadMessage.getBalanceByAddressRequestMessage:type_name -> protowire.GetBalanceByAddressRequestMessage
113, // 113: protowire.KaspadMessage.getBalanceByAddressResponseMessage:type_name -> protowire.GetBalanceByAddressResponseMessage
0, // 114: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage
0, // 115: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage
0, // 116: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage
0, // 117: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage
116, // [116:118] is the sub-list for method output_type
114, // [114:116] is the sub-list for method input_type
114, // [114:114] is the sub-list for extension type_name
114, // [114:114] is the sub-list for extension extendee
0, // [0:114] is the sub-list for field type_name
}
func init() { file_messages_proto_init() }
@ -2799,6 +2847,8 @@ func file_messages_proto_init() {
(*KaspadMessage_NotifyVirtualDaaScoreChangedRequest)(nil),
(*KaspadMessage_NotifyVirtualDaaScoreChangedResponse)(nil),
(*KaspadMessage_VirtualDaaScoreChangedNotification)(nil),
(*KaspadMessage_GetBalanceByAddressRequestMessage)(nil),
(*KaspadMessage_GetBalanceByAddressResponseMessage)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{

View File

@ -121,6 +121,8 @@ message KaspadMessage {
NotifyVirtualDaaScoreChangedRequestMessage notifyVirtualDaaScoreChangedRequest = 1074;
NotifyVirtualDaaScoreChangedResponseMessage notifyVirtualDaaScoreChangedResponse = 1075;
VirtualDaaScoreChangedNotificationMessage virtualDaaScoreChangedNotification = 1076;
GetBalanceByAddressRequestMessage getBalanceByAddressRequest = 1077;
GetBalanceByAddressResponseMessage getBalanceByAddressResponse = 1078;
}
}

View File

@ -7,6 +7,7 @@
- [RPCError](#protowire.RPCError)
- [RpcBlock](#protowire.RpcBlock)
- [RpcBlockHeader](#protowire.RpcBlockHeader)
- [RpcBlockLevelParents](#protowire.RpcBlockLevelParents)
- [RpcBlockVerboseData](#protowire.RpcBlockVerboseData)
- [RpcTransaction](#protowire.RpcTransaction)
- [RpcTransactionInput](#protowire.RpcTransactionInput)
@ -76,6 +77,8 @@
- [StopNotifyingUtxosChangedResponseMessage](#protowire.StopNotifyingUtxosChangedResponseMessage)
- [GetUtxosByAddressesRequestMessage](#protowire.GetUtxosByAddressesRequestMessage)
- [GetUtxosByAddressesResponseMessage](#protowire.GetUtxosByAddressesResponseMessage)
- [GetBalanceByAddressRequestMessage](#protowire.GetBalanceByAddressRequestMessage)
- [GetBalanceByAddressResponseMessage](#protowire.GetBalanceByAddressResponseMessage)
- [GetVirtualSelectedParentBlueScoreRequestMessage](#protowire.GetVirtualSelectedParentBlueScoreRequestMessage)
- [GetVirtualSelectedParentBlueScoreResponseMessage](#protowire.GetVirtualSelectedParentBlueScoreResponseMessage)
- [NotifyVirtualSelectedParentBlueScoreChangedRequestMessage](#protowire.NotifyVirtualSelectedParentBlueScoreChangedRequestMessage)
@ -161,13 +164,32 @@ Receivers of any ResponseMessage are expected to check whether its error field i
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| version | [uint32](#uint32) | | |
| parentHashes | [string](#string) | repeated | |
| parents | [RpcBlockLevelParents](#protowire.RpcBlockLevelParents) | repeated | |
| hashMerkleRoot | [string](#string) | | |
| acceptedIdMerkleRoot | [string](#string) | | |
| utxoCommitment | [string](#string) | | |
| timestamp | [int64](#int64) | | |
| bits | [uint32](#uint32) | | |
| nonce | [uint64](#uint64) | | |
| daaScore | [uint64](#uint64) | | |
| blueWork | [string](#string) | | |
| pruningPoint | [string](#string) | | |
| blueScore | [uint64](#uint64) | | |
<a name="protowire.RpcBlockLevelParents"></a>
### RpcBlockLevelParents
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parentHashes | [string](#string) | repeated | |
@ -313,7 +335,7 @@ Receivers of any ResponseMessage are expected to check whether its error field i
| ----- | ---- | ----- | ----------- |
| transactionId | [string](#string) | | |
| hash | [string](#string) | | |
| size | [uint64](#uint64) | | |
| mass | [uint64](#uint64) | | |
| blockHash | [string](#string) | | |
| blockTime | [uint64](#uint64) | | |
@ -1273,6 +1295,39 @@ This call is only available when this kaspad was started with `--utxoindex`
<a name="protowire.GetBalanceByAddressRequestMessage"></a>
### GetBalanceByAddressRequestMessage
GetBalanceByAddressRequest returns the total balance in unspent transactions towards a given address
This call is only available when this kaspad was started with `--utxoindex`
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| address | [string](#string) | | |
<a name="protowire.GetBalanceByAddressResponseMessage"></a>
### GetBalanceByAddressResponseMessage
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| balance | [uint64](#uint64) | | |
| error | [RPCError](#protowire.RPCError) | | |
<a name="protowire.GetVirtualSelectedParentBlueScoreRequestMessage"></a>
### GetVirtualSelectedParentBlueScoreRequestMessage

View File

@ -498,6 +498,19 @@ message GetUtxosByAddressesResponseMessage {
RPCError error = 1000;
}
// GetBalanceByAddressRequest returns the total balance in unspent transactions towards a given address
//
// This call is only available when this kaspad was started with `--utxoindex`
message GetBalanceByAddressRequestMessage {
string address = 1;
}
message GetBalanceByAddressResponseMessage {
uint64 balance = 1;
RPCError error = 1000;
}
// GetVirtualSelectedParentBlueScoreRequestMessage requests the blue score of the current selected parent
// of the virtual block.
message GetVirtualSelectedParentBlueScoreRequestMessage {

View File

@ -0,0 +1,69 @@
package protowire
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/pkg/errors"
)
func (x *KaspadMessage_GetBalanceByAddressRequestMessage) toAppMessage() (appmessage.Message, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "KaspadMessage_GetBalanceByAddressRequest is nil")
}
return x.GetBalanceByAddressRequestMessage.toAppMessage()
}
func (x *KaspadMessage_GetBalanceByAddressRequestMessage) fromAppMessage(message *appmessage.GetBalanceByAddressRequestMessage) error {
x.GetBalanceByAddressRequestMessage = &GetBalanceByAddressRequestMessage{
Address: message.Address,
}
return nil
}
func (x *GetBalanceByAddressRequestMessage) toAppMessage() (appmessage.Message, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "GetBalanceByAddressRequest is nil")
}
return &appmessage.GetBalanceByAddressRequestMessage{
Address: x.Address,
}, nil
}
func (x *KaspadMessage_GetBalanceByAddressResponseMessage) toAppMessage() (appmessage.Message, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "GetBalanceByAddressResponse is nil")
}
return x.GetBalanceByAddressResponseMessage.toAppMessage()
}
func (x *KaspadMessage_GetBalanceByAddressResponseMessage) fromAppMessage(message *appmessage.GetBalanceByAddressResponseMessage) error {
var err *RPCError
if message.Error != nil {
err = &RPCError{Message: message.Error.Message}
}
x.GetBalanceByAddressResponseMessage = &GetBalanceByAddressResponseMessage{
Balance: message.Balance,
Error: err,
}
return nil
}
func (x *GetBalanceByAddressResponseMessage) toAppMessage() (appmessage.Message, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "GetBalanceByAddressResponse is nil")
}
rpcErr, err := x.Error.toAppMessage()
// Error is an optional field
if err != nil && !errors.Is(err, errorNil) {
return nil, err
}
if rpcErr != nil && x.Balance != 1 {
return nil, errors.New("GetBalanceByAddressResponse contains both an error and a response")
}
return &appmessage.GetBalanceByAddressResponseMessage{
Balance: x.Balance,
Error: rpcErr,
}, nil
}

View File

@ -702,6 +702,20 @@ func toRPCPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err
}
return payload, nil
case *appmessage.GetBalanceByAddressRequestMessage:
payload := new(KaspadMessage_GetBalanceByAddressRequestMessage)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBalanceByAddressResponseMessage:
payload := new(KaspadMessage_GetBalanceByAddressResponseMessage)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetVirtualSelectedParentBlueScoreRequestMessage:
payload := new(KaspadMessage_GetVirtualSelectedParentBlueScoreRequest)
err := payload.fromAppMessage(message)

View File

@ -0,0 +1,20 @@
package rpcclient
import "github.com/kaspanet/kaspad/app/appmessage"
// GetBalanceByAddress sends an RPC request respective to the function's name and returns the RPC server's response
func (c *RPCClient) GetBalanceByAddress(address string) (*appmessage.GetBalanceByAddressResponseMessage, error) {
err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewGetBalanceByAddressRequest(address))
if err != nil {
return nil, err
}
response, err := c.route(appmessage.CmdGetBalanceByAddressResponseMessage).DequeueWithTimeout(c.timeout)
if err != nil {
return nil, err
}
getBalanceByAddressResponse := response.(*appmessage.GetBalanceByAddressResponseMessage)
if getBalanceByAddressResponse.Error != nil {
return nil, c.convertRPCError(getBalanceByAddressResponse.Error)
}
return getBalanceByAddressResponse, nil
}