Skip to content

Commit 0fd849d

Browse files
authored
Merge branch 'master' into khalil/1659-secure-grpc-support
2 parents 6c4aa75 + 18e4dbe commit 0fd849d

11 files changed

Lines changed: 271 additions & 60 deletions

File tree

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ go 1.13
44

55
require (
66
github.com/a8m/envsubst v1.2.0
7+
github.com/getsentry/sentry-go v0.12.0
78
github.com/go-git/go-git/v5 v5.4.2
89
github.com/gosuri/uilive v0.0.4
910
github.com/joho/godotenv v1.4.0
1011
github.com/manifoldco/promptui v0.9.0
1112
github.com/onflow/cadence v0.20.2
12-
github.com/onflow/cadence/languageserver v0.18.3-0.20211005105715-3c618f0fcd10
13+
github.com/onflow/cadence/languageserver v0.18.3-0.20220126162456-79571a12b7ff
1314
github.com/onflow/flow-core-contracts/lib/go/templates v0.7.9
1415
github.com/onflow/flow-emulator v0.27.3
1516
github.com/onflow/flow-go v0.23.4

go.sum

Lines changed: 102 additions & 3 deletions
Large diffs are not rendered by default.

internal/accounts/create.go

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ type flagsCreate struct {
3636
Signer string `default:"emulator-account" flag:"signer" info:"Account name from configuration used to sign the transaction"`
3737
Keys []string `flag:"key" info:"Public keys to attach to account"`
3838
Weights []int `flag:"key-weight" info:"Weight for the key"`
39-
SigAlgo string `default:"ECDSA_P256" flag:"sig-algo" info:"Signature algorithm used to generate the keys"`
40-
HashAlgo string `default:"SHA3_256" flag:"hash-algo" info:"Hash used for the digest"`
39+
SigAlgo []string `default:"ECDSA_P256" flag:"sig-algo" info:"Signature algorithm used to generate the keys"`
40+
HashAlgo []string `default:"SHA3_256" flag:"hash-algo" info:"Hash used for the digest"`
4141
Contracts []string `flag:"contract" info:"Contract to be deployed during account creation. <name:filename>"`
4242
Include []string `default:"" flag:"include" info:"Fields to include in the output"`
4343
}
@@ -66,23 +66,50 @@ func create(
6666
return nil, err
6767
}
6868

69-
sigAlgo := crypto.StringToSignatureAlgorithm(createFlags.SigAlgo)
70-
if sigAlgo == crypto.UnknownSignatureAlgorithm {
71-
return nil, fmt.Errorf("invalid signature algorithm: %s", createFlags.SigAlgo)
69+
if len(createFlags.SigAlgo) == 1 && len(createFlags.HashAlgo) == 1 {
70+
// Fill up depending on size of key input
71+
if len(createFlags.Keys) > 1 {
72+
for i := 1; i < len(createFlags.Keys); i++ {
73+
createFlags.SigAlgo = append(createFlags.SigAlgo, createFlags.SigAlgo[0])
74+
createFlags.HashAlgo = append(createFlags.HashAlgo, createFlags.HashAlgo[0])
75+
}
76+
// Deprecated usage message?
77+
}
78+
79+
} else
80+
// double check matching array lengths on inputs
81+
if len(createFlags.Keys) != len(createFlags.SigAlgo) || len(createFlags.SigAlgo) != len(createFlags.HashAlgo) {
82+
return nil, fmt.Errorf("must provide a signature and hash algorithm for every key provided to --key: %d keys, %d signature algo, %d hash algo", len(createFlags.Keys), len(createFlags.SigAlgo), len(createFlags.HashAlgo))
7283
}
7384

74-
hashAlgo := crypto.StringToHashAlgorithm(createFlags.HashAlgo)
75-
if hashAlgo == crypto.UnknownHashAlgorithm {
76-
return nil, fmt.Errorf("invalid hash algorithm: %s", createFlags.HashAlgo)
85+
// read all signature algorithms
86+
sigAlgos := make([]crypto.SignatureAlgorithm, 0, len(createFlags.SigAlgo))
87+
for _, sigAlgoStr := range createFlags.SigAlgo {
88+
sigAlgo := crypto.StringToSignatureAlgorithm(sigAlgoStr)
89+
if sigAlgo == crypto.UnknownSignatureAlgorithm {
90+
return nil, fmt.Errorf("invalid signature algorithm: %s", createFlags.SigAlgo)
91+
}
92+
sigAlgos = append(sigAlgos, sigAlgo)
93+
}
94+
95+
// read all hash algorithms
96+
hashAlgos := make([]crypto.HashAlgorithm, 0, len(createFlags.HashAlgo))
97+
for _, hashAlgoStr := range createFlags.HashAlgo {
98+
99+
hashAlgo := crypto.StringToHashAlgorithm(hashAlgoStr)
100+
if hashAlgo == crypto.UnknownHashAlgorithm {
101+
return nil, fmt.Errorf("invalid hash algorithm: %s", createFlags.HashAlgo)
102+
}
103+
hashAlgos = append(hashAlgos, hashAlgo)
77104
}
78105

79106
keyWeights := createFlags.Weights
80107

81108
// decode public keys
82-
var pubKeys []crypto.PublicKey
83-
for _, k := range createFlags.Keys {
109+
pubKeys := make([]crypto.PublicKey, 0, len(createFlags.Keys))
110+
for i, k := range createFlags.Keys {
84111
k = strings.TrimPrefix(k, "0x") // clear possible prefix
85-
key, err := crypto.DecodePublicKeyHex(sigAlgo, k)
112+
key, err := crypto.DecodePublicKeyHex(sigAlgos[i], k)
86113
if err != nil {
87114
return nil, fmt.Errorf("failed decoding public key: %s with error: %w", key, err)
88115
}
@@ -93,8 +120,8 @@ func create(
93120
signer,
94121
pubKeys,
95122
keyWeights,
96-
sigAlgo,
97-
hashAlgo,
123+
sigAlgos,
124+
hashAlgos,
98125
createFlags.Contracts,
99126
)
100127

internal/command/command.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import (
3636
"github.com/onflow/flow-cli/pkg/flowkit/services"
3737
"github.com/onflow/flow-cli/pkg/flowkit/util"
3838

39+
"github.com/getsentry/sentry-go"
40+
"github.com/spf13/afero"
3941
"github.com/spf13/cobra"
4042
)
4143

@@ -81,7 +83,13 @@ const (
8183
// here we can do all boilerplate code that is else copied in each command and make sure
8284
// we have one place to handle all errors and ensure commands have consistent results.
8385
func (c Command) AddToParent(parent *cobra.Command) {
86+
// initialize crash reporting for the CLI
87+
initCrashReporting()
88+
8489
c.Cmd.Run = func(cmd *cobra.Command, args []string) {
90+
defer sentry.Flush(2 * time.Second)
91+
defer sentry.Recover()
92+
8593
// initialize file loader used in commands
8694
loader := &afero.Afero{Fs: afero.NewOsFs()}
8795

@@ -189,7 +197,6 @@ func resolveHost(state *flowkit.State, hostFlag, networkKeyFlag, networkFlag str
189197
}
190198

191199
return network.Host, network.Key, nil
192-
193200
}
194201

195202
// create logger utility.
@@ -247,3 +254,29 @@ func checkVersion(logger output.Logger) {
247254
))
248255
}
249256
}
257+
258+
// initCrashReporting set-ups sentry as crash reporting tool, it also sets listener for panics
259+
// and asks before sending the error for a permission to do so from the user.
260+
func initCrashReporting() {
261+
currentVersion := build.Semver()
262+
263+
err := sentry.Init(sentry.ClientOptions{
264+
Dsn: "https://a3d7d72b79ff49ce808e241ccc5bf111@o1129322.ingest.sentry.io/6173086",
265+
Environment: "Dev",
266+
Release: currentVersion,
267+
AttachStacktrace: true,
268+
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
269+
// ask for crash report permission
270+
fmt.Printf("\n%s Crash detected! %s\n\n", output.ErrorEmoji(), event.Message)
271+
272+
if output.ReportCrash() {
273+
return event
274+
}
275+
276+
return nil
277+
},
278+
})
279+
if err != nil {
280+
fmt.Println(err) // safest output method at this point
281+
}
282+
}

internal/keys/keys.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import (
3232
"github.com/onflow/flow-cli/pkg/flowkit/util"
3333
)
3434

35+
const faucetHost = "https://testnet-faucet.onflow.org/"
36+
3537
var Cmd = &cobra.Command{
3638
Use: "keys",
3739
Short: "Utilities to manage keys",
@@ -65,6 +67,18 @@ func (k *KeyResult) String() string {
6567
writer := util.CreateTabWriter(&b)
6668

6769
if k.privateKey != nil {
70+
// build the faucet link
71+
link := fmt.Sprintf("%s?key=%x", faucetHost, k.publicKey.Encode())
72+
if k.privateKey.Algorithm() != crypto.ECDSA_P256 {
73+
link = fmt.Sprintf("%s&sig-algo=%s", link, k.privateKey.Algorithm().String())
74+
}
75+
76+
fmt.Printf(
77+
"%s If you want to create an account on testnet with the generated keys use this link:\n%s \n\n",
78+
output.TryEmoji(),
79+
link,
80+
)
81+
6882
_, _ = fmt.Fprintf(writer, "%s Store private key safely and don't share with anyone! \n", output.StopEmoji())
6983
_, _ = fmt.Fprintf(writer, "Private Key \t %x \n", k.privateKey.Encode())
7084
}

pkg/flowkit/output/prompt.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,13 @@ func RemoveNetworkPrompt(networks config.Networks) string {
497497

498498
return name
499499
}
500+
501+
func ReportCrash() bool {
502+
prompt := promptui.Select{
503+
Label: "🙏 Please report the crash so we can improve the CLI. Do you want to report it?",
504+
Items: []string{"Yes, report the crash", "No"},
505+
}
506+
chosen, _, _ := prompt.Run()
507+
508+
return chosen == 0
509+
}

pkg/flowkit/services/accounts.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ func (a *Accounts) Create(
178178
signer *flowkit.Account,
179179
pubKeys []crypto.PublicKey,
180180
keyWeights []int,
181-
sigAlgo crypto.SignatureAlgorithm,
182-
hashAlgo crypto.HashAlgorithm,
181+
sigAlgo []crypto.SignatureAlgorithm,
182+
hashAlgo []crypto.HashAlgorithm,
183183
contractArgs []string,
184184
) (*flow.Account, error) {
185185
if a.state == nil {
@@ -204,8 +204,8 @@ func (a *Accounts) Create(
204204

205205
accKey := &flow.AccountKey{
206206
PublicKey: pubKey,
207-
SigAlgo: sigAlgo,
208-
HashAlgo: hashAlgo,
207+
SigAlgo: sigAlgo[i],
208+
HashAlgo: hashAlgo[i],
209209
Weight: weight,
210210
}
211211

pkg/flowkit/services/accounts_test.go

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ func TestAccounts(t *testing.T) {
9898
serviceAcc,
9999
[]crypto.PublicKey{pubKey},
100100
[]int{1000},
101-
crypto.ECDSA_P256,
102-
crypto.SHA3_256,
101+
[]crypto.SignatureAlgorithm{crypto.ECDSA_P256},
102+
[]crypto.HashAlgorithm{crypto.SHA3_256},
103103
nil,
104104
)
105105

@@ -134,8 +134,8 @@ func TestAccounts(t *testing.T) {
134134
serviceAcc,
135135
[]crypto.PublicKey{pubKey},
136136
[]int{1000},
137-
crypto.ECDSA_P256,
138-
crypto.SHA3_256,
137+
[]crypto.SignatureAlgorithm{crypto.ECDSA_P256},
138+
[]crypto.HashAlgorithm{crypto.SHA3_256},
139139
[]string{"Hello:contractHello.cdc"},
140140
)
141141

@@ -296,8 +296,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
296296
account *flowkit.Account
297297
pubKeys []crypto.PublicKey
298298
weights []int
299-
sigAlgo crypto.SignatureAlgorithm
300-
hashAlgo crypto.HashAlgorithm
299+
sigAlgo []crypto.SignatureAlgorithm
300+
hashAlgo []crypto.HashAlgorithm
301301
args []string
302302
}
303303

@@ -316,19 +316,29 @@ func TestAccountsCreate_Integration(t *testing.T) {
316316
srvAcc, _ := state.EmulatorServiceAccount()
317317

318318
accIn := []accountsIn{{
319-
account: srvAcc,
320-
sigAlgo: crypto.ECDSA_P256,
321-
hashAlgo: crypto.SHA3_256,
322-
args: nil,
319+
account: srvAcc,
320+
sigAlgo: []crypto.SignatureAlgorithm{
321+
tests.SigAlgos()[0],
322+
},
323+
hashAlgo: []crypto.HashAlgorithm{
324+
tests.HashAlgos()[0],
325+
},
326+
args: nil,
323327
pubKeys: []crypto.PublicKey{
324328
tests.PubKeys()[0],
325329
},
326330
weights: []int{flow.AccountKeyWeightThreshold},
327331
}, {
328-
account: srvAcc,
329-
args: nil,
330-
sigAlgo: crypto.ECDSA_P256,
331-
hashAlgo: crypto.SHA3_256,
332+
account: srvAcc,
333+
args: nil,
334+
sigAlgo: []crypto.SignatureAlgorithm{
335+
tests.SigAlgos()[0],
336+
tests.SigAlgos()[1],
337+
},
338+
hashAlgo: []crypto.HashAlgorithm{
339+
tests.HashAlgos()[0],
340+
tests.HashAlgos()[1],
341+
},
332342
pubKeys: []crypto.PublicKey{
333343
tests.PubKeys()[0],
334344
tests.PubKeys()[1],
@@ -342,8 +352,12 @@ func TestAccountsCreate_Integration(t *testing.T) {
342352
tests.ContractSimple.Filename,
343353
),
344354
},
345-
sigAlgo: crypto.ECDSA_P256,
346-
hashAlgo: crypto.SHA3_256,
355+
sigAlgo: []crypto.SignatureAlgorithm{
356+
tests.SigAlgos()[0],
357+
},
358+
hashAlgo: []crypto.HashAlgorithm{
359+
tests.HashAlgos()[0],
360+
},
347361
pubKeys: []crypto.PublicKey{
348362
tests.PubKeys()[0],
349363
},
@@ -393,8 +407,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
393407
for x, k := range acc.Keys {
394408
assert.Equal(t, k.PublicKey, a.pubKeys[x])
395409
assert.Equal(t, k.Weight, c.weights[x])
396-
assert.Equal(t, k.SigAlgo, a.sigAlgo)
397-
assert.Equal(t, k.HashAlgo, a.hashAlgo)
410+
assert.Equal(t, k.SigAlgo, a.sigAlgo[x])
411+
assert.Equal(t, k.HashAlgo, a.hashAlgo[x])
398412
}
399413

400414
}
@@ -418,35 +432,35 @@ func TestAccountsCreate_Integration(t *testing.T) {
418432
accIn := []accountsIn{
419433
{
420434
account: srvAcc,
421-
sigAlgo: crypto.ECDSA_P256,
422-
hashAlgo: crypto.SHA3_256,
435+
sigAlgo: []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
436+
hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
423437
args: []string{"Invalid:Invalid"},
424438
pubKeys: []crypto.PublicKey{
425439
tests.PubKeys()[0],
426440
},
427441
weights: []int{1000},
428442
}, {
429443
account: srvAcc,
430-
sigAlgo: crypto.UnknownSignatureAlgorithm,
431-
hashAlgo: crypto.SHA3_256,
444+
sigAlgo: []crypto.SignatureAlgorithm{crypto.UnknownSignatureAlgorithm},
445+
hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
432446
args: nil,
433447
pubKeys: []crypto.PublicKey{
434448
tests.PubKeys()[0],
435449
},
436450
weights: []int{1000},
437451
}, {
438452
account: srvAcc,
439-
sigAlgo: crypto.UnknownSignatureAlgorithm,
440-
hashAlgo: crypto.UnknownHashAlgorithm,
453+
sigAlgo: []crypto.SignatureAlgorithm{crypto.UnknownSignatureAlgorithm},
454+
hashAlgo: []crypto.HashAlgorithm{crypto.UnknownHashAlgorithm},
441455
args: nil,
442456
pubKeys: []crypto.PublicKey{
443457
tests.PubKeys()[0],
444458
},
445459
weights: []int{1000},
446460
}, {
447461
account: srvAcc,
448-
sigAlgo: crypto.ECDSA_P256,
449-
hashAlgo: crypto.SHA3_256,
462+
sigAlgo: []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
463+
hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
450464
args: nil,
451465
pubKeys: []crypto.PublicKey{
452466
tests.PubKeys()[0],
@@ -455,8 +469,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
455469
weights: []int{1000},
456470
}, {
457471
account: srvAcc,
458-
sigAlgo: crypto.ECDSA_P256,
459-
hashAlgo: crypto.SHA3_256,
472+
sigAlgo: []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
473+
hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
460474
args: nil,
461475
pubKeys: []crypto.PublicKey{
462476
tests.PubKeys()[0],

pkg/flowkit/services/blocks_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"testing"
2323

2424
"github.com/onflow/flow-go-sdk"
25-
"github.com/onflow/flow-go-sdk/crypto"
2625
"github.com/stretchr/testify/assert"
2726

2827
"github.com/onflow/flow-cli/tests"
@@ -108,7 +107,7 @@ func TestBlocksGet_Integration(t *testing.T) {
108107
assert.Equal(t, block.ID.String(), "7bc42fe85d32ca513769a74f97f7e1a7bad6c9407f0d934c2aa645ef9cf613c7")
109108

110109
// create an event
111-
_, _ = s.Accounts.Create(srvAcc, tests.PubKeys(), nil, crypto.ECDSA_P256, crypto.SHA3_256, nil)
110+
_, _ = s.Accounts.Create(srvAcc, tests.PubKeys(), nil, tests.SigAlgos(), tests.HashAlgos(), nil)
112111

113112
block, blockEvents, _, err = s.Blocks.GetBlock("latest", "flow.AccountCreated", true)
114113

0 commit comments

Comments
 (0)