/
wallet.go
126 lines (112 loc) · 3.61 KB
/
wallet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package user
import (
"context"
"fmt"
"math/big"
userPb "github.com/textileio/powergate/v2/api/gen/powergate/user/v1"
"github.com/textileio/powergate/v2/ffs/api"
"github.com/textileio/powergate/v2/wallet"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Balance returns the balance for an address.
func (s *Service) Balance(ctx context.Context, req *userPb.BalanceRequest) (*userPb.BalanceResponse, error) {
bal, err := s.w.Balance(ctx, req.Address)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting balance: %v", err)
}
return &userPb.BalanceResponse{Balance: bal.String()}, nil
}
// NewAddress calls ffs.NewAddr.
func (s *Service) NewAddress(ctx context.Context, req *userPb.NewAddressRequest) (*userPb.NewAddressResponse, error) {
i, err := s.getInstanceByToken(ctx)
if err != nil {
return nil, err
}
var opts []api.NewAddressOption
if req.AddressType != "" {
opts = append(opts, api.WithAddressType(req.AddressType))
}
if req.MakeDefault {
opts = append(opts, api.WithMakeDefault(req.MakeDefault))
}
addr, err := i.NewAddr(ctx, req.Name, opts...)
if err != nil {
return nil, err
}
return &userPb.NewAddressResponse{Address: addr}, nil
}
// Addresses calls ffs.Addrs.
func (s *Service) Addresses(ctx context.Context, req *userPb.AddressesRequest) (*userPb.AddressesResponse, error) {
i, err := s.getInstanceByToken(ctx)
if err != nil {
return nil, err
}
addrs := i.Addrs()
res := make([]*userPb.AddrInfo, len(addrs))
for i, addr := range addrs {
bal, err := s.w.Balance(ctx, addr.Addr)
if err != nil {
return nil, status.Errorf(codes.Internal, "getting address balance: %v", err)
}
ai := &userPb.AddrInfo{
Name: addr.Name,
Address: addr.Addr,
Type: addr.Type,
Balance: bal.String(),
}
vc, err := s.w.GetVerifiedClientInfo(ctx, addr.Addr)
if err != nil && err != wallet.ErrNoVerifiedClient {
return nil, status.Errorf(codes.Internal, "getting verified-client wallet address information: %s", err)
}
if err == nil {
ai.VerifiedClientInfo = &userPb.AddrInfo_VerifiedClientInfo{
RemainingDatacapBytes: vc.RemainingDatacapBytes.String(),
}
}
res[i] = ai
}
return &userPb.AddressesResponse{Addresses: res}, nil
}
// SendFil sends fil from a managed address to any other address.
func (s *Service) SendFil(ctx context.Context, req *userPb.SendFilRequest) (*userPb.SendFilResponse, error) {
i, err := s.getInstanceByToken(ctx)
if err != nil {
return nil, err
}
amt, ok := new(big.Int).SetString(req.Amount, 10)
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "parsing amount %v", req.Amount)
}
cid, err := i.SendFil(ctx, req.From, req.To, amt)
if err != nil {
return nil, err
}
return &userPb.SendFilResponse{
Cid: cid.String(),
}, nil
}
// SignMessage calls ffs.SignMessage.
func (s *Service) SignMessage(ctx context.Context, req *userPb.SignMessageRequest) (*userPb.SignMessageResponse, error) {
i, err := s.getInstanceByToken(ctx)
if err != nil {
return nil, err
}
signature, err := i.SignMessage(ctx, req.Address, req.Message)
if err != nil {
return nil, fmt.Errorf("signing message: %s", err)
}
return &userPb.SignMessageResponse{Signature: signature}, nil
}
// VerifyMessage calls ffs.VerifyMessage.
func (s *Service) VerifyMessage(ctx context.Context, req *userPb.VerifyMessageRequest) (*userPb.VerifyMessageResponse, error) {
i, err := s.getInstanceByToken(ctx)
if err != nil {
return nil, err
}
ok, err := i.VerifyMessage(ctx, req.Address, req.Message, req.Signature)
if err != nil {
return nil, fmt.Errorf("verifying signature: %s", err)
}
return &userPb.VerifyMessageResponse{Ok: ok}, nil
}