@@ -19,12 +19,12 @@ package signature
1919import (
2020 "encoding/hex"
2121 "fmt"
22- "log "
22+ "os "
2323 "os/exec"
24+ "regexp"
2425 "strings"
2526)
2627
27- // const subkeyCmd = "/Users/philipstanislaus/go/src/github.com/paritytech/substrate/target/debug/subkey"
2828const subkeyCmd = "subkey"
2929
3030type KeyringPair struct {
@@ -36,6 +36,46 @@ type KeyringPair struct {
3636 PublicKey []byte
3737}
3838
39+ var rePubKey = regexp .MustCompile (`Public key \(hex\): 0x([a-f0-9]*)\n` )
40+ var reAddress = regexp .MustCompile (`Address \(SS58\): ([a-zA-Z0-9]*)\n` )
41+
42+ func KeyringPairFromSecret (seedOrPhrase string ) (KeyringPair , error ) {
43+ // use "subkey" command for creation of public key and address
44+ cmd := exec .Command (subkeyCmd , "inspect" , seedOrPhrase )
45+
46+ // execute the command, get the output
47+ out , err := cmd .Output ()
48+ if err != nil {
49+ return KeyringPair {}, fmt .Errorf ("failed to generate keyring pair from secret: %v" , err .Error ())
50+ }
51+
52+ if string (out ) == "Invalid phrase/URI given" {
53+ return KeyringPair {}, fmt .Errorf ("failed to generate keyring pair from secret: invalid phrase/URI given" )
54+ }
55+
56+ // find the pub key
57+ resPk := rePubKey .FindStringSubmatch (string (out ))
58+ if len (resPk ) != 2 {
59+ return KeyringPair {}, fmt .Errorf ("failed to generate keyring pair from secret, pubkey not found in output: %v" , resPk )
60+ }
61+ pk , err := hex .DecodeString (string (resPk [1 ]))
62+ if err != nil {
63+ return KeyringPair {}, fmt .Errorf ("failed to generate keyring pair from secret, could not hex decode pubkey: %v" , string (resPk [1 ]))
64+ }
65+
66+ // find the address
67+ addr := reAddress .FindStringSubmatch (string (out ))
68+ if len (addr ) != 2 {
69+ return KeyringPair {}, fmt .Errorf ("failed to generate keyring pair from secret, address not found in output: %v" , addr )
70+ }
71+
72+ return KeyringPair {
73+ URI : seedOrPhrase ,
74+ Address : addr [1 ],
75+ PublicKey : pk ,
76+ }, nil
77+ }
78+
3979var TestKeyringPairAlice = KeyringPair {
4080 URI : "//Alice" ,
4181 PublicKey : []byte {0xd4 , 0x35 , 0x93 , 0xc7 , 0x15 , 0xfd , 0xd3 , 0x1c , 0x61 , 0x14 , 0x1a , 0xbd , 0x4 , 0xa9 , 0x9f , 0xd6 , 0x82 , 0x2c , 0x85 , 0x58 , 0x85 , 0x4c , 0xcd , 0xe3 , 0x9a , 0x56 , 0x84 , 0xe7 , 0xa5 , 0x6d , 0xa2 , 0x7d }, //nolint:lll
@@ -52,7 +92,7 @@ func Sign(data []byte, privateKeyURI string) ([]byte, error) {
5292 dataHex := hex .EncodeToString (data )
5393 cmd .Stdin = strings .NewReader (dataHex )
5494
55- log .Printf ("echo -n \" %v\" | %v sign %v --hex" , dataHex , subkeyCmd , privateKeyURI )
95+ // log.Printf("echo -n \"%v\" | %v sign %v --hex", dataHex, subkeyCmd, privateKeyURI)
5696
5797 // execute the command, get the output
5898 out , err := cmd .Output ()
@@ -85,12 +125,12 @@ func Verify(data []byte, sig []byte, privateKeyURI string) (bool, error) {
85125 dataHex := hex .EncodeToString (data )
86126 cmd .Stdin = strings .NewReader (dataHex )
87127
88- log .Printf ("echo -n \" %v\" | %v verify %v %v --hex" , dataHex , subkeyCmd , sigHex , privateKeyURI )
128+ // log.Printf("echo -n \"%v\" | %v verify %v %v --hex", dataHex, subkeyCmd, sigHex, privateKeyURI)
89129
90130 // execute the command, get the output
91131 out , err := cmd .Output ()
92132 if err != nil {
93- log . Fatal ( "Failed to verify with subkey" , err .Error ())
133+ return false , fmt . Errorf ( "failed to verify with subkey: %v " , err .Error ())
94134 }
95135
96136 // remove line feed
@@ -102,3 +142,18 @@ func Verify(data []byte, sig []byte, privateKeyURI string) (bool, error) {
102142 valid := outStr == "Signature verifies correctly."
103143 return valid , nil
104144}
145+
146+ // LoadKeyringPairFromEnv looks up whether the env variable TEST_PRIV_KEY is set and is not empty and tries to use its
147+ // content as a private phrase, seed or URI to derive a key ring pair. Panics if the private phrase, seed or URI is
148+ // not valid or the keyring pair cannot be derived
149+ func LoadKeyringPairFromEnv () (kp KeyringPair , ok bool ) {
150+ priv , ok := os .LookupEnv ("TEST_PRIV_KEY" )
151+ if ! ok || priv == "" {
152+ return kp , false
153+ }
154+ kp , err := KeyringPairFromSecret (priv )
155+ if err != nil {
156+ panic (fmt .Errorf ("cannot load keyring pair from env or use fallback: %v" , err ))
157+ }
158+ return kp , true
159+ }
0 commit comments