Skip to content
This repository was archived by the owner on Apr 15, 2022. It is now read-only.

Commit df5373c

Browse files
author
Booyoun
authored
Merge pull request #8 from cosmostation/develop
Develop
2 parents c32b4b0 + 1148f98 commit df5373c

File tree

4 files changed

+84
-12
lines changed

4 files changed

+84
-12
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ Generate Cosmos address from mnemonic
5757
const cosmosjs = require("@cosmostation/cosmosjs");
5858

5959
const chainId = "chain-id";
60-
const cosmos = cosmosjs.network(chainId)
60+
const cosmos = cosmosjs.network(lcdUrl, chainId)
6161

6262
const mnemonic = "..."
63+
cosmos.setPath("m/44'/118'/0'/0/0");
6364
const address = cosmos.getAddress(mnemonic);
6465
const ecpairPriv = cosmos.getECPairPriv(mnemonic);
6566
```
@@ -93,12 +94,14 @@ cosmos.getAccounts(address).then(data => {
9394
```
9495

9596
Sign transaction by using stdSignMsg and broadcast by using [/txs](https://lcd-do-not-abuse.cosmostation.io/txs) REST API
96-
* API Call Limit: 10 per second
9797
```js
9898
const signedTx = cosmos.sign(stdSignMsg, ecpairPriv);
9999
cosmos.broadcast(signedTx).then(response => console.log(response));
100100
```
101101

102+
Cosmostation offers LCD url(https://lcd-do-not-abuse.cosmostation.io).
103+
* API Rate Limiting: 10 requests per second
104+
102105
## Supporting Message Types (Updating...)
103106

104107
- MsgSend
@@ -229,6 +232,20 @@ stdSignMsg = cosmos.NewStdMsg({
229232
sequence: data.value.sequence
230233
});
231234
```
235+
- MsgModifyWithdrawAddress
236+
```js
237+
stdSignMsg = cosmos.NewStdMsg({
238+
type: "cosmos-sdk/MsgModifyWithdrawAddress",
239+
delegator_address: address,
240+
withdraw_address: "cosmos133mtfk63fuac5e2npfgcktwufnty2536wedfal",
241+
feeDenom: "uatom",
242+
fee: 5000,
243+
gas: 200000,
244+
memo: "",
245+
account_number: data.value.account_number,
246+
sequence: data.value.sequence
247+
});
248+
```
232249

233250
## Documentation
234251

example/cosmos.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const cosmosjs = require("../src");
44
const mnemonic = "swear buyer security impulse public stereo peasant correct cross tornado bid discover anchor float venture deal patch property cool wreck eight dwarf december surface";
55
const chainId = "cosmoshub-2";
66
const cosmos = cosmosjs.network("https://lcd-do-not-abuse.cosmostation.io", chainId);
7+
cosmos.setPath("m/44'/118'/0'/0/0");
78
const address = cosmos.getAddress(mnemonic);
89
const ecpairPriv = cosmos.getECPairPriv(mnemonic);
910

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cosmostation/cosmosjs",
3-
"version": "0.2.0",
3+
"version": "0.2.2",
44
"description": "A javascript open source library for Cosmos Network.",
55
"main": "./src/index.js",
66
"engines": {

src/index.js

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ const secp256k1 = require('secp256k1');
1414
const crypto = require('crypto');
1515
const bitcoinjs = require('bitcoinjs-lib');
1616

17-
const PATH = "m/44'/118'/0'/0/0";
18-
19-
let Cosmos = function (url, chainId) {
17+
let Cosmos = function(url, chainId) {
2018
this.url = url;
2119
this.chainId = chainId;
20+
this.path = "m/44'/118'/0'/0/0";
21+
this.bech32MainPrefix = "cosmos";
2222

2323
if (!this.url) {
2424
throw new Error("url object was not set or invalid")
@@ -49,6 +49,34 @@ function getPubKeyBase64(ecpairPriv) {
4949
return Buffer.from(pubKeyByte, 'binary').toString('base64');
5050
}
5151

52+
function sortObject(obj) {
53+
if (obj === null) return null;
54+
if (typeof obj !== "object") return obj;
55+
if (Array.isArray(obj)) return obj.map(sortObject);
56+
const sortedKeys = Object.keys(obj).sort();
57+
const result = {};
58+
sortedKeys.forEach(key => {
59+
result[key] = sortObject(obj[key])
60+
});
61+
return result;
62+
}
63+
64+
Cosmos.prototype.setBech32MainPrefix = function(bech32MainPrefix) {
65+
this.bech32MainPrefix = bech32MainPrefix;
66+
67+
if (!this.bech32MainPrefix) {
68+
throw new Error("bech32MainPrefix object was not set or invalid")
69+
}
70+
}
71+
72+
Cosmos.prototype.setPath = function(path) {
73+
this.path = path;
74+
75+
if (!this.path) {
76+
throw new Error("path object was not set or invalid")
77+
}
78+
}
79+
5280
Cosmos.prototype.getAccounts = function(address) {
5381
return fetch(this.url + "/auth/accounts/" + address)
5482
.then(response => response.json())
@@ -60,9 +88,9 @@ Cosmos.prototype.getAddress = function(mnemonic) {
6088
}
6189
const seed = bip39.mnemonicToSeed(mnemonic);
6290
const node = bip32.fromSeed(seed);
63-
const child = node.derivePath(PATH);
91+
const child = node.derivePath(this.path);
6492
const words = bech32.toWords(child.identifier);
65-
return bech32.encode('cosmos', words);
93+
return bech32.encode(this.bech32MainPrefix, words);
6694
}
6795

6896
Cosmos.prototype.getECPairPriv = function(mnemonic) {
@@ -71,7 +99,7 @@ Cosmos.prototype.getECPairPriv = function(mnemonic) {
7199
}
72100
const seed = bip39.mnemonicToSeed(mnemonic);
73101
const node = bip32.fromSeed(seed);
74-
const child = node.derivePath(PATH);
102+
const child = node.derivePath(this.path);
75103
const ecpair = bitcoinjs.ECPair.fromPrivateKey(child.privateKey, {compressed : false})
76104
return ecpair.privateKey;
77105
}
@@ -82,7 +110,7 @@ Cosmos.prototype.NewStdMsg = function(input) {
82110
if (input.type == "cosmos-sdk/MsgSend") {
83111
stdSignMsg.json =
84112
{
85-
account_number: String(input.account_number),
113+
account_number: String(input.account_number),
86114
chain_id: this.chainId,
87115
fee: {
88116
amount: [
@@ -321,18 +349,44 @@ Cosmos.prototype.NewStdMsg = function(input) {
321349
],
322350
sequence: String(input.sequence)
323351
}
352+
} else if (input.type == "cosmos-sdk/MsgModifyWithdrawAddress") {
353+
stdSignMsg.json =
354+
{
355+
account_number: String(input.account_number),
356+
chain_id: this.chainId,
357+
fee: {
358+
amount: [
359+
{
360+
amount: String(input.fee),
361+
denom: input.feeDenom
362+
}
363+
],
364+
gas: String(input.gas)
365+
},
366+
memo: input.memo,
367+
msgs: [
368+
{
369+
type: input.type,
370+
value: {
371+
delegator_address: input.delegator_address,
372+
withdraw_address: input.withdraw_address
373+
}
374+
}
375+
],
376+
sequence: String(input.sequence)
377+
}
324378
} else {
325379
throw new Error("No such input.type: " + input.type)
326380
}
327381

328-
stdSignMsg.bytes = convertStringToBytes(JSON.stringify(stdSignMsg.json));
382+
stdSignMsg.bytes = convertStringToBytes(JSON.stringify(sortObject(stdSignMsg.json)));
329383

330384
return stdSignMsg;
331385
}
332386

333387
Cosmos.prototype.sign = function(stdSignMsg, ecpairPriv, modeType = "sync") {
334388
// The supported return types includes "block"(return after tx commit), "sync"(return afer CheckTx) and "async"(return right away).
335-
const hash = crypto.createHash('sha256').update(JSON.stringify(stdSignMsg.json)).digest('hex');
389+
const hash = crypto.createHash('sha256').update(JSON.stringify(sortObject(stdSignMsg.json))).digest('hex');
336390
const buf = Buffer.from(hash, 'hex');
337391
let signObj = secp256k1.sign(buf, ecpairPriv);
338392
var signatureBase64 = Buffer.from(signObj.signature, 'binary').toString('base64');

0 commit comments

Comments
 (0)