Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command generating chain link file #583

Merged
merged 33 commits into from
Aug 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4aed658
Build generate chain link json command
dadamu Aug 6, 2021
1c40e11
Fix typo
dadamu Aug 6, 2021
02e74d7
Make chain link json file not generate when testing
dadamu Aug 6, 2021
caa3429
Change thecomment of the flag
dadamu Aug 6, 2021
b7e3553
Seperate chain link generae function from cmd
dadamu Aug 6, 2021
e980647
Add comments
dadamu Aug 6, 2021
df91b02
Fix lint
dadamu Aug 9, 2021
6c7d35f
Fix lint
dadamu Aug 9, 2021
e68e436
Update changeset
dadamu Aug 9, 2021
07a1ec1
Allow generate link json using other chain config
dadamu Aug 11, 2021
7530053
Merge branch 'master' of github.com:desmos-labs/desmos into paul/gene…
dadamu Aug 11, 2021
14a9353
Build interactive prompt for creating chain link json file
dadamu Aug 11, 2021
bae26a5
Fix lint
dadamu Aug 11, 2021
1bee089
Remove unused package
dadamu Aug 11, 2021
a83d60f
Remove unused pkgs
dadamu Aug 11, 2021
5ab6370
Reset sum
dadamu Aug 11, 2021
38d0117
Merge branch 'master' of github.com:desmos-labs/desmos into paul/gene…
dadamu Aug 11, 2021
d87d452
Add go mod tidy in workflow
dadamu Aug 11, 2021
bd9c83f
Fix dependency
dadamu Aug 11, 2021
c4f5449
Remove go mod tidy in workflow
dadamu Aug 11, 2021
388d453
Update sum again with go1.16
dadamu Aug 11, 2021
bcf575e
Fix osmosis chain name
dadamu Aug 11, 2021
28178ba
Update app/desmos/cmd/create-chain-link.go
dadamu Aug 12, 2021
65a2f5a
Remove unused unpack interface
dadamu Aug 12, 2021
5fcd7d9
Fix syntax and apply suggestions
dadamu Aug 12, 2021
a0cf451
Merge branch 'paul/generate-chainlink-file-cmd' of github.com:desmos-…
dadamu Aug 12, 2021
4a392e3
Remove unused filename flag
dadamu Aug 12, 2021
53b90d5
Simplify unit test code
dadamu Aug 12, 2021
b598793
Fix mock generator
dadamu Aug 12, 2021
68c6d44
Update changeset
dadamu Aug 12, 2021
45149b6
Add prompt to ask filename
dadamu Aug 14, 2021
3231ea4
Small improvements and code re-arrangement
RiccardoM Aug 14, 2021
04afde8
Removed changeset in favor of CHANGELOG entry
RiccardoM Aug 14, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Renamed `PollData` and `PollAnswer` to `Poll` and `ProvidedAnswer` ([\#536]((https://github.com/desmos-labs/desmos/issues/536)))
- Enabled snapshot by default ([\#529](https://github.com/desmos-labs/desmos/pull/529))
- Improved the performance of profile validation checks ([\#548](https://github.com/desmos-labs/desmos/pull/548))
- Added `create-chain-link-json` command ([\#572](https://github.com/desmos-labs/desmos/pull/572))


## Version 0.17.7
Expand Down
101 changes: 101 additions & 0 deletions app/desmos/cmd/chainlink/create_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package chainlink

import (
"encoding/hex"
"fmt"
"io/ioutil"

chainlinktypes "github.com/desmos-labs/desmos/app/desmos/cmd/chainlink/types"

"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"

"github.com/desmos-labs/desmos/app"
profilescliutils "github.com/desmos-labs/desmos/x/profiles/client/utils"
profilestypes "github.com/desmos-labs/desmos/x/profiles/types"
)

// GetCreateChainLinkJSON returns the command allowing to generate the chain link JSON
// file that is required by the link-chain command
func GetCreateChainLinkJSON() *cobra.Command {
return &cobra.Command{
Use: "create-chain-link-json",
Short: "Start an interactive prompt to create a new chain link JSON object",
Long: `Start an interactive prompt to create a new chain link JSON object that can be used to later link your Desmos profile to another chain.
Once you have built the JSON object using this command, you can then run the following command to complete the linkage:
desmos tx profiles link-chain [/path/to/json/file.json]
Note that this command will ask you the mnemonic that should be used to generate the private key of the address you want to link.
The mnemonic is only used temporarily and never stored anywhere.`,
RunE: func(cmd *cobra.Command, args []string) error {
// Build the chain link reference getter
getter := chainlinktypes.NewChainLinkReferencePrompt()

// Get the data
mnemonic, err := getter.GetMnemonic()
if err != nil {
return err
}

chain, err := getter.GetChain()
if err != nil {
return err
}

filename, err := getter.GetFilename()
if err != nil {
return err
}

// Build che chain link JSON
chainLinkJSON, err := generateChainLinkJSON(mnemonic, chain)
if err != nil {
return err
}

cdc, _ := app.MakeCodecs()
bz, err := cdc.MarshalJSON(&chainLinkJSON)
if err != nil {
return err
}

if filename != "" {
if err := ioutil.WriteFile(filename, bz, 0600); err != nil {
return err
}
}

cmd.Println(fmt.Sprintf("Chain link JSON file stored at %s", filename))

return nil
},
}
}

// generateChainLinkJSON returns build a new ChainLinkJSON intance using the provided mnemonic and chain configuration
func generateChainLinkJSON(mnemonic string, chain chainlinktypes.Chain) (profilescliutils.ChainLinkJSON, error) {
// Create an in-memory keybase for signing
keyBase := keyring.NewInMemory()
keyName := "chainlink"
_, err := keyBase.NewAccount(keyName, mnemonic, "", chain.DerivationPath, hd.Secp256k1)
if err != nil {
return profilescliutils.ChainLinkJSON{}, err
}

// Generate the proof signing it with the key
key, _ := keyBase.Key(keyName)
addr, _ := sdk.Bech32ifyAddressBytes(chain.Prefix, key.GetAddress())
sig, pubkey, err := keyBase.Sign(keyName, []byte(addr))
if err != nil {
return profilescliutils.ChainLinkJSON{}, err
}

return profilescliutils.NewChainLinkJSON(
profilestypes.NewBech32Address(addr, chain.Prefix),
profilestypes.NewProof(pubkey, hex.EncodeToString(sig), addr),
profilestypes.NewChainConfig(chain.Name),
), nil
}
83 changes: 83 additions & 0 deletions app/desmos/cmd/chainlink/create_json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package chainlink_test

import (
"os"
"testing"

cmd "github.com/desmos-labs/desmos/app/desmos/cmd/chainlink"
"github.com/desmos-labs/desmos/app/desmos/cmd/chainlink/types"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/desmos-labs/desmos/app"
profilescliutils "github.com/desmos-labs/desmos/x/profiles/client/utils"
profilestypes "github.com/desmos-labs/desmos/x/profiles/types"
)

// MockGetter represents a mock implementation of ChainLinkReferenceGetter
type MockGetter struct{}

// GetMnemonic implements ChainLinkReferenceGetter
func (mock MockGetter) GetMnemonic() (string, error) {
return "clip toilet stairs jaguar baby over mosquito capital speed mule adjust eye print voyage verify smart open crack imitate auto gauge museum planet rebel", nil
}

// GetChain implements ChainLinkReferenceGetter
func (mock MockGetter) GetChain() (types.Chain, error) {
return types.NewChain("Cosmos", "cosmos", "cosmos", "m/44'/118'/0'/0/0"), nil
}

// GetFilename implements ChainLinkReferenceGetter
func (mock MockGetter) GetFilename() (string, error) {
return "", nil
}

func TestGetCreateChainLinkJSON(t *testing.T) {
cfg := sdk.GetConfig()
app.SetupConfig(cfg)

output := os.Stdout
clientCtx := client.Context{}.
WithOutput(output)

out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd.GetCreateChainLinkJSON(MockGetter{}), []string{})
require.NoError(t, err)

cdc, _ := app.MakeCodecs()
var data profilescliutils.ChainLinkJSON
err = cdc.UnmarshalJSON(out.Bytes(), &data)
require.NoError(t, err)

// create a account to inmemory keybase
keyBase := keyring.NewInMemory()
keyName := "chainlink"
_, err = keyBase.NewAccount(
"chainlink",
"clip toilet stairs jaguar baby over mosquito capital speed mule adjust eye print voyage verify smart open crack imitate auto gauge museum planet rebel",
"",
"m/44'/118'/0'/0/0",
hd.Secp256k1,
)
require.NoError(t, err)

// get key from keybase
key, err := keyBase.Key(keyName)
require.NoError(t, err)

expected := profilescliutils.NewChainLinkJSON(
profilestypes.NewBech32Address("cosmos13j7p6faa9jr8ty6lvqv0prldprr6m5xenmafnt", "cosmos"),
profilestypes.NewProof(
key.GetPubKey(),
"c3bd014b2178d63d94b9c28e628bfcf56736de28f352841b0bb27d6fff2968d62c13a10aeddd1ebfe3b13f3f8e61f79a2c63ae6ff5cb78cb0d64e6b0a70fae57",
"cosmos13j7p6faa9jr8ty6lvqv0prldprr6m5xenmafnt"),
profilestypes.NewChainConfig("cosmos"),
)

require.Equal(t, expected, data)

}
19 changes: 19 additions & 0 deletions app/desmos/cmd/chainlink/types/chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package types

// Chain contains the data of a single chain
type Chain struct {
ID string
Name string
Prefix string
DerivationPath string
}

// NewChain returns a new Chain instance
func NewChain(id, name, prefix, derivationPath string) Chain {
return Chain{
id,
name,
prefix,
derivationPath,
}
}
19 changes: 19 additions & 0 deletions app/desmos/cmd/chainlink/types/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package types

// Config contains the data of the configuration
type Config struct {
Chains []Chain
}

// DefaultConfig returns the default config instance of the configuration
func DefaultConfig() Config {
return Config{
Chains: []Chain{
NewChain("Desmos", "desmos", "desmos", "m/44'/852'/0'/0/0"),
NewChain("Cosmos", "cosmos", "cosmos", "m/44'/118'/0'/0/0"),
NewChain("Akash", "akash", "akash", "m/44'/118'/0'/0/0"),
NewChain("Osmosis", "osmosis", "osmo", "m/44'/118'/0'/0/0"),
NewChain("Other", "", "", ""),
},
}
}
Loading