-
Notifications
You must be signed in to change notification settings - Fork 19
/
api.go
135 lines (115 loc) · 6.23 KB
/
api.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
127
128
129
130
131
132
133
134
135
package api
import (
"context"
"time"
"code.vegaprotocol.io/vega/libs/jsonrpc"
apipb "code.vegaprotocol.io/vega/protos/vega/api/v1"
commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
"code.vegaprotocol.io/vega/wallet/wallet"
"go.uber.org/zap"
)
// WalletStore is the component used to retrieve and update wallets from the
// computer.
//go:generate go run github.com/golang/mock/mockgen -destination mocks/wallet_store_mock.go -package mocks code.vegaprotocol.io/vega/wallet/api WalletStore
type WalletStore interface {
WalletExists(ctx context.Context, name string) (bool, error)
GetWallet(ctx context.Context, name, passphrase string) (wallet.Wallet, error)
ListWallets(ctx context.Context) ([]string, error)
SaveWallet(ctx context.Context, w wallet.Wallet, passphrase string) error
}
// Node is the component used to get network information and send transactions.
//go:generate go run github.com/golang/mock/mockgen -destination mocks/node_mock.go -package mocks code.vegaprotocol.io/vega/wallet/api Node
type Node interface {
Host() string
Stop() error
SendTransaction(context.Context, *commandspb.Transaction, apipb.SubmitTransactionRequest_Type) (string, error)
CheckTransaction(context.Context, *commandspb.Transaction) (*apipb.CheckTransactionResponse, error)
HealthCheck(context.Context) error
LastBlock(context.Context) (*apipb.LastBlockHeightResponse, error)
}
// NodeSelector implementing the strategy for node selection.
//go:generate go run github.com/golang/mock/mockgen -destination mocks/node_selector_mock.go -package mocks code.vegaprotocol.io/vega/wallet/api NodeSelector
type NodeSelector interface {
Node(ctx context.Context) (Node, error)
Stop()
}
// Pipeline is the component connecting the client front-end and the JSON-RPC API.
// Convention:
// - Notify* functions do not expect a response.
// - Request* functions are expecting a client intervention.
//go:generate go run github.com/golang/mock/mockgen -destination mocks/pipeline_mock.go -package mocks code.vegaprotocol.io/vega/wallet/api Pipeline
type Pipeline interface {
// NotifyError is used to report errors to the client.
NotifyError(ctx context.Context, traceID string, t ErrorType, err error)
// RequestWalletConnectionReview is used to trigger a client review of
// the wallet connection requested by the specified hostname.
// It returns true if the client approved the wallet connection, false
// otherwise.
RequestWalletConnectionReview(ctx context.Context, traceID, hostname string) (bool, error)
// NotifySuccessfulRequest is used to notify the client the request is
// successful.
NotifySuccessfulRequest(ctx context.Context, traceID string)
// RequestWalletSelection is used to trigger selection of the wallet the
// client wants to use for the specified hostname.
RequestWalletSelection(ctx context.Context, traceID, hostname string, availableWallets []string) (SelectedWallet, error)
// RequestPassphrase is used to request the client to enter the passphrase of
// the wallet. It's primarily used for request that requires saving changes
// on it.
RequestPassphrase(ctx context.Context, traceID, wallet string) (string, error)
// RequestPermissionsReview is used to trigger a client review of the permissions
// requested by the specified hostname.
// It returns true if the client approved the requested permissions, false
// otherwise.
RequestPermissionsReview(ctx context.Context, traceID, hostname, wallet string, perms map[string]string) (bool, error)
// RequestTransactionReview is used to trigger a client review of the
// transaction a third-party application wants to send.
// It returns true if the client approved the sending of the transaction,
// false otherwise.
RequestTransactionReview(ctx context.Context, traceID, hostname, wallet, pubKey, transaction string, receivedAt time.Time) (bool, error)
// NotifyTransactionStatus is used to report the transaction status once
// sent.
NotifyTransactionStatus(ctx context.Context, traceID, txHash, tx string, err error, sentAt time.Time)
}
// ErrorType defines the type of error that is sent to the client, for fine
// grain error management and reporting.
type ErrorType string
var (
// InternalError defines an unexpected technical error upon which the client
// can't act.
// The client front-end should report it to the client and automatically
// abort the processing of the ongoing request.
// It can be raised if a file is not accessible or corrupt, for example.
InternalError ErrorType = "Internal Error"
// ServerError defines a programmatic error threw by the server, such as
// a request cancellation.
// It's a type of error that should be expected and handled.
ServerError ErrorType = "Server Error"
// NetworkError defines an error that comes from the network and its nodes.
NetworkError ErrorType = "Network Error"
// ClientError defines an error that originated from the client and that
// requires its intervention to correct it.
// It can be raised if a passphrase is invalid, for example.
ClientError ErrorType = "Client Error"
)
// SelectedWallet holds the result of the wallet selection from the client.
type SelectedWallet struct {
Wallet string `json:"wallet"`
Passphrase string `json:"passphrase"`
}
// RestrictedAPI builds a JSON-RPC API of the wallet with a subset of the requests
// that are intended to be exposed to external services, such as bots, apps,
// scripts.
// The reason is that we don't want external clients to be able to call
// administration capabilities that should only be exposed to the user.
func RestrictedAPI(log *zap.Logger, walletStore WalletStore, pipeline Pipeline, nodeSelector NodeSelector) (*jsonrpc.API, error) {
sessions := NewSessions()
walletAPI := jsonrpc.New(log)
walletAPI.RegisterMethod("connect_wallet", NewConnectWallet(walletStore, pipeline, sessions))
walletAPI.RegisterMethod("disconnect_wallet", NewDisconnectWallet(sessions))
walletAPI.RegisterMethod("get_permissions", NewGetPermissions(sessions))
walletAPI.RegisterMethod("request_permissions", NewRequestPermissions(walletStore, pipeline, sessions))
walletAPI.RegisterMethod("list_keys", NewListKeys(sessions))
walletAPI.RegisterMethod("send_transaction", NewSendTransaction(pipeline, nodeSelector, sessions))
log.Info("restricted JSON-RPC API initialised")
return walletAPI, nil
}