Skip to content

Commit 8a54a0c

Browse files
Merge pull request #36 from ElrondNetwork/erdpy-wallet-new
Erdpy wallet new
2 parents 775f614 + 876ef7c commit 8a54a0c

21 files changed

Lines changed: 2373 additions & 126 deletions

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
include erdpy/projects/*.txt
22
include erdpy/projects/*.json
3+
include erdpy/wallet/*.txt
34

45
include erdpy/testnet/wallets/users/*.pem
56
include erdpy/testnet/wallets/users/*.json

erdpy/CLI.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ contract Build, deploy and interact with Smart Contracts
3434
tx Create and broadcast Transactions
3535
validator Stake, Unjail and other actions useful for Validators
3636
account Get Account data (nonce, balance) from the Network
37-
wallet Derive private key from mnemonic, bech32 address helpers etc.
37+
wallet Derive secret key from mnemonic, bech32 address helpers etc.
3838
network Get Network parameters, such as number of shards, chain identifier etc.
3939
cost Estimate cost of Transactions
4040
dispatcher Enqueue transactions, then bulk dispatch them
@@ -701,7 +701,7 @@ optional arguments:
701701
$ erdpy wallet --help
702702
usage: erdpy wallet COMMAND [-h] ...
703703
704-
Derive private key from mnemonic, bech32 address helpers etc.
704+
Derive secret key from mnemonic, bech32 address helpers etc.
705705
706706
COMMANDS:
707707
{derive,bech32,pem-address,pem-address-hex}

erdpy/accounts.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ def generate_accounts(self, count):
2727
self.generate_account(i)
2828

2929
def generate_account(self, name):
30-
seed, pubkey = generate_pair()
30+
secret_key, pubkey = generate_pair()
3131
address = Address(pubkey).bech32()
3232

3333
pem_file = f"{name}_{address}.pem"
3434
pem_file = path.join(self.folder, pem_file)
35-
pem.write(pem_file, seed, pubkey, name=f"{name}:{address}")
35+
pem.write(pem_file, secret_key, pubkey, name=f"{name}:{address}")
3636

3737
def get_all(self):
3838
accounts = []
@@ -59,24 +59,24 @@ def __init__(self,
5959
self.ledger = ledger
6060

6161
if self.pem_file:
62-
seed, pubkey = pem.parse(self.pem_file, self.pem_index)
63-
self.private_key_seed = seed.hex()
62+
secret_key, pubkey = pem.parse(self.pem_file, self.pem_index)
63+
self.secret_key = secret_key.hex()
6464
self.address = Address(pubkey)
6565
elif key_file and pass_file:
6666
password = get_password(pass_file)
67-
address_from_key_file, seed = load_from_key_file(key_file, password)
68-
self.private_key_seed = seed.hex()
67+
address_from_key_file, secret_key = load_from_key_file(key_file, password)
68+
self.secret_key = secret_key.hex()
6969
self.address = Address(address_from_key_file)
7070

7171
def sync_nonce(self, proxy: Any):
7272
logger.info("Account.sync_nonce()")
7373
self.nonce = proxy.get_account_nonce(self.address)
7474
logger.info(f"Account.sync_nonce() done: {self.nonce}")
7575

76-
def get_seed(self) -> bytes:
76+
def get_secret_key(self) -> bytes:
7777
if self.ledger:
7878
raise LedgerError("cannot get seed from a Ledger account")
79-
return unhexlify(self.private_key_seed)
79+
return unhexlify(self.secret_key)
8080

8181

8282
class Address(IAddress):

erdpy/cli_wallet.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
from erdpy.wallet.keyfile import save_to_key_file
2+
from erdpy.wallet.core import generate_mnemonic
13
import logging
4+
import getpass
5+
from pathlib import Path
26
from typing import Any, List
37

4-
from erdpy import cli_shared, wallet
8+
from erdpy import cli_shared, wallet, utils
59
from erdpy.accounts import Account, Address
610
from erdpy.wallet import pem
711

@@ -12,10 +16,24 @@ def setup_parser(args: List[str], subparsers: Any) -> Any:
1216
parser = cli_shared.add_group_subparser(
1317
subparsers,
1418
"wallet",
15-
"Derive private key from mnemonic, bech32 address helpers etc."
19+
"Derive secret key from mnemonic, bech32 address helpers etc."
1620
)
1721
subparsers = parser.add_subparsers()
1822

23+
sub = cli_shared.add_command_subparser(
24+
subparsers,
25+
"wallet",
26+
"new",
27+
"Create a new wallet"
28+
)
29+
sub.add_argument("--json",
30+
help="whether to create a json key file", action="store_true", default=False)
31+
sub.add_argument("--pem",
32+
help="whether to create a pem key file", action="store_true", default=False)
33+
sub.add_argument("--output-path",
34+
help="the output path and base file name for the generated wallet files (default: %(default)s)", type=str, default="./wallet")
35+
sub.set_defaults(func=new_wallet)
36+
1937
sub = cli_shared.add_command_subparser(
2038
subparsers,
2139
"wallet",
@@ -69,19 +87,42 @@ def setup_parser(args: List[str], subparsers: Any) -> Any:
6987
return subparsers
7088

7189

90+
def new_wallet(args: Any):
91+
mnemonic = generate_mnemonic()
92+
print(f"Mnemonic: {mnemonic}")
93+
secret_key, pubkey = wallet.derive_keys(mnemonic)
94+
if args.pem:
95+
pem_file = prepare_file(args.output_path, ".pem")
96+
address = Address(pubkey)
97+
pem.write(pem_file, secret_key, pubkey, name=address.bech32())
98+
logger.info(f"Pem wallet generated: {pem_file}")
99+
if args.json:
100+
json_file = prepare_file(args.output_path, ".json")
101+
password = getpass.getpass("Enter a new password:")
102+
save_to_key_file(json_file, secret_key, pubkey, password)
103+
logger.info(f"Json wallet generated: {json_file}")
104+
105+
106+
def prepare_file(output_path: str, suffix: str) -> Path:
107+
base_path = Path(output_path)
108+
utils.ensure_folder(base_path.parent)
109+
file_path = base_path.with_suffix(suffix)
110+
return utils.uniquify(file_path)
111+
112+
72113
def generate_pem(args: Any):
73114
pem_file = args.pem
74115
mnemonic = args.mnemonic
75116
index = args.index
76117

77-
seed, pubkey = wallet.generate_pair()
118+
secret_key, pubkey = wallet.generate_pair()
78119
if mnemonic:
79120
mnemonic = input("Enter mnemonic:\n")
80121
mnemonic = mnemonic.strip()
81-
seed, pubkey = wallet.derive_keys(mnemonic, index)
122+
secret_key, pubkey = wallet.derive_keys(mnemonic, index)
82123

83124
address = Address(pubkey)
84-
pem.write(pem_file, seed, pubkey, name=address.bech32())
125+
pem.write(pem_file, secret_key, pubkey, name=address.bech32())
85126
logger.info(f"Created PEM file [{pem_file}] for [{address.bech32()}]")
86127

87128

erdpy/delegation/staking_provider.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ def prepare_args_for_add_nodes(args: Any):
4242
# get validator
4343
validator_pem = validator.get("pemFile")
4444
validator_pem = path.join(path.dirname(args.validators_file), validator_pem)
45-
seed, bls_key = parse_validator_pem(validator_pem)
46-
signed_message = sign_message_with_bls_key(account.address.pubkey().hex(), seed.decode('ascii'))
45+
secret_key_bytes, bls_key = parse_validator_pem(validator_pem)
46+
signed_message = sign_message_with_bls_key(account.address.pubkey().hex(), secret_key_bytes.decode('ascii'))
4747
add_nodes_data += f"@{bls_key}@{signed_message}"
4848

4949
args.receiver = args.delegation_contract

erdpy/ide/static/app/models.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var SmartContract = Backbone.Model.extend({
33

44
initialize: function () {
55
},
6-
6+
77
deploy: function (options) {
88
var payload = options.toJSON();
99
payload.id = this.id;
@@ -22,7 +22,7 @@ var SmartContract = Backbone.Model.extend({
2222
app.talkToHead("queryWatchedVariables", payload);
2323
},
2424

25-
addWatchedVariable: function(options) {
25+
addWatchedVariable: function (options) {
2626
this.getWatchedVariables(options.onTestnet).push({
2727
Name: "alice's balance",
2828
FunctionName: "do_balance",
@@ -32,7 +32,7 @@ var SmartContract = Backbone.Model.extend({
3232
this.setWatchedVariables(options);
3333
},
3434

35-
updateWatchedVariable: function(options) {
35+
updateWatchedVariable: function (options) {
3636
var index = options.index;
3737
var variable = this.getWatchedVariables(options.onTestnet)[index];
3838
variable.Name = options.name;
@@ -42,20 +42,20 @@ var SmartContract = Backbone.Model.extend({
4242
this.setWatchedVariables(options);
4343
},
4444

45-
deleteWatchedVariable: function(options) {
45+
deleteWatchedVariable: function (options) {
4646
var variables = this.getWatchedVariables(options.onTestnet);
4747
variables.splice(options.index, 1);
4848

4949
this.setWatchedVariables(options);
5050
},
5151

52-
getWatchedVariables: function(onTestnet) {
52+
getWatchedVariables: function (onTestnet) {
5353
var properties = onTestnet ? this.get("PropertiesOnTestnet") : this.get("PropertiesOnNodeDebug");
5454
var variables = properties.WatchedVariables;
5555
return variables;
5656
},
5757

58-
setWatchedVariables: function(options) {
58+
setWatchedVariables: function (options) {
5959
var payload = options;
6060
payload.id = this.id;
6161
payload.variables = this.getWatchedVariables(options.onTestnet);
@@ -68,8 +68,8 @@ var SmartContract = Backbone.Model.extend({
6868
var SmartContractDeployOptions = Backbone.Model.extend({
6969
validate: function (attrs, options) {
7070
if (attrs.onTestnet) {
71-
if (!attrs.privateKey) {
72-
return "When deploying on testnet, the private key is required.";
71+
if (!attrs.secretKey) {
72+
return "When deploying on testnet, the secret key is required.";
7373
}
7474
}
7575
else {
@@ -87,8 +87,8 @@ var SmartContractRunOptions = Backbone.Model.extend({
8787
}
8888

8989
if (attrs.onTestnet) {
90-
if (!attrs.privateKey) {
91-
return "When running on testnet, the private key is required.";
90+
if (!attrs.secretKey) {
91+
return "When running on testnet, the secret key is required.";
9292
}
9393
}
9494
else {
@@ -101,4 +101,4 @@ var SmartContractRunOptions = Backbone.Model.extend({
101101

102102
var SmartContractsCollection = Backbone.Collection.extend({
103103
model: SmartContract
104-
});
104+
});

erdpy/ide/static/app/views.deployDialog.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var DeployDialog = Backbone.View.extend({
66
"shown.bs.modal": "onBootstrapModalShown",
77
"hidden.bs.modal": "onBootstrapModalHidden",
88
"click .btn-submit": "onClickSubmit",
9-
"change input[name='PrivateKeyFile']": "onChangePrivateKey"
9+
"change input[name='SecretKeyFile']": "onChangeSecretKey"
1010
},
1111

1212
initialize: function (options) {
@@ -49,13 +49,13 @@ var DeployDialog = Backbone.View.extend({
4949
this.remove();
5050
},
5151

52-
onChangePrivateKey: function (event) {
52+
onChangeSecretKey: function (event) {
5353
var self = this;
5454
var file = event.currentTarget.files[0];
5555
var reader = new FileReader();
5656

5757
reader.onload = function (onloadEvent) {
58-
self.privateKey = onloadEvent.target.result;
58+
self.secretKey = onloadEvent.target.result;
5959
};
6060

6161
reader.readAsText(file);
@@ -69,7 +69,7 @@ var DeployDialog = Backbone.View.extend({
6969
var gasPrice = this.getGasPrice();
7070

7171
var deployOptions = new SmartContractDeployOptions({
72-
privateKey: this.privateKey,
72+
secretKey: this.secretKey,
7373
senderAddress: senderAddress,
7474
initArgs: initArgs,
7575
value: value,
@@ -117,4 +117,4 @@ var DeployDialog = Backbone.View.extend({
117117
getGasPrice: function () {
118118
return Number(this.$el.find("[name='GasPrice']").val());
119119
}
120-
});
120+
});

erdpy/ide/static/app/views.runDialog.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var RunDialog = Backbone.View.extend({
66
"shown.bs.modal": "onBootstrapModalShown",
77
"hidden.bs.modal": "onBootstrapModalHidden",
88
"click .btn-submit": "onClickSubmit",
9-
"change input[name='PrivateKeyFile']": "onChangePrivateKey"
9+
"change input[name='SecretKeyFile']": "onChangeSecretKey"
1010
},
1111

1212
initialize: function (options) {
@@ -49,13 +49,13 @@ var RunDialog = Backbone.View.extend({
4949
this.remove();
5050
},
5151

52-
onChangePrivateKey: function (event) {
52+
onChangeSecretKey: function (event) {
5353
var self = this;
5454
var file = event.currentTarget.files[0];
5555
var reader = new FileReader();
5656

5757
reader.onload = function (onloadEvent) {
58-
self.privateKey = onloadEvent.target.result;
58+
self.secretKey = onloadEvent.target.result;
5959
};
6060

6161
reader.readAsText(file);
@@ -70,7 +70,7 @@ var RunDialog = Backbone.View.extend({
7070
var gasPrice = this.getGasPrice();
7171

7272
var runOptions = new SmartContractRunOptions({
73-
privateKey: this.privateKey,
73+
secretKey: this.secretKey,
7474
senderAddress: senderAddress,
7575
functionName: functionName,
7676
functionArgs: functionArgs,
@@ -90,11 +90,11 @@ var RunDialog = Backbone.View.extend({
9090
}
9191
},
9292

93-
clearValidationErrors: function() {
93+
clearValidationErrors: function () {
9494
this.$el.find(".validation-errors-container").addClass("d-none").empty();
9595
},
9696

97-
displayValidationErrors: function(validationError) {
97+
displayValidationErrors: function (validationError) {
9898
this.$el.find(".validation-errors-container").removeClass("d-none").text(validationError);
9999
},
100100

@@ -123,4 +123,4 @@ var RunDialog = Backbone.View.extend({
123123
getGasPrice: function () {
124124
return Number(this.$el.find("[name='GasPrice']").val());
125125
}
126-
});
126+
});

erdpy/ide/views/_deployDialog.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ <h4 class="modal-title">Deploy Smart Contract</h4>
99
<form>
1010
[[ if (onTestnet) { ]]
1111
<div class="form-group">
12-
<label class="">Private key:</label>
13-
<input class="form-control" type="file" name="PrivateKeyFile" accept=".pem" />
12+
<label class="">Secret key:</label>
13+
<input class="form-control" type="file" name="SecretKeyFile" accept=".pem" />
1414
</div>
1515
[[ } else { ]]
1616
<div class="form-group">
@@ -53,7 +53,8 @@ <h4 class="modal-title">Deploy Smart Contract</h4>
5353
[[ if (contract.PropertiesOnTestnet.Address) { ]]
5454
<div class="form-group">
5555
<label class="">Deployed at address:</label>
56-
<input class="form-control" name="" type="text" value="[[= contract.PropertiesOnTestnet.Address ]]" readonly />
56+
<input class="form-control" name="" type="text" value="[[= contract.PropertiesOnTestnet.Address ]]"
57+
readonly />
5758
</div>
5859
[[ } ]]
5960
[[ } else { ]]
@@ -79,4 +80,4 @@ <h4 class="modal-title">Deploy Smart Contract</h4>
7980
</button>
8081
</div>
8182
</div>
82-
</div>
83+
</div>

erdpy/ide/views/_runDialog.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ <h4 class="modal-title">Run Smart Contract Function</h4>
1212
[[ var properties = onTestnet ? contract.PropertiesOnTestnet : contract.PropertiesOnNodeDebug; ]]
1313
[[ if (onTestnet) { ]]
1414
<div class="form-group">
15-
<label class="">Private key:</label>
16-
<input class="form-control" type="file" name="PrivateKeyFile" accept=".pem" />
15+
<label class="">Secret key:</label>
16+
<input class="form-control" type="file" name="SecretKeyFile" accept=".pem" />
1717
</div>
1818
[[ } else { ]]
1919
<div class="form-group">
@@ -76,4 +76,4 @@ <h4 class="modal-title">Run Smart Contract Function</h4>
7676
<button type="button" class="btn btn-primary btn-submit">Run</button>
7777
</div>
7878
</div>
79-
</div>
79+
</div>

0 commit comments

Comments
 (0)