Skip to content

Commit 51b47da

Browse files
Merge pull request #355 from hypersign-protocol/develop
v0.1.8-rc.1 : Release
2 parents 6f1f596 + 597964b commit 51b47da

19 files changed

+881
-154
lines changed

cmd/hid-noded/cmd/generate_ssi.go

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
"github.com/cosmos/cosmos-sdk/client"
11+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
12+
"github.com/hypersign-protocol/hid-node/app"
13+
"github.com/hypersign-protocol/hid-node/x/ssi/types"
14+
"github.com/multiformats/go-multibase"
15+
"github.com/spf13/cobra"
16+
17+
sdk "github.com/cosmos/cosmos-sdk/types"
18+
)
19+
20+
const fromFlag = "from"
21+
const didAliasFlag = "did-alias"
22+
const keyringBackendFlag = "keyring-backend"
23+
const didNamespaceFlag = "did-namespace"
24+
25+
func generateSSICmd() *cobra.Command {
26+
cmd := &cobra.Command{
27+
Use: "ssi-tools",
28+
Short: "commands to experiment around Self Sovereign Identity (SSI) documents",
29+
}
30+
31+
cmd.AddCommand(generateDidCmd())
32+
cmd.AddCommand(showDidByAliasCmd())
33+
cmd.AddCommand(listAllDidAliasesCmd())
34+
35+
return cmd
36+
}
37+
38+
func listAllDidAliasesCmd() *cobra.Command {
39+
cmd := &cobra.Command{
40+
Use: "list-did-aliases",
41+
Short: "List all DID Document alias names",
42+
RunE: func(cmd *cobra.Command, _ []string) error {
43+
didAliasConfig, err := types.GetDidAliasConfig(cmd)
44+
if err != nil {
45+
return err
46+
}
47+
48+
clientCtx, err := client.GetClientTxContext(cmd)
49+
if err != nil {
50+
return err
51+
}
52+
53+
result := []map[string]string{}
54+
55+
if _, err := os.Stat(didAliasConfig.DidAliasDir); err != nil {
56+
if os.IsNotExist(err) {
57+
fmt.Fprintf(cmd.ErrOrStderr(), "%v\n\n", []string{})
58+
return nil
59+
}
60+
}
61+
didJsonFiles, err := os.ReadDir(didAliasConfig.DidAliasDir)
62+
if err != nil {
63+
return err
64+
}
65+
66+
// Consider only those files whose extensions are '.json'
67+
for _, didJsonFile := range didJsonFiles {
68+
isDidJsonFile := !didJsonFile.IsDir() && (strings.Split(didJsonFile.Name(), ".")[1] == "json")
69+
if isDidJsonFile {
70+
unit := map[string]string{}
71+
didDocBytes, err := os.ReadFile(filepath.Join(didAliasConfig.DidAliasDir, didJsonFile.Name()))
72+
if err != nil {
73+
return err
74+
}
75+
76+
var didDoc types.Did
77+
err = clientCtx.Codec.UnmarshalJSON(didDocBytes, &didDoc)
78+
if err != nil {
79+
// Ignore any files which are not able to parse into type.Did
80+
continue
81+
}
82+
83+
unit["did"] = didDoc.Id
84+
unit["alias"] = strings.Split(didJsonFile.Name(), ".")[0]
85+
result = append(result, unit)
86+
} else {
87+
continue
88+
}
89+
}
90+
91+
// Indent Map
92+
resultBytes, err := json.MarshalIndent(result, "", " ")
93+
if err != nil {
94+
return err
95+
}
96+
97+
_, err = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", string(resultBytes))
98+
return err
99+
},
100+
}
101+
return cmd
102+
}
103+
104+
func showDidByAliasCmd() *cobra.Command {
105+
exampleString := "hid-noded ssi-tools show-did-by-alias didsample3"
106+
107+
cmd := &cobra.Command{
108+
Use: "show-did-by-alias [alias-name]",
109+
Args: cobra.ExactArgs(1),
110+
Example: exampleString,
111+
Short: "Retrieve the Did Document by a alias name",
112+
RunE: func(cmd *cobra.Command, args []string) error {
113+
didAliasConfig, err := types.GetDidAliasConfig(cmd)
114+
if err != nil {
115+
return err
116+
}
117+
118+
aliasName := args[0]
119+
aliasFile := aliasName + ".json"
120+
121+
if _, err := os.Stat(didAliasConfig.DidAliasDir); err != nil {
122+
if os.IsNotExist(err) {
123+
fmt.Fprintf(cmd.ErrOrStderr(), "DID Document alias '%v' does not exist\n", aliasName)
124+
return nil
125+
}
126+
}
127+
128+
didDocBytes, err := os.ReadFile(filepath.Join(didAliasConfig.DidAliasDir, aliasFile))
129+
if err != nil {
130+
fmt.Fprintf(cmd.ErrOrStderr(), "DID Document alias '%v' does not exist\n", aliasName)
131+
return nil
132+
}
133+
134+
_, err = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", string(didDocBytes))
135+
return err
136+
},
137+
}
138+
139+
return cmd
140+
}
141+
142+
func generateDidCmd() *cobra.Command {
143+
exampleString1 := "hid-noded ssi-tools generate-did --from hid1kspgn6f5hmurulx4645ch6rf0kt90jpv5ydykp --keyring-backend test --did-alias example1"
144+
exampleString2 := "hid-noded ssi-tools generate-did --from node1 --keyring-backend test --did-alias example2"
145+
exampleString3 := "hid-noded ssi-tools generate-did --from node1 --keyring-backend test --did-alias example3 --did-namespace devnet"
146+
147+
cmd := &cobra.Command{
148+
Use: "generate-did",
149+
Short: "Generates a DID Document",
150+
Example: exampleString1 + "\n" + exampleString2 + "\n" + exampleString3,
151+
RunE: func(cmd *cobra.Command, _ []string) error {
152+
// Get the flags
153+
account, err := cmd.Flags().GetString(fromFlag)
154+
if err != nil {
155+
return err
156+
}
157+
if account == "" {
158+
return fmt.Errorf("no value provided for --from flag")
159+
}
160+
161+
didAlias, err := cmd.Flags().GetString(didAliasFlag)
162+
if err != nil {
163+
return err
164+
}
165+
if didAlias == "" {
166+
return fmt.Errorf("no value provided for --did-alias flag")
167+
}
168+
169+
keyringBackend, err := cmd.Flags().GetString(keyringBackendFlag)
170+
if err != nil {
171+
return err
172+
}
173+
if keyringBackend == "" {
174+
return fmt.Errorf("no value provided for --keyring-backend flag")
175+
}
176+
177+
didNamespace, err := cmd.Flags().GetString(didNamespaceFlag)
178+
if err != nil {
179+
return err
180+
}
181+
182+
// Get Public Key from keyring account
183+
var kr keyring.Keyring
184+
appName := "hid-noded-keyring"
185+
didAliasConfig, err := types.GetDidAliasConfig(cmd)
186+
if err != nil {
187+
return err
188+
}
189+
190+
switch keyringBackend {
191+
case "test":
192+
kr, err = keyring.New(appName, "test", didAliasConfig.HidNodeConfigDir, nil)
193+
if err != nil {
194+
return err
195+
}
196+
default:
197+
return fmt.Errorf("unsupported keyring-backend : %v", keyringBackend)
198+
}
199+
200+
// Handle both key name as well as key address
201+
var userKeyInfo keyring.Info
202+
var errAccountFetch error
203+
204+
userKeyInfo, errAccountFetch = kr.Key(account)
205+
if errAccountFetch != nil {
206+
if accountAddr, err := sdk.AccAddressFromBech32(account); err != nil {
207+
return err
208+
} else {
209+
userKeyInfo, errAccountFetch = kr.KeyByAddress(accountAddr)
210+
if errAccountFetch != nil {
211+
return errAccountFetch
212+
}
213+
}
214+
}
215+
216+
pubKeyBytes := userKeyInfo.GetPubKey().Bytes()
217+
pubKeyMultibase, err := multibase.Encode(multibase.Base58BTC, pubKeyBytes)
218+
if err != nil {
219+
return err
220+
}
221+
userBlockchainAddress := sdk.MustBech32ifyAddressBytes(
222+
app.AccountAddressPrefix,
223+
userKeyInfo.GetAddress().Bytes(),
224+
)
225+
226+
// Generate a DID document with both publicKeyMultibase and blockchainAccountId
227+
didDoc := generateDidDoc(didNamespace, pubKeyMultibase, userBlockchainAddress)
228+
229+
// Construct the JSON and store it in $HOME/.hid-node/generated-ssi-docs
230+
if _, err := os.Stat(didAliasConfig.DidAliasDir); err != nil {
231+
if os.IsNotExist(err) {
232+
if err := os.Mkdir(didAliasConfig.DidAliasDir, os.ModePerm); err != nil {
233+
return err
234+
}
235+
} else {
236+
return err
237+
}
238+
}
239+
240+
didJsonBytes, err := json.MarshalIndent(didDoc, "", " ")
241+
if err != nil {
242+
return err
243+
}
244+
didJsonFilename := didAlias + ".json"
245+
didJsonPath := filepath.Join(didAliasConfig.DidAliasDir, didJsonFilename)
246+
if err := os.WriteFile(didJsonPath, didJsonBytes, 0644); err != nil {
247+
return err
248+
}
249+
250+
_, err = fmt.Fprintf(cmd.ErrOrStderr(), "DID Document alias '%v' (didId: %v) has been successfully generated at %v\n", didAlias, didDoc.Id, didJsonPath)
251+
252+
return err
253+
},
254+
}
255+
256+
cmd.Flags().String(fromFlag, "", "name of account while will sign the DID Document")
257+
cmd.Flags().String(didAliasFlag, "", "alias of the generated DID Document which can be referred to while registering on-chain")
258+
cmd.Flags().String(keyringBackendFlag, "", "supported keyring backend: (test)")
259+
cmd.Flags().String(didNamespaceFlag, "", "namespace of DID Document Id")
260+
return cmd
261+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package cmd
2+
3+
import (
4+
"github.com/hypersign-protocol/hid-node/x/ssi/types"
5+
)
6+
7+
func formDidId(didNamespace string, publicKeyMultibase string) string {
8+
if didNamespace != "" {
9+
return types.DocumentIdentifierDid + ":" + types.DidMethod + ":" + didNamespace + ":" + publicKeyMultibase
10+
} else {
11+
return types.DocumentIdentifierDid + ":" + types.DidMethod + ":" + publicKeyMultibase
12+
}
13+
}
14+
15+
func generateDidDoc(didNamespace string, publicKeyMultibase string, userAddress string) *types.Did {
16+
didId := formDidId(didNamespace, publicKeyMultibase)
17+
18+
return &types.Did{
19+
Id: didId,
20+
Controller: []string{didId},
21+
VerificationMethod: []*types.VerificationMethod{
22+
{
23+
Id: didId + "#k1",
24+
Type: types.EcdsaSecp256k1VerificationKey2019,
25+
Controller: didId,
26+
PublicKeyMultibase: publicKeyMultibase,
27+
BlockchainAccountId: types.CosmosCAIP10Prefix + ":jagrat:" + userAddress,
28+
},
29+
},
30+
}
31+
}

cmd/hid-noded/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
114114
)
115115

116116
rootCmd.AddCommand(server.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec))
117+
rootCmd.AddCommand(generateSSICmd())
117118
}
118119

119120
func addModuleInitFlags(startCmd *cobra.Command) {

localnetsetup.sh

100644100755
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ cat $HOME/.hid-node/config/genesis.json | jq '.app_state["gov"]["deposit_params"
3838
cat $HOME/.hid-node/config/genesis.json | jq '.app_state["gov"]["voting_params"]["voting_period"]="50s"' > $HOME/.hid-node/config/tmp_genesis.json && mv $HOME/.hid-node/config/tmp_genesis.json $HOME/.hid-node/config/genesis.json
3939

4040
# update ssi genesis
41-
cat $HOME/.hid-node/config/genesis.json | jq '.app_state["ssi"]["chain_namespace"]="testnet"' > $HOME/.hid-node/config/tmp_genesis.json && mv $HOME/.hid-node/config/tmp_genesis.json $HOME/.hid-node/config/genesis.json
41+
cat $HOME/.hid-node/config/genesis.json | jq '.app_state["ssi"]["chain_namespace"]="devnet"' > $HOME/.hid-node/config/tmp_genesis.json && mv $HOME/.hid-node/config/tmp_genesis.json $HOME/.hid-node/config/genesis.json
4242

4343
# update mint genesis
4444
cat $HOME/.hid-node/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="uhid"' > $HOME/.hid-node/config/tmp_genesis.json && mv $HOME/.hid-node/config/tmp_genesis.json $HOME/.hid-node/config/genesis.json
@@ -59,6 +59,12 @@ sed -i -E 's|allow_duplicate_ip = false|allow_duplicate_ip = true|g' $HOME/.hid-
5959
sed -i -E 's|addr_book_strict = true|addr_book_strict = false|g' $HOME/.hid-node/config/config.toml
6060
sed -i -E 's|cors_allowed_origins = \[\]|cors_allowed_origins = \[\"\*\"\]|g' $HOME/.hid-node/config/config.toml
6161

62-
echo -e "\nConfiguarations set, you are ready to run hid-noded now!"
62+
echo -e "\nConfiguration set up is done, you are ready to run hid-noded now!"
63+
64+
echo -e "\nPlease note the important chain configurations below:"
65+
66+
echo -e "\nRPC server address: http://localhost:26657"
67+
echo -e "API server address: http://localhost:1317"
68+
echo -e "DID Namespace: devnet"
6369

6470
echo -e "\nEnter the command 'hid-noded start' to start a single node blockchain."

0 commit comments

Comments
 (0)