Skip to content

Commit 3596ea1

Browse files
author
Fabrice Bascoulergue
committed
Implement testnet and update documentation plus unittests
1 parent 090814c commit 3596ea1

File tree

3 files changed

+113
-35
lines changed

3 files changed

+113
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The SDK is based on the [CosmJS](https://github.com/cosmos/cosmjs) implementatio
6565

6666
It is intented to be used standalone, without having to import specific CosmJS packages which can get make implementations tricky and messy.
6767

68-
Therefore all codecs, types, functions are features from the CosmJS SDK are either re-implemented by this SDK or re-exporter for simplicity purposes.
68+
Therefore all codecs, types, functions are features from the CosmJS SDK are either re-implemented by this SDK or re-exported for simplicity purposes.
6969

7070
Directly importing the CosmJS SDK or other cryptographic library should be considered bad practice for most use cases.
7171

docs/README.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ console.log(`Wallet address: ${wallet.address}`);
6060
### Connect to the testnet
6161

6262
```typescript
63-
const testnetClient = await LumClient.connect('http://localhost:26657');
63+
// Use http://node0.lum.network/rpc to connect to the mainnet
64+
const testnetClient = await LumClient.connect('http://node0.testnet.lum.network/rpc');
6465
```
6566

6667
### Account information & balance
@@ -93,7 +94,7 @@ if (balances.length === 0) {
9394

9495
#### Get account transactions (sent and received)
9596
```typescript
96-
// The client search feature supports multiple searches and merge+store the results
97+
// The client search feature supports multiple searches and merge+sort the results
9798
const transactions = await testnetClient.searchTx([
9899
LumUtils.searchTxFrom(wallet.address),
99100
LumUtils.searchTxTo(wallet.address),
@@ -119,3 +120,25 @@ const broadcastResult = await clt.signAndBroadcastTx(w1, [sendMsg], fee, 'hello
119120
// Verify the transaction was succesfully broadcasted and made it into a block
120121
console.log(`Broadcast success: ${LumUtils.broadcastTxCommitSuccess(broadcastResult)}`);
121122
```
123+
124+
### Use all tendermint RPCs
125+
126+
The underlying tendermint client is directly accessible via the `.tmClient` property of the LumClient.
127+
128+
```typescript
129+
const health = await testnetClient.tmClient.health();
130+
const status = await testnetClient.tmClient.status();
131+
const genesis = await testnetClient.tmClient.genesis();
132+
const latestBlock = await testnetClient.tmClient.block();
133+
```
134+
135+
### Use all modules RPCs
136+
137+
The underlying query client is directly accessible via the `.queryClient` property of the LumClient.
138+
139+
It allows to directly query all modules endpoints such as:
140+
141+
```typescript
142+
const supplies = await clt.queryClient.bank.unverified.totalSupply();
143+
// [{ denom: 'lum', amount: '1000000' }]
144+
```

tests/client.test.ts

Lines changed: 87 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,93 @@
1-
import { LumWallet, LumConstants } from '../src';
1+
import { LumWallet, LumClient, LumUtils, LumConstants, LumRegistry, LumTypes } from '../src';
2+
3+
const genesisAccountAddress = 'lum100hm4tt3z3mj4gc453quvu452dcp2ehqavrtlp';
4+
const genesisValidatorAddress = '23D45E13FF3418D23DF989D78EBE6DE76F3A89EC';
25

36
describe('LumClient', () => {
4-
it('Should connect', async () => {
5-
const w1 = await LumWallet.fromMnemonic('noodle hope lounge dismiss erase elephant seek crawl check equal city chest', LumConstants.getLumHdPath(0), 'cosmos');
6-
const w2 = await LumWallet.fromMnemonic('sick hollow lizard train motion eternal mixture rude section tray nice awful', LumConstants.getLumHdPath(0), 'cosmos');
7+
let clt: LumClient;
8+
let w1: LumWallet;
9+
let w2: LumWallet;
10+
11+
beforeAll(async () => {
12+
clt = await LumClient.connect('http://node0.testnet.lum.network/rpc');
13+
w1 = await LumWallet.fromMnemonic('noodle hope lounge dismiss erase elephant seek crawl check equal city chest');
14+
w2 = await LumWallet.fromMnemonic('sick hollow lizard train motion eternal mixture rude section tray nice awful');
715
expect(w1.address).not.toEqual(w2.address);
16+
});
17+
18+
afterAll(async () => {
19+
await expect(clt.disconnect()).resolves.toBeTruthy();
20+
});
21+
22+
it('Should expose basic information', async () => {
23+
expect(clt.getChainId()).resolves.toEqual('lumnetwork'); // TODO: will be update to lumnetwork-testnet
24+
expect(clt.getBlockHeight()).resolves.toBeGreaterThan(0);
25+
expect(clt.getBlock()).resolves.toBeTruthy();
26+
});
27+
28+
it('should expose tendermint rpcs', async () => {
29+
expect(clt.tmClient.health()).resolves.toBeNull();
30+
expect(clt.tmClient.status()).resolves.toBeTruthy();
31+
expect(clt.tmClient.genesis()).resolves.toBeTruthy();
32+
expect(clt.tmClient.abciInfo()).resolves.toBeTruthy();
33+
expect(clt.tmClient.block()).resolves.toBeTruthy();
34+
expect(clt.tmClient.blockResults()).resolves.toBeTruthy();
35+
expect(clt.tmClient.blockchain()).resolves.toBeTruthy();
36+
expect(clt.tmClient.validatorsAll()).resolves.toBeTruthy();
37+
});
38+
39+
it('Should expose bank module', async () => {
40+
const supplies = await clt.queryClient.bank.unverified.totalSupply();
41+
expect(supplies).toBeTruthy();
42+
expect(supplies.length).toBeGreaterThan(0);
43+
const lumSupply = supplies.filter((c) => c.denom === LumConstants.LumDenom)[0];
44+
expect(lumSupply).toBeTruthy();
45+
expect(parseFloat(lumSupply.amount)).toBeGreaterThan(0);
46+
});
47+
48+
it('Should expose staking module', async () => {
49+
const validators = await clt.tmClient.validatorsAll();
50+
expect(validators.validators.length).toBeGreaterThanOrEqual(1);
51+
const block = await clt.getBlock();
52+
let found = false;
53+
for (let v = 0; v < validators.validators.length; v++) {
54+
const val = validators.validators[v];
55+
if (LumUtils.toHex(val.address) === LumUtils.toHex(block.block.header.proposerAddress)) {
56+
found = true;
57+
break;
58+
}
59+
}
60+
expect(found).toBeTruthy();
61+
62+
// Get boot val (genesis) with address genesisValidatorAddress
63+
const bootVal = validators.validators.filter((v) => LumUtils.toHex(v.address).toUpperCase() === genesisValidatorAddress)[0];
64+
expect(bootVal).toBeTruthy();
65+
66+
// Get staking validator by matching it using pubkeys
67+
const stakers = await clt.queryClient.staking.unverified.validators('BOND_STATUS_BONDED');
68+
const bootStak = stakers.validators.filter((s) => LumUtils.toHex((LumRegistry.decode(s.consensusPubkey) as LumTypes.PubKey).key) === LumUtils.toHex(bootVal.pubkey.data))[0];
69+
expect(bootVal).toBeTruthy();
70+
71+
// Get account information by deriving the address from the operator address
72+
const delegAddress = LumUtils.Bech32.encode(LumConstants.LumBech32PrefixAccAddr, LumUtils.Bech32.decode(bootStak.operatorAddress).data);
73+
const account = await clt.getAccount(delegAddress);
74+
expect(account).toBeTruthy();
75+
76+
// Get account balances
77+
const balances = await clt.getAllBalancesUnverified(account.address);
78+
expect(balances).toBeTruthy();
79+
expect(balances.length).toBeGreaterThan(0);
80+
const lumBalance = balances.filter((b) => b.denom === LumConstants.LumDenom)[0];
81+
expect(lumBalance).toBeTruthy();
82+
expect(parseFloat(lumBalance.amount)).toBeGreaterThan(0);
83+
});
884

9-
// Can connect to Cosmos testnet for compatibility checks:
10-
// https://stargate.cosmos.network/testnet
11-
// const clt = await LumClient.connect('http://localhost:26657');
12-
// console.log('wallet address', w1.address);
13-
// console.log('getChainId', await clt.getChainId());
14-
// console.log('getBlockHeight', await clt.getBlockHeight());
15-
// console.log('getBlock', await clt.getBlock());
16-
// console.log('getAccount', await clt.getAccount(w1.address));
17-
// console.log('getAccountUnverified', await clt.getAccountUnverified(w1.address));
18-
// console.log('getBalance', await clt.getBalance(w1.address, 'token'));
19-
// console.log('getBalancesUnverified', await clt.getBalancesUnverified(w1.address));
20-
// const txs = await clt.searchTx([LumUtils.searchTxFrom(w1.address), LumUtils.searchTxTo(w1.address)]);
21-
// console.log('getTx', await clt.getTx(txs[0].hash));
22-
// console.log('searchTxs', txs);
23-
// const sendMsg = LumMessages.BuildMsgSend(w1.address, w2.address, [{ denom: 'token', amount: '2' }]);
24-
// const res = await clt.signAndBroadcastTx(w1, [sendMsg], {
25-
// amount: [
26-
// {
27-
// denom: 'token',
28-
// amount: '1',
29-
// },
30-
// ],
31-
// gas: '180000', // 180k
32-
// });
33-
// console.log('signAndBroadcastTx', LumUtils.broadcastTxCommitSuccess(res), res);
34-
// console.log('getBalance(w1)', await clt.getBalance(w1.address, 'token'));
35-
// console.log('getBalance(w2)', await clt.getBalance(w2.address, 'token'));
36-
// WIP - needs to be automated through CICD
85+
it('Should expose distribution module', async () => {
86+
const deleg = await clt.queryClient.distribution.unverified.delegatorWithdrawAddress(genesisAccountAddress);
87+
expect(deleg).toBeTruthy();
88+
expect(deleg.withdrawAddress).toEqual(genesisAccountAddress);
89+
const validators = await clt.queryClient.distribution.unverified.delegatorValidators(genesisAccountAddress);
90+
expect(validators).toBeTruthy();
91+
expect(validators.validators.length).toBeGreaterThan(0);
3792
});
3893
});

0 commit comments

Comments
 (0)