Skip to content

Commit 451adee

Browse files
authoredAug 4, 2020
feat: Stake (#279)
* feat: add basic stake function * docs: update docs
1 parent 00c5957 commit 451adee

File tree

10 files changed

+507
-0
lines changed

10 files changed

+507
-0
lines changed
 

‎__tests__/stake.test.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { getClient, address } from "./utils"
2+
3+
describe("stake management", () => {
4+
beforeEach(() => {
5+
jest.setTimeout(50000)
6+
})
7+
8+
it("bsc delegate", async () => {
9+
const client = await getClient(true)
10+
const validatorAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"
11+
12+
try {
13+
const res = await client.stake.bscDelegate({
14+
delegateAddress: address,
15+
validatorAddress,
16+
amount: 10,
17+
})
18+
expect(res.status).toBe(200)
19+
} catch (err) {
20+
if (err.message.includes("insufficient fund")) {
21+
expect(1).toBeTruthy()
22+
}
23+
throw err
24+
}
25+
})
26+
27+
it("bsc undelegate", async () => {
28+
const client = await getClient(true)
29+
const validatorAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"
30+
31+
try {
32+
const res = await client.stake.bscUndelegate({
33+
delegateAddress: address,
34+
validatorAddress,
35+
amount: 10,
36+
})
37+
expect(res.status).toBe(200)
38+
} catch (err) {
39+
if (err.message.includes("insufficient fund")) {
40+
expect(1).toBeTruthy()
41+
}
42+
throw err
43+
}
44+
})
45+
46+
it("bsc redelegate", async () => {
47+
const client = await getClient(true)
48+
const validatorSrcAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"
49+
const validatorDstAddress = "bva1pcd6muhehuz6fy05wfhq9sd5fww6ggdap3adxg"
50+
try {
51+
const res = await client.stake.bscReDelegate({
52+
delegateAddress: address,
53+
validatorSrcAddress,
54+
validatorDstAddress,
55+
amount: 10,
56+
})
57+
expect(res.status).toBe(200)
58+
} catch (err) {
59+
if (err.message.includes("insufficient fund")) {
60+
expect(1).toBeTruthy()
61+
}
62+
throw err
63+
}
64+
})
65+
})

‎docs/api-docs/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* [Bridge](classes/bridge.md)
1010
* [LedgerApp](classes/ledgerapp.md)
1111
* [RpcClient](classes/rpcclient.md)
12+
* [Stake](classes/stake.md)
1213
* [TokenManagement](classes/tokenmanagement.md)
1314
* [Transaction](classes/transaction.md)
1415

‎docs/api-docs/classes/stake.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
# Class: Stake
3+
4+
Stake
5+
6+
## Hierarchy
7+
8+
* **Stake**
9+
10+
## Index
11+
12+
### Constructors
13+
14+
* [constructor](stake.md#constructor)
15+
16+
## Constructors
17+
18+
### constructor
19+
20+
\+ **new Stake**(`bncClient`: [BncClient](bncclient.md)): *[Stake](stake.md)*
21+
22+
**Parameters:**
23+
24+
Name | Type | Description |
25+
------ | ------ | ------ |
26+
`bncClient` | [BncClient](bncclient.md) | |
27+
28+
**Returns:** *[Stake](stake.md)*

‎src/client/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Gov from "./gov"
1212
import Swap from "./swap"
1313
import TokenManagement, { validateMiniTokenSymbol } from "./token"
1414
import { Bridge } from "./bridge"
15+
import { Stake } from "./stake"
1516

1617
const BASENUMBER = Math.pow(10, 8)
1718

@@ -145,6 +146,7 @@ export class BncClient {
145146
public swap: Swap
146147
public gov: Gov
147148
public bridge: Bridge
149+
public stake: Stake
148150
public chainId?: string | null
149151
public addressPrefix: typeof NETWORK_PREFIX_MAPPING[keyof typeof NETWORK_PREFIX_MAPPING] =
150152
"tbnb"
@@ -173,6 +175,7 @@ export class BncClient {
173175
this.swap = new Swap(this)
174176
this.gov = new Gov(this)
175177
this.bridge = new Bridge(this)
178+
this.stake = new Stake(this)
176179
}
177180

178181
/**
@@ -816,6 +819,7 @@ export class BncClient {
816819
sequence: typeof sequence !== "number" ? parseInt(sequence!) : sequence,
817820
source: this._source,
818821
})
822+
819823
return this._signingDelegate.call(this, tx, stdSignMsg)
820824
}
821825

‎src/client/stake/index.ts

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import Big from "big.js"
2+
3+
import { BncClient } from "../"
4+
import * as crypto from "../../crypto"
5+
import {
6+
BscDelegateMsg,
7+
BaseMsg,
8+
BscUndelegateMsg,
9+
BscReDelegateMsg,
10+
} from "../../types"
11+
12+
/**
13+
* Stake
14+
*/
15+
export class Stake {
16+
private _bncClient!: BncClient
17+
18+
/**
19+
* @param {BncClient} bncClient
20+
*/
21+
constructor(bncClient: BncClient) {
22+
this._bncClient = bncClient
23+
}
24+
25+
public async bscDelegate({
26+
delegateAddress,
27+
validatorAddress,
28+
amount,
29+
symbol = "BNB",
30+
sideChainId = "chapel", //default value is ganges(testnet)
31+
}: {
32+
delegateAddress: string
33+
validatorAddress: string
34+
amount: number
35+
symbol?: string
36+
sideChainId?: string
37+
}) {
38+
if (!amount) {
39+
throw new Error("amount should not be empty")
40+
}
41+
42+
if (!delegateAddress) {
43+
throw new Error("delegate address should not be null")
44+
}
45+
46+
if (!crypto.checkAddress(validatorAddress, "bva")) {
47+
throw new Error("validator address is not valid")
48+
}
49+
50+
amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())
51+
52+
const bscDelegateMsg = new BscDelegateMsg({
53+
delegator_addr: delegateAddress,
54+
validator_addr: validatorAddress,
55+
delegation: { denom: symbol, amount },
56+
side_chain_id: sideChainId,
57+
})
58+
59+
return await this.broadcast(bscDelegateMsg, delegateAddress)
60+
}
61+
62+
public async bscUndelegate({
63+
delegateAddress,
64+
validatorAddress,
65+
amount,
66+
symbol = "BNB",
67+
sideChainId = "chapel", //default value is ganges(testnet)
68+
}: {
69+
delegateAddress: string
70+
validatorAddress: string
71+
amount: number
72+
symbol?: string
73+
sideChainId?: string
74+
}) {
75+
if (!amount) {
76+
throw new Error("amount should not be empty")
77+
}
78+
79+
if (!delegateAddress) {
80+
throw new Error("delegate address should not be null")
81+
}
82+
83+
if (!crypto.checkAddress(validatorAddress, "bva")) {
84+
throw new Error("validator address is not valid")
85+
}
86+
87+
amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())
88+
89+
const unDelegateMsg = new BscUndelegateMsg({
90+
delegator_addr: delegateAddress,
91+
validator_addr: validatorAddress,
92+
amount: { denom: symbol, amount },
93+
side_chain_id: sideChainId,
94+
})
95+
96+
return await this.broadcast(unDelegateMsg, delegateAddress)
97+
}
98+
99+
public async bscReDelegate({
100+
delegateAddress,
101+
validatorSrcAddress,
102+
validatorDstAddress,
103+
amount,
104+
symbol = "BNB",
105+
sideChainId = "chapel", //default value is ganges(testnet)
106+
}: {
107+
delegateAddress: string
108+
validatorSrcAddress: string
109+
validatorDstAddress: string
110+
amount: number
111+
symbol?: string
112+
sideChainId?: string
113+
}) {
114+
if (!amount) {
115+
throw new Error("amount should not be empty")
116+
}
117+
118+
if (!delegateAddress) {
119+
throw new Error("delegate address should not be null")
120+
}
121+
122+
if (!crypto.checkAddress(validatorSrcAddress, "bva")) {
123+
throw new Error("validator source address is not valid")
124+
}
125+
126+
if (!crypto.checkAddress(validatorDstAddress, "bva")) {
127+
throw new Error("validator dest address is not valid")
128+
}
129+
130+
amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())
131+
132+
const bscReDelegateMsg = new BscReDelegateMsg({
133+
delegator_addr: delegateAddress,
134+
validator_src_addr: validatorSrcAddress,
135+
validator_dst_addr: validatorDstAddress,
136+
amount: { denom: symbol, amount },
137+
side_chain_id: sideChainId,
138+
})
139+
140+
return await this.broadcast(bscReDelegateMsg, delegateAddress)
141+
}
142+
143+
private async broadcast(
144+
msg: BaseMsg,
145+
fromAddress: string,
146+
sequence?: number
147+
) {
148+
const signedTx = await this._bncClient._prepareTransaction(
149+
msg.getMsg(),
150+
msg.getSignMsg(),
151+
fromAddress,
152+
sequence
153+
)
154+
return this._bncClient._broadcastDelegate(signedTx)
155+
}
156+
}

‎src/types/msg/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from "./dex"
33
export * from "./token"
44
export * from "./send"
55
export * from "./claim"
6+
export * from "./stake"

‎src/types/msg/stake/bscDelegateMsg.ts

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { BaseMsg, Msg, SignMsg, Coin } from ".."
2+
import * as crypto from "../../../crypto"
3+
import { AminoPrefix } from "../../tx"
4+
5+
export interface SignedBscDelegate extends SignMsg {
6+
delegator_addr: string
7+
validator_addr: string
8+
delegation: Coin
9+
side_chain_id: string
10+
}
11+
12+
export interface BscDelegateData extends Msg {
13+
delegator_addr: Buffer
14+
validator_addr: Buffer
15+
delegation: Coin
16+
side_chain_id: string
17+
aminoPrefix: AminoPrefix
18+
}
19+
20+
export class BscDelegateMsg extends BaseMsg {
21+
private delegator_addr: string
22+
private validator_addr: string
23+
private delegation: Coin
24+
private side_chain_id: string
25+
26+
constructor({
27+
delegator_addr,
28+
validator_addr,
29+
delegation,
30+
side_chain_id,
31+
}: {
32+
delegator_addr: string
33+
validator_addr: string
34+
delegation: Coin
35+
side_chain_id: string
36+
}) {
37+
super()
38+
this.delegator_addr = delegator_addr
39+
this.validator_addr = validator_addr
40+
this.delegation = delegation
41+
this.side_chain_id = side_chain_id
42+
}
43+
44+
getSignMsg() {
45+
const { denom, amount } = this.delegation
46+
const signMsg: SignedBscDelegate = {
47+
delegator_addr: this.delegator_addr,
48+
validator_addr: this.validator_addr,
49+
delegation: { denom, amount: String(amount) },
50+
side_chain_id: this.side_chain_id,
51+
}
52+
53+
return {
54+
type: "cosmos-sdk/MsgSideChainDelegate",
55+
value: signMsg,
56+
}
57+
}
58+
59+
getMsg() {
60+
const data: BscDelegateData = {
61+
delegator_addr: crypto.decodeAddress(this.delegator_addr),
62+
validator_addr: crypto.decodeAddress(this.validator_addr),
63+
delegation: this.delegation,
64+
side_chain_id: this.side_chain_id,
65+
aminoPrefix: AminoPrefix.MsgSideChainDelegate,
66+
}
67+
68+
return data
69+
}
70+
71+
static defaultMsg() {
72+
return {
73+
delegator_addr: Buffer.from(""),
74+
validator_addr: Buffer.from(""),
75+
delegation: [{ denom: "", amount: 0 }],
76+
side_chain_id: "",
77+
aminoPrefix: AminoPrefix.MsgSideChainDelegate,
78+
}
79+
}
80+
}
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { BaseMsg, Msg, SignMsg, Coin } from ".."
2+
import * as crypto from "../../../crypto"
3+
import { AminoPrefix } from "../../tx"
4+
5+
export interface SignedBscReDelegate extends SignMsg {
6+
delegator_addr: string
7+
validator_src_addr: string
8+
validator_dst_addr: string
9+
amount: Coin
10+
side_chain_id: string
11+
}
12+
13+
export interface BscReDelegateData extends Msg {
14+
delegator_addr: Buffer
15+
validator_src_addr: Buffer
16+
validator_dst_addr: Buffer
17+
amount: Coin
18+
side_chain_id: string
19+
aminoPrefix: AminoPrefix
20+
}
21+
22+
export class BscReDelegateMsg extends BaseMsg {
23+
private delegator_addr: string
24+
private validator_src_addr: string
25+
private validator_dst_addr: string
26+
private amount: Coin
27+
private side_chain_id: string
28+
29+
constructor({
30+
delegator_addr,
31+
validator_src_addr,
32+
validator_dst_addr,
33+
amount,
34+
side_chain_id,
35+
}: {
36+
delegator_addr: string
37+
validator_src_addr: string
38+
validator_dst_addr: string
39+
amount: Coin
40+
side_chain_id: string
41+
}) {
42+
super()
43+
this.delegator_addr = delegator_addr
44+
this.validator_src_addr = validator_src_addr
45+
this.validator_dst_addr = validator_dst_addr
46+
this.amount = amount
47+
this.side_chain_id = side_chain_id
48+
}
49+
50+
getSignMsg() {
51+
const { denom, amount } = this.amount
52+
const signMsg: SignedBscReDelegate = {
53+
delegator_addr: this.delegator_addr,
54+
validator_src_addr: this.validator_src_addr,
55+
validator_dst_addr: this.validator_dst_addr,
56+
amount: { denom, amount: String(amount) },
57+
side_chain_id: this.side_chain_id,
58+
}
59+
60+
return {
61+
type: "cosmos-sdk/MsgSideChainRedelegate",
62+
value: signMsg,
63+
}
64+
}
65+
66+
getMsg() {
67+
const data: BscReDelegateData = {
68+
delegator_addr: crypto.decodeAddress(this.delegator_addr),
69+
validator_src_addr: crypto.decodeAddress(this.validator_src_addr),
70+
validator_dst_addr: crypto.decodeAddress(this.validator_dst_addr),
71+
amount: this.amount,
72+
side_chain_id: this.side_chain_id,
73+
aminoPrefix: AminoPrefix.MsgSideChainRedelegate,
74+
}
75+
76+
return data
77+
}
78+
79+
static defaultMsg() {
80+
return {
81+
delegator_addr: Buffer.from(""),
82+
validator_src_addr: Buffer.from(""),
83+
validator_dst_addr: Buffer.from(""),
84+
amount: [{ denom: "", amount: 0 }],
85+
side_chain_id: "",
86+
aminoPrefix: AminoPrefix.MsgSideChainRedelegate,
87+
}
88+
}
89+
}
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { BaseMsg, Msg, SignMsg, Coin } from ".."
2+
import * as crypto from "../../../crypto"
3+
import { AminoPrefix } from "../../tx"
4+
5+
export interface SignedBscUndelegate extends SignMsg {
6+
delegator_addr: string
7+
validator_addr: string
8+
amount: Coin
9+
side_chain_id: string
10+
}
11+
12+
export interface BscUndelegateData extends Msg {
13+
delegator_addr: Buffer
14+
validator_addr: Buffer
15+
amount: Coin
16+
side_chain_id: string
17+
aminoPrefix: AminoPrefix
18+
}
19+
20+
export class BscUndelegateMsg extends BaseMsg {
21+
private delegator_addr: string
22+
private validator_addr: string
23+
private amount: Coin
24+
private side_chain_id: string
25+
26+
constructor({
27+
delegator_addr,
28+
validator_addr,
29+
amount,
30+
side_chain_id,
31+
}: {
32+
delegator_addr: string
33+
validator_addr: string
34+
amount: Coin
35+
side_chain_id: string
36+
}) {
37+
super()
38+
this.delegator_addr = delegator_addr
39+
this.validator_addr = validator_addr
40+
this.amount = amount
41+
this.side_chain_id = side_chain_id
42+
}
43+
44+
getSignMsg() {
45+
const { denom, amount } = this.amount
46+
const signMsg: SignedBscUndelegate = {
47+
delegator_addr: this.delegator_addr,
48+
validator_addr: this.validator_addr,
49+
amount: { denom, amount: String(amount) },
50+
side_chain_id: this.side_chain_id,
51+
}
52+
53+
return {
54+
type: "cosmos-sdk/MsgSideChainUndelegate",
55+
value: signMsg,
56+
}
57+
}
58+
59+
getMsg() {
60+
const data: BscUndelegateData = {
61+
delegator_addr: crypto.decodeAddress(this.delegator_addr),
62+
validator_addr: crypto.decodeAddress(this.validator_addr),
63+
amount: this.amount,
64+
side_chain_id: this.side_chain_id,
65+
aminoPrefix: AminoPrefix.MsgSideChainUndelegate,
66+
}
67+
68+
return data
69+
}
70+
71+
static defaultMsg() {
72+
return {
73+
delegator_addr: Buffer.from(""),
74+
validator_addr: Buffer.from(""),
75+
amount: [{ denom: "", amount: 0 }],
76+
side_chain_id: "",
77+
aminoPrefix: AminoPrefix.MsgSideChainUndelegate,
78+
}
79+
}
80+
}

‎src/types/msg/stake/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./bscDelegateMsg"
2+
export * from "./bscUndelegateMsg"
3+
export * from "./bscRedelegateMsg"

0 commit comments

Comments
 (0)
Please sign in to comment.