-
Notifications
You must be signed in to change notification settings - Fork 175
/
emulator_client.go
125 lines (98 loc) · 3.24 KB
/
emulator_client.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
package module
import (
"context"
"fmt"
"google.golang.org/grpc"
"github.com/onflow/cadence"
jsoncdc "github.com/onflow/cadence/encoding/json"
emulator "github.com/onflow/flow-emulator"
sdk "github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go/model/flow"
)
// EmulatorClient is a wrapper around the emulator to implement the same interface
// used by the SDK client. Used for testing against the emulator.
type EmulatorClient struct {
blockchain *emulator.Blockchain
}
func NewEmulatorClient(blockchain *emulator.Blockchain) *EmulatorClient {
client := &EmulatorClient{
blockchain: blockchain,
}
return client
}
func (c *EmulatorClient) GetAccount(ctx context.Context, address sdk.Address, opts ...grpc.CallOption) (*sdk.Account, error) {
return c.blockchain.GetAccount(address)
}
func (c *EmulatorClient) GetAccountAtLatestBlock(ctx context.Context, address sdk.Address, opts ...grpc.CallOption) (*sdk.Account, error) {
return c.blockchain.GetAccount(address)
}
func (c *EmulatorClient) SendTransaction(ctx context.Context, tx sdk.Transaction, opts ...grpc.CallOption) error {
_, err := c.Submit(&tx)
return err
}
func (c *EmulatorClient) GetLatestBlock(ctx context.Context, isSealed bool, opts ...grpc.CallOption) (*sdk.Block, error) {
block, err := c.blockchain.GetLatestBlock()
if err != nil {
return nil, err
}
blockID := block.ID()
var id sdk.Identifier
copy(id[:], blockID[:])
sdkBlock := &sdk.Block{
BlockHeader: sdk.BlockHeader{ID: id},
}
return sdkBlock, nil
}
func (c *EmulatorClient) GetTransactionResult(ctx context.Context, txID sdk.Identifier, opts ...grpc.CallOption) (*sdk.TransactionResult, error) {
return c.blockchain.GetTransactionResult(txID)
}
func (c *EmulatorClient) ExecuteScriptAtLatestBlock(ctx context.Context, script []byte, args []cadence.Value, opts ...grpc.CallOption) (cadence.Value, error) {
arguments := [][]byte{}
for _, arg := range args {
val, err := jsoncdc.Encode(arg)
if err != nil {
return nil, fmt.Errorf("could not encode arguments: %w", err)
}
arguments = append(arguments, val)
}
scriptResult, err := c.blockchain.ExecuteScript(script, arguments)
if err != nil {
return nil, err
}
return scriptResult.Value, nil
}
func (c *EmulatorClient) ExecuteScriptAtBlockID(ctx context.Context, blockID sdk.Identifier, script []byte, args []cadence.Value, opts ...grpc.CallOption) (cadence.Value, error) {
arguments := [][]byte{}
for _, arg := range args {
val, err := jsoncdc.Encode(arg)
if err != nil {
return nil, fmt.Errorf("could not encode arguments: %w", err)
}
arguments = append(arguments, val)
}
// get block by ID
block, err := c.blockchain.GetBlockByID(blockID)
if err != nil {
return nil, err
}
scriptResult, err := c.blockchain.ExecuteScriptAtBlock(script, arguments, block.Header.Height)
if err != nil {
return nil, err
}
if scriptResult.Error != nil {
return nil, fmt.Errorf("error in script: %w", scriptResult.Error)
}
return scriptResult.Value, nil
}
func (c *EmulatorClient) Submit(tx *sdk.Transaction) (*flow.Block, error) {
// submit the signed transaction
err := c.blockchain.AddTransaction(*tx)
if err != nil {
return nil, err
}
block, _, err := c.blockchain.ExecuteAndCommitBlock()
if err != nil {
return nil, err
}
return block, nil
}