nockchain-grpc/wallet/nockchain_service.go
2025-10-06 13:38:53 +07:00

116 lines
2.8 KiB
Go

package wallet
import (
context "context"
"fmt"
"github.com/phamminh0811/private-grpc/nockchain"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
type NockchainClient struct {
conn *grpc.ClientConn
client nockchain.NockchainServiceClient
}
// NewNockchainClient creates a new gRPC client connection
func NewNockchainClient(address string) (*NockchainClient, error) {
creds := credentials.NewClientTLSFromCert(nil, "")
conn, err := grpc.NewClient(
address,
grpc.WithTransportCredentials(creds),
)
if err != nil {
return nil, fmt.Errorf("failed to connect: %w", err)
}
client := nockchain.NewNockchainServiceClient(conn)
return &NockchainClient{
conn: conn,
client: client,
}, nil
}
func (nc *NockchainClient) Close() error {
return nc.conn.Close()
}
func (nc *NockchainClient) WalletGetBalance(address string) (*nockchain.WalletBalanceData, error) {
pageToken := ""
allNotes := []*nockchain.BalanceEntry{}
var height *nockchain.BlockHeight
var blockId *nockchain.Hash
for {
req := nockchain.WalletGetBalanceRequest{
Address: address,
Page: &nockchain.PageRequest{
ClientPageItemsLimit: 0,
PageToken: pageToken,
MaxBytes: 0,
},
}
resp, err := nc.client.WalletGetBalance(context.Background(), &req)
if err != nil {
return nil, err
}
balance := nockchain.WalletBalanceData{}
switch resp.Result.(type) {
case *nockchain.WalletGetBalanceResponse_Balance:
balance = *resp.GetBalance()
case *nockchain.WalletGetBalanceResponse_Error:
return nil, fmt.Errorf("error: %s", resp.GetError().Message)
default:
return nil, fmt.Errorf("invalid result type")
}
if height == nil {
height = balance.Height
blockId = balance.BlockId
}
if balance.Height != height || balance.BlockId != blockId {
return nil, fmt.Errorf("snapshot changed during pagination; retry")
}
allNotes = append(allNotes, balance.Notes...)
if balance.Page.NextPageToken == "" {
break
} else {
pageToken = balance.Page.NextPageToken
}
}
return &nockchain.WalletBalanceData{
Notes: allNotes,
Height: height,
BlockId: blockId,
Page: &nockchain.PageResponse{
NextPageToken: "",
},
}, nil
}
func (nc *NockchainClient) TxAccepted(txId string) (*nockchain.TransactionAcceptedResponse, error) {
req := nockchain.TransactionAcceptedRequest{
TxId: &nockchain.Base58Hash{
Hash: txId,
},
}
resp, err := nc.client.TransactionAccepted(context.Background(), &req)
if err != nil {
return nil, err
}
switch resp.Result.(type) {
case *nockchain.TransactionAcceptedResponse_Accepted:
return resp, nil
case *nockchain.TransactionAcceptedResponse_Error:
return nil, fmt.Errorf("error: %s", resp.GetError().Message)
default:
return nil, fmt.Errorf("invalid result type")
}
}