Skip to content

Commit c0251e2

Browse files
committed
Add a smapp-compatible wallet sign subcommand
Motivation ---------- smapp has a simple message signing functionality, which uses a wallet's keypair to sign text messages using Ed25519ctx. This functionality is used by, for example, Team24 to authenticate an sm1 address owner. The functionality is also supported by the third-party wallet implementation smeshwallet.com. Description ----------- This change adds a simple `smcli wallet sign` subcommand, which takes a wallet JSON and a message as arguments, signs the message, and outputs a smapp-compatible JSON structure of message, signature, and signer public key.
1 parent a1e889a commit c0251e2

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

cmd/wallet.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package cmd
22

33
import (
4+
"crypto"
5+
"crypto/ed25519"
46
"encoding/hex"
7+
"encoding/json"
58
"errors"
69
"fmt"
710
"log"
@@ -289,10 +292,58 @@ only child keys).`,
289292
},
290293
}
291294

295+
var signCmd = &cobra.Command{
296+
Use: "sign [wallet file] [message]",
297+
Short: "Signs a message using a wallet's first child key",
298+
Args: cobra.ExactArgs(2),
299+
Run: func(cmd *cobra.Command, args []string) {
300+
walletFn := args[0]
301+
message := args[1]
302+
303+
// make sure the file exists
304+
f, err := os.Open(walletFn)
305+
cobra.CheckErr(err)
306+
defer f.Close()
307+
308+
// get the password
309+
fmt.Print("Enter wallet password: ")
310+
password, err := password.Read(os.Stdin)
311+
fmt.Println()
312+
cobra.CheckErr(err)
313+
314+
// attempt to read it
315+
wk := wallet.NewKey(wallet.WithPasswordOnly([]byte(password)))
316+
w, err := wk.Open(f, debug)
317+
cobra.CheckErr(err)
318+
319+
// Sign message using child account 0.
320+
child0 := w.Secrets.Accounts[0] // TODO: flag to select child
321+
sk0 := ed25519.PrivateKey(child0.Private)
322+
sig, err := sk0.Sign(nil, []byte(message), crypto.Hash(0))
323+
cobra.CheckErr(err)
324+
325+
// Output signed message in a JSON format compatible with smapp's signing feature.
326+
type signedMessage struct {
327+
Text string `json:"text"`
328+
Signature string `json:"signature"`
329+
PublicKey string `json:"publicKey"`
330+
}
331+
out := signedMessage{
332+
Text: message,
333+
Signature: "0x" + hex.EncodeToString(sig),
334+
PublicKey: "0x" + hex.EncodeToString(child0.Public),
335+
}
336+
enc := json.NewEncoder(os.Stdout)
337+
enc.SetIndent("", " ")
338+
enc.Encode(out)
339+
},
340+
}
341+
292342
func init() {
293343
rootCmd.AddCommand(walletCmd)
294344
walletCmd.AddCommand(createCmd)
295345
walletCmd.AddCommand(readCmd)
346+
walletCmd.AddCommand(signCmd)
296347
readCmd.Flags().BoolVarP(&printPrivate, "private", "p", false, "Print private keys")
297348
readCmd.Flags().BoolVarP(&printFull, "full", "f", false, "Print full keys (no abbreviation)")
298349
readCmd.Flags().BoolVar(&printBase58, "base58", false, "Print keys in base58 (rather than hex)")

0 commit comments

Comments
 (0)