diff --git a/Gruntfile.js b/Gruntfile.js
index 1245e833a1..8227f9d15a 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -5,14 +5,16 @@ module.exports = function (grunt) {
return content
.replace(/CLIENT_VERSION\s*=\s*'[^']+'/, grunt.template.process("CLIENT_VERSION = '<%= pkg.version %>a'"))
.replace(/NODE_ADDRESS\s*=\s*'[^']+'/, grunt.template.process("NODE_ADDRESS = '<%= meta.configurations.testnet.server %>'"))
- .replace(/NETWORK_NAME\s*=\s*'[^']+'/, grunt.template.process("NETWORK_NAME = '<%= meta.configurations.testnet.name %>'"));
+ .replace(/NETWORK_NAME\s*=\s*'[^']+'/, grunt.template.process("NETWORK_NAME = '<%= meta.configurations.testnet.name %>'"))
+ .replace(/NETWORK_CODE\s*=\s*'[^']+'/, grunt.template.process("NETWORK_CODE = '<%= meta.configurations.testnet.code %>'"));
};
var replaceMainnetVersion = function (content) {
return content
.replace(/CLIENT_VERSION\s*=\s*'[^']+'/, grunt.template.process("CLIENT_VERSION = '<%= pkg.version %>a'"))
.replace(/NODE_ADDRESS\s*=\s*'[^']+'/, grunt.template.process("NODE_ADDRESS = '<%= meta.configurations.mainnet.server %>'"))
- .replace(/NETWORK_NAME\s*=\s*'[^']+'/, grunt.template.process("NETWORK_NAME = '<%= meta.configurations.mainnet.name %>'"));
+ .replace(/NETWORK_NAME\s*=\s*'[^']+'/, grunt.template.process("NETWORK_NAME = '<%= meta.configurations.mainnet.name %>'"))
+ .replace(/NETWORK_CODE\s*=\s*'[^']+'/, grunt.template.process("NETWORK_CODE = '<%= meta.configurations.mainnet.code %>'"));
};
// Project configuration.
@@ -24,10 +26,12 @@ module.exports = function (grunt) {
configurations: {
testnet: {
name: 'testnet',
+ code: 'T',
server: 'http://52.30.47.67:6869'
},
mainnet: {
name: 'mainnet',
+ code: 'W',
server: 'https://nodes.wavesnodes.com'
},
chrome: {
diff --git a/js/waves.settings.js b/js/waves.settings.js
index 37b360309f..fec2315a0a 100644
--- a/js/waves.settings.js
+++ b/js/waves.settings.js
@@ -26,6 +26,8 @@ var Waves = (function (Waves) {
Waves.constants.CLIENT_VERSION = '0.4.1a';
Waves.constants.NODE_ADDRESS = 'http://52.30.47.67:6869';
Waves.constants.NETWORK_NAME = 'devel';
+ Waves.constants.ADDRESS_VERSION = 1;
+ Waves.constants.NETWORK_CODE = 'T';
return Waves;
}(Waves || {}));
diff --git a/js/waves.ui.functions.js b/js/waves.ui.functions.js
index 11c0cd78ec..eb4f5bbe5d 100644
--- a/js/waves.ui.functions.js
+++ b/js/waves.ui.functions.js
@@ -326,13 +326,11 @@ var Waves = (function(Waves, $, undefined) {
// additional address validation
var freshKey = Waves.getPublicKey(accountDetails.passphrase);
- Waves.apiRequest(Waves.api.waves.address, freshKey, function(response) {
- var generated = Waves.Addressing.fromRawAddress(response.address);
- var bytes = converters.stringToByteArray(accountDetails.password);
- var id = Base58.encode(Waves.blake2bHash(new Uint8Array(bytes)));
+ var generated = Waves.buildAddress(freshKey);
+ var bytes = converters.stringToByteArray(accountDetails.password);
+ var id = Base58.encode(Waves.blake2bHash(new Uint8Array(bytes)));
- Waves.apiRequest(Waves.api.address.check(Waves.address, generated, id));
- });
+ Waves.apiRequest(Waves.api.address.check(Waves.address, generated, id));
});
}
diff --git a/js/waves.ui.js b/js/waves.ui.js
index a7ed35fae1..36c91db4bc 100644
--- a/js/waves.ui.js
+++ b/js/waves.ui.js
@@ -369,13 +369,11 @@ var Waves = (function(Waves, $, undefined) {
});
$('#header-wPop-backup').on($.modal.BEFORE_OPEN, function() {
- Waves.apiRequest(Waves.api.waves.address, Waves.publicKey, function(response) {
- $('#seedBackup').val(Waves.passphrase);
- $('#encodedSeedBackup').val(Base58.encode(converters.stringToByteArray(Waves.passphrase)));
- $('#privateKeyBackup').val(Waves.privateKey);
- $('#publicKeyBackup').val(Waves.publicKey);
- $("#addressBackup").val(Waves.Addressing.fromRawAddress(response.address).getDisplayAddress());
- });
+ $('#seedBackup').val(Waves.passphrase);
+ $('#encodedSeedBackup').val(Base58.encode(converters.stringToByteArray(Waves.passphrase)));
+ $('#privateKeyBackup').val(Waves.privateKey);
+ $('#publicKeyBackup').val(Waves.publicKey);
+ $("#addressBackup").val(Waves.buildAddress(Waves.publicKey).getDisplayAddress());
});
$('#header-wPop-backup').on($.modal.AFTER_CLOSE, function() {
diff --git a/js/waves.ui.lockscreen.js b/js/waves.ui.lockscreen.js
index 3ba6968ca6..3478bb17ce 100644
--- a/js/waves.ui.lockscreen.js
+++ b/js/waves.ui.lockscreen.js
@@ -97,7 +97,6 @@ var Waves = (function(Waves, $, undefined) {
$("#publicKeyLockscreen").html('');
$("#privateKeyLockscreen").html('');
$("#addresLockscreen").html('');
-
});
//Create new Waves Acount
@@ -125,7 +124,6 @@ var Waves = (function(Waves, $, undefined) {
});
$('#login-wPop-new').on($.modal.CLOSE, function(event, modal) {
-
var passphrase = PassPhraseGenerator.generatePassPhrase();
$("#walletSeed").val(passphrase);
@@ -134,11 +132,8 @@ var Waves = (function(Waves, $, undefined) {
$("#publicKeyLockscreen").html(publicKey);
$("#privateKeyLockscreen").html(privateKey);
-
- Waves.apiRequest(Waves.api.waves.address, publicKey, function(response) {
- $("#addresLockscreen").html(Waves.Addressing.fromRawAddress(response.address).getDisplayAddress());
- NProgress.done();
- });
+ $("#addresLockscreen").html(Waves.buildAddress(publicKey).getDisplayAddress());
+ NProgress.done();
});
$("#close_create_account_modal").on("click", function(){
@@ -163,10 +158,7 @@ var Waves = (function(Waves, $, undefined) {
$("#publicKeyLockscreen").html(publicKey);
$("#privateKeyLockscreen").html(privateKey);
-
- Waves.apiRequest(Waves.api.waves.address, publicKey, function(response) {
- $("#addresLockscreen").html(Waves.Addressing.fromRawAddress(response.address).getDisplayAddress());
- });
+ $("#addresLockscreen").html(Waves.buildAddress(publicKey).getDisplayAddress());
});
$("#generateRandomSeed").on("click", function(e) {
@@ -180,10 +172,7 @@ var Waves = (function(Waves, $, undefined) {
$("#publicKeyLockscreen").html(publicKey);
$("#privateKeyLockscreen").html(privateKey);
-
- Waves.apiRequest(Waves.api.waves.address, publicKey, function(response) {
- $("#addresLockscreen").html(Waves.Addressing.fromRawAddress(response.address).getDisplayAddress());
- });
+ $("#addresLockscreen").html(Waves.buildAddress(publicKey).getDisplayAddress());
});
$(".goBack").on("click", function(e) {
@@ -206,84 +195,75 @@ var Waves = (function(Waves, $, undefined) {
var name = $("#walletName").val();
var password = $("#walletPassword").val();
+ var address = Waves.buildAddress(publicKey);
+ var cipher = Waves.encryptWalletSeed(passphrase, password).toString();
+ var checksum = converters.byteArrayToHexString(Waves.simpleHash(converters.stringToByteArray(passphrase)));
- Waves.apiRequest(Waves.api.waves.address, publicKey, function(response) {
-
- var address = Waves.Addressing.fromRawAddress(response.address);
- var cipher = Waves.encryptWalletSeed(passphrase, password).toString();
- var checksum = converters.byteArrayToHexString(Waves.simpleHash(converters.stringToByteArray(passphrase)));
-
- var accountData = {
- name: name,
- cipher: cipher,
- checksum: checksum,
- publicKey: publicKey,
- address: address.getRawAddress()
- };
+ var accountData = {
+ name: name,
+ cipher: cipher,
+ checksum: checksum,
+ publicKey: publicKey,
+ address: address.getRawAddress()
+ };
- if(Waves.hasLocalStorage) {
-
- var currentAccounts = localStorage.getItem('Waves'+Waves.network);
- currentAccounts = JSON.parse(currentAccounts);
+ if(Waves.hasLocalStorage) {
- if(currentAccounts !== undefined && currentAccounts !== null) {
+ var currentAccounts = localStorage.getItem('Waves'+Waves.network);
+ currentAccounts = JSON.parse(currentAccounts);
- currentAccounts.accounts.push(accountData);
- localStorage.setItem('Waves'+Waves.network, JSON.stringify(currentAccounts));
- $("#wavesAccounts").append('
'+accountData.name+' ' + address.getDisplayAddress());
+ if(currentAccounts !== undefined && currentAccounts !== null) {
- } else {
- var accountArray = { accounts: [accountData] };
- localStorage.setItem('Waves'+Waves.network, JSON.stringify(accountArray));
- $("#wavesAccounts").append('
'+accountData.name+'' + address.getDisplayAddress());
- }
+ currentAccounts.accounts.push(accountData);
+ localStorage.setItem('Waves'+Waves.network, JSON.stringify(currentAccounts));
+ $("#wavesAccounts").append('
'+accountData.name+' ' + address.getDisplayAddress());
} else {
+ var accountArray = { accounts: [accountData] };
+ localStorage.setItem('Waves'+Waves.network, JSON.stringify(accountArray));
+ $("#wavesAccounts").append('
'+accountData.name+'' + address.getDisplayAddress());
+ }
- Waves.getAccounts(function(currentAccounts) {
-
- var saveData = {
- name: name,
- cipher: cipher,
- checksum: checksum,
- publicKey: publicKey,
- address: address.getRawAddress()
- };
+ } else {
- if(currentAccounts !== '') {
+ Waves.getAccounts(function(currentAccounts) {
- currentAccounts = currentAccounts['WavesAccounts'];
+ var saveData = {
+ name: name,
+ cipher: cipher,
+ checksum: checksum,
+ publicKey: publicKey,
+ address: address.getRawAddress()
+ };
- currentAccounts.accounts.push(saveData);
- chrome.storage.sync.set({'WavesAccounts': currentAccounts}, function() {
- // Notify that we saved.
- $.growl.notice({ message: "Added Account!" });
- $("#wavesAccounts").append('
'+saveData.name+' ' + address.getDisplayAddress());
- });
+ if(currentAccounts !== '') {
- } else {
+ currentAccounts = currentAccounts['WavesAccounts'];
- var accountArray = { accounts: [saveData] };
- chrome.storage.sync.set({'WavesAccounts': accountArray}, function() {
- // Notify that we saved.
- $.growl.notice({ message: "Added Account!" });
- $("#wavesAccounts").append('
'+saveData.name+' ' + address.getDisplayAddress());
- });
- }
+ currentAccounts.accounts.push(saveData);
+ chrome.storage.sync.set({'WavesAccounts': currentAccounts}, function() {
+ // Notify that we saved.
+ $.growl.notice({ message: "Added Account!" });
+ $("#wavesAccounts").append('
'+saveData.name+' ' + address.getDisplayAddress());
+ });
- });
-
- }
+ } else {
- accountData.firstTime = true;
- accountData.password = password;
- accountData.passphrase = passphrase;
- passphrase = '';
+ var accountArray = { accounts: [saveData] };
+ chrome.storage.sync.set({'WavesAccounts': accountArray}, function() {
+ // Notify that we saved.
+ $.growl.notice({ message: "Added Account!" });
+ $("#wavesAccounts").append('
'+saveData.name+' ' + address.getDisplayAddress());
+ });
+ }
+ });
+ }
- Waves.login(accountData);
+ accountData.firstTime = true;
+ accountData.password = password;
+ accountData.passphrase = passphrase;
- });
-
+ Waves.login(accountData);
});
Waves.UI.registerForm.setupValidation();
diff --git a/js/waves.util.js b/js/waves.util.js
index d41dd79cb4..54b646051c 100644
--- a/js/waves.util.js
+++ b/js/waves.util.js
@@ -246,6 +246,10 @@ var Waves = (function (Waves, $, undefined) {
};
Waves.MAP = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+
+ var getNetworkIdByte = function() {
+ return Waves.constants.NETWORK_CODE.charCodeAt(0) & 0xFF;
+ }
Waves.getLocalDateFormat = function () {
return Waves.LOCALE_DATE_FORMAT;
@@ -364,6 +368,24 @@ var Waves = (function (Waves, $, undefined) {
return Base58.encode(p.private);
}
+ Waves.buildRawAddress = function (encodedPublicKey) {
+ var publicKey = Base58.decode(encodedPublicKey);
+ var publicKeyHash = this.hashChain(publicKey);
+
+ var prefix = new Uint8Array(2);
+ prefix[0] = Waves.constants.ADDRESS_VERSION;
+ prefix[1] = getNetworkIdByte();
+
+ var unhashedAddress = this.appendUint8Arrays(prefix, publicKeyHash.slice(0, 20));
+ var addressHash = this.hashChain(unhashedAddress).slice(0, 4);
+
+ return Base58.encode(this.appendUint8Arrays(unhashedAddress, addressHash));
+ }
+
+ Waves.buildAddress = function (encodedPublicKey) {
+ return Waves.Addressing.fromRawAddress(this.buildRawAddress(encodedPublicKey));
+ }
+
//Returns publicKey built from string
Waves.getPublicKey = function(secretPhrase) {
return this.buildPublicKey(converters.stringToByteArray(secretPhrase));
diff --git a/tests/spec/waves.util.spec.js b/tests/spec/waves.util.spec.js
index 05b003271c..f64af10b16 100755
--- a/tests/spec/waves.util.spec.js
+++ b/tests/spec/waves.util.spec.js
@@ -54,4 +54,32 @@ describe("waves.util", function() {
signature = Waves.nonDeterministicSign(privateKey, messageBytes);
expect(Waves.verify(publicKey, messageBytes, Base58.decode(signature))).toBe(true);
});
+
+ it("should generate network addresses locally", function() {
+ // testing testnet address generation
+ Waves.constants.NETWORK_CODE = 'T';
+ expect(Waves.buildRawAddress("5ug8nQ1ubfjAZVJFed4mcXVVEBz53DfV8nBQWuKbt2AJ"))
+ .toEqual("3Mtkz8KeXUZmTbNH1MFcrMGv4t1av5tmaFL");
+ expect(Waves.buildRawAddress("9iDrC31brcunVTRCq69iUngg1S5Ai1rd6iX7vTwAGTvn"))
+ .toEqual("3N33kaYS3C9pvVsVjLKLApmRQHfzm3UY36N");
+ expect(Waves.buildRawAddress("Dq5f76Ro3qQCPWSDrCNrVDCiKwNFKCP2UmnVZzPxVf8"))
+ .toEqual("3NBmgsTgGv8nfmYzbCiKvTuBJtDpVyyxqKr");
+ expect(Waves.buildRawAddress("6tk94Rwij3FXwfaJLWu9PhQAHDY2MUjPLYkHQ28HaRk3"))
+ .toEqual("3MstHyC4tKtBhzbWdhrJ3jkxPD1hYSJCi77");
+ expect(Waves.buildRawAddress("2oGDrLRdBsU9Nb32jgPMh3TrQXm9QifUBLnLijfWqY5e"))
+ .toEqual("3MzUpwpiNTr32YWoYVmRFyzJQgdDbti3shP");
+ expect(Waves.buildRawAddress("71m88eJxbfJnNPW87r4Qtrp9Q2qa1wsLYmrxXRAzLPF6"))
+ .toEqual("3MwJXUURjZY2BmbMDRMwgGnJ19RZC9Hdg3V");
+ expect(Waves.buildRawAddress("7Ftuept6hfNEhSeVA439asPWZQVuteqWQUEPz6RGHsAo"))
+ .toEqual("3MpETHR7opAMN6dWqJejq1X37YCkq6Nu5hK");
+ expect(Waves.buildRawAddress("AEYsMR1171SmhV77rDtBTyfjmFubzirpHqFH4hV1aDt9"))
+ .toEqual("3MyciTA8STrTWjZ46KdoZ1ASf5GuY7sD8be");
+
+ // testing mainnet address generation
+ Waves.constants.NETWORK_CODE = 'W';
+ expect(Waves.buildRawAddress("D1vnz91YRXyDM72R6ZsPZfj1woMzL5nZtFrfeGQYjMs6"))
+ .toEqual("3PKGL4nMz3sMESQXPzmX5GKbiQtCi2Tu9Z5");
+ expect(Waves.buildRawAddress("9Emin4uvu2cew67hkpkX2ZKV6NJEjyP7Uvzbf8ARMCc6"))
+ .toEqual("3P9oRcFxwjW58bqu1oXyk1JrRTy8ADSKvdN");
+ });
});