Skip to content

Commit

Permalink
Add way to encode/decode addresses from binary (#216)
Browse files Browse the repository at this point in the history
* Add way to encode/decode addresses from binary
  • Loading branch information
jasonpaulos authored Sep 25, 2020
1 parent 6f3d3a7 commit 3a052ea
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Example result
"gorilla fortune learn marble essay uphold defense hover index effort ice atom figure will improve mom indoor mansion people elder hill material donkey abandon gown"
```
#### Mnemonic to secret sey
#### Mnemonic to secret key
```javascript
var secret_key = algosdk.mnemonicToSecretKey(mnemonic);
```
Expand All @@ -75,6 +75,28 @@ Example result
true
```
#### Encode/decode addresses
These two functions let you convert addresses between their string and binary representations.
```javascript
var decoded = algosdk.decodeAddress("IB3NJALXLDX5JLYCD4TMTMLVCKDRZNS4JONHMIWD6XM7DSKYR7MWHI6I7U");
var encoded = algosdk.encodeAddress(decoded.publicKey);
console.log('Decoded:', decoded);
console.log('Encoded:', encoded);
```
Result
```text
Decoded: {
publicKey: Uint8Array(32) [
64, 118, 212, 129, 119, 88, 239, 212,
175, 2, 31, 38, 201, 177, 117, 18,
135, 28, 182, 92, 75, 154, 118, 34,
195, 245, 217, 241, 201, 88, 143, 217
],
checksum: Uint8Array(4) [ 99, 163, 200, 253 ]
}
Encoded: IB3NJALXLDX5JLYCD4TMTMLVCKDRZNS4JONHMIWD6XM7DSKYR7MWHI6I7U
```
#### Sign a transaction
In order to create and sign a transaction, create first an object with the relevant properties.
There is no need to specify the `from` address, it is computed directly from the secretKey.
Expand Down
22 changes: 21 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,31 @@ function generateAccount() {

/**
* isValidAddress takes an Algorand address and checks if valid.
* @param addr Algorand address
* @param {string} addr Algorand address
* @returns {boolean} true if valid, false otherwise
*/
function isValidAddress(addr) {
return address.isValidAddress(addr);
}

/**
* encodeAddress takes an Algorand address as a Uint8Array and encodes it into a string with checksum.
* @param {Uint8Array} addr a raw Algorand address
* @returns {string} the address and checksum encoded as a string.
*/
function encodeAddress(addr) {
return address.encode(addr);
}

/**
* decodeAddress takes an Algorand address in string form and decodes it into a Uint8Array.
* @param {string} addr an Algorand address with checksum.
* @returns {{publicKey: Uint8Array, checksum: Uint8Array}} the decoded form of the address's public key and checksum
*/
function decodeAddress(addr) {
return address.decode(addr)
}

/**
* mnemonicToSecretKey takes a mnemonic string and returns the corresponding Algorand address and its secret key.
* @param mn 25 words Algorand mnemonic
Expand Down Expand Up @@ -1181,6 +1199,8 @@ function makeApplicationNoOpTxn(from, suggestedParams, appIndex,

module.exports = {
isValidAddress,
encodeAddress,
decodeAddress,
generateAccount,
secretKeyToMnemonic,
mnemonicToSecretKey,
Expand Down
23 changes: 12 additions & 11 deletions tests/3.Address.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
let assert = require('assert');
let nacl = require("../src/nacl/naclWrappers");
let address = require("../src/encoding/address");
let algosdk = require("../src/main");

describe('address', function () {
describe('#isValid', function () {
it('should verify a valid Algorand address', function () {
assert.ok(address.isValidAddress("MO2H6ZU47Q36GJ6GVHUKGEBEQINN7ZWVACMWZQGIYUOE3RBSRVYHV4ACJI"));
assert.ok(algosdk.isValidAddress("MO2H6ZU47Q36GJ6GVHUKGEBEQINN7ZWVACMWZQGIYUOE3RBSRVYHV4ACJI"));
});

it('should fail to verify an invalid Algorand address', function () {
assert.strictEqual(address.isValidAddress("MO2H6ZU47Q36GJ6GVHUKGEBEQINN7ZWVACMWZQGIYUOE3RBSRVYHV4ACJG"), false);
assert.strictEqual(algosdk.isValidAddress("MO2H6ZU47Q36GJ6GVHUKGEBEQINN7ZWVACMWZQGIYUOE3RBSRVYHV4ACJG"), false);
});
});

describe('encode, decode', function () {
it('should be able to encode and verify an address', function () {
let pk = nacl.randomBytes(32);
let addr = address.encode(pk);
assert.ok(address.isValidAddress(addr));
let addr = algosdk.encodeAddress(pk);
assert.ok(algosdk.isValidAddress(addr));
});

it('should be able to encode and decode an address', function () {
let pk = nacl.randomBytes(32);
let addr = address.encode(pk);
let d = address.decode(addr);
let addr = algosdk.encodeAddress(pk);
let d = algosdk.decodeAddress(addr);
assert.deepStrictEqual(new Uint8Array(d.publicKey), pk);
});
});

describe('from multisig preimage', function () {
it('should match main repo code', function () {
const addr1 = address.decode("XMHLMNAVJIMAW2RHJXLXKKK4G3J3U6VONNO3BTAQYVDC3MHTGDP3J5OCRU");
const addr2 = address.decode("HTNOX33OCQI2JCOLZ2IRM3BC2WZ6JUILSLEORBPFI6W7GU5Q4ZW6LINHLA");
const addr3 = address.decode("E6JSNTY4PVCY3IRZ6XEDHEO6VIHCQ5KGXCIQKFQCMB2N6HXRY4IB43VSHI");
const addr1 = algosdk.decodeAddress("XMHLMNAVJIMAW2RHJXLXKKK4G3J3U6VONNO3BTAQYVDC3MHTGDP3J5OCRU");
const addr2 = algosdk.decodeAddress("HTNOX33OCQI2JCOLZ2IRM3BC2WZ6JUILSLEORBPFI6W7GU5Q4ZW6LINHLA");
const addr3 = algosdk.decodeAddress("E6JSNTY4PVCY3IRZ6XEDHEO6VIHCQ5KGXCIQKFQCMB2N6HXRY4IB43VSHI");
const params = {
version: 1,
threshold: 2,
pks: [addr1.publicKey, addr2.publicKey, addr3.publicKey],
};
const expectAddr = "UCE2U2JC4O4ZR6W763GUQCG57HQCDZEUJY4J5I6VYY4HQZUJDF7AKZO5GM";
let actualAddr = address.fromMultisigPreImg(params);
let actualAddrEnc = address.encode(actualAddr);
assert.ok(address.isValidAddress(actualAddrEnc));
let actualAddrEnc = algosdk.encodeAddress(actualAddr);
assert.ok(algosdk.isValidAddress(actualAddrEnc));
assert.deepStrictEqual(actualAddrEnc, expectAddr);
});
})
Expand Down

0 comments on commit 3a052ea

Please sign in to comment.