Skip to content

Commit

Permalink
feat: Stake (#279)
Browse files Browse the repository at this point in the history
* feat: add basic stake function

* docs: update docs
  • Loading branch information
xzjcool authored Aug 4, 2020
1 parent 00c5957 commit 451adee
Show file tree
Hide file tree
Showing 10 changed files with 507 additions and 0 deletions.
65 changes: 65 additions & 0 deletions __tests__/stake.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { getClient, address } from "./utils"

describe("stake management", () => {
beforeEach(() => {
jest.setTimeout(50000)
})

it("bsc delegate", async () => {
const client = await getClient(true)
const validatorAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"

try {
const res = await client.stake.bscDelegate({
delegateAddress: address,
validatorAddress,
amount: 10,
})
expect(res.status).toBe(200)
} catch (err) {
if (err.message.includes("insufficient fund")) {
expect(1).toBeTruthy()
}
throw err
}
})

it("bsc undelegate", async () => {
const client = await getClient(true)
const validatorAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"

try {
const res = await client.stake.bscUndelegate({
delegateAddress: address,
validatorAddress,
amount: 10,
})
expect(res.status).toBe(200)
} catch (err) {
if (err.message.includes("insufficient fund")) {
expect(1).toBeTruthy()
}
throw err
}
})

it("bsc redelegate", async () => {
const client = await getClient(true)
const validatorSrcAddress = "bva10npy5809y303f227g4leqw7vs3s6ep5ul26sq2"
const validatorDstAddress = "bva1pcd6muhehuz6fy05wfhq9sd5fww6ggdap3adxg"
try {
const res = await client.stake.bscReDelegate({
delegateAddress: address,
validatorSrcAddress,
validatorDstAddress,
amount: 10,
})
expect(res.status).toBe(200)
} catch (err) {
if (err.message.includes("insufficient fund")) {
expect(1).toBeTruthy()
}
throw err
}
})
})
1 change: 1 addition & 0 deletions docs/api-docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [Bridge](classes/bridge.md)
* [LedgerApp](classes/ledgerapp.md)
* [RpcClient](classes/rpcclient.md)
* [Stake](classes/stake.md)
* [TokenManagement](classes/tokenmanagement.md)
* [Transaction](classes/transaction.md)

Expand Down
28 changes: 28 additions & 0 deletions docs/api-docs/classes/stake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

# Class: Stake

Stake

## Hierarchy

* **Stake**

## Index

### Constructors

* [constructor](stake.md#constructor)

## Constructors

### constructor

\+ **new Stake**(`bncClient`: [BncClient](bncclient.md)): *[Stake](stake.md)*

**Parameters:**

Name | Type | Description |
------ | ------ | ------ |
`bncClient` | [BncClient](bncclient.md) | |

**Returns:** *[Stake](stake.md)*
4 changes: 4 additions & 0 deletions src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Gov from "./gov"
import Swap from "./swap"
import TokenManagement, { validateMiniTokenSymbol } from "./token"
import { Bridge } from "./bridge"
import { Stake } from "./stake"

const BASENUMBER = Math.pow(10, 8)

Expand Down Expand Up @@ -145,6 +146,7 @@ export class BncClient {
public swap: Swap
public gov: Gov
public bridge: Bridge
public stake: Stake
public chainId?: string | null
public addressPrefix: typeof NETWORK_PREFIX_MAPPING[keyof typeof NETWORK_PREFIX_MAPPING] =
"tbnb"
Expand Down Expand Up @@ -173,6 +175,7 @@ export class BncClient {
this.swap = new Swap(this)
this.gov = new Gov(this)
this.bridge = new Bridge(this)
this.stake = new Stake(this)
}

/**
Expand Down Expand Up @@ -816,6 +819,7 @@ export class BncClient {
sequence: typeof sequence !== "number" ? parseInt(sequence!) : sequence,
source: this._source,
})

return this._signingDelegate.call(this, tx, stdSignMsg)
}

Expand Down
156 changes: 156 additions & 0 deletions src/client/stake/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import Big from "big.js"

import { BncClient } from "../"
import * as crypto from "../../crypto"
import {
BscDelegateMsg,
BaseMsg,
BscUndelegateMsg,
BscReDelegateMsg,
} from "../../types"

/**
* Stake
*/
export class Stake {
private _bncClient!: BncClient

/**
* @param {BncClient} bncClient
*/
constructor(bncClient: BncClient) {
this._bncClient = bncClient
}

public async bscDelegate({
delegateAddress,
validatorAddress,
amount,
symbol = "BNB",
sideChainId = "chapel", //default value is ganges(testnet)
}: {
delegateAddress: string
validatorAddress: string
amount: number
symbol?: string
sideChainId?: string
}) {
if (!amount) {
throw new Error("amount should not be empty")
}

if (!delegateAddress) {
throw new Error("delegate address should not be null")
}

if (!crypto.checkAddress(validatorAddress, "bva")) {
throw new Error("validator address is not valid")
}

amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())

const bscDelegateMsg = new BscDelegateMsg({
delegator_addr: delegateAddress,
validator_addr: validatorAddress,
delegation: { denom: symbol, amount },
side_chain_id: sideChainId,
})

return await this.broadcast(bscDelegateMsg, delegateAddress)
}

public async bscUndelegate({
delegateAddress,
validatorAddress,
amount,
symbol = "BNB",
sideChainId = "chapel", //default value is ganges(testnet)
}: {
delegateAddress: string
validatorAddress: string
amount: number
symbol?: string
sideChainId?: string
}) {
if (!amount) {
throw new Error("amount should not be empty")
}

if (!delegateAddress) {
throw new Error("delegate address should not be null")
}

if (!crypto.checkAddress(validatorAddress, "bva")) {
throw new Error("validator address is not valid")
}

amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())

const unDelegateMsg = new BscUndelegateMsg({
delegator_addr: delegateAddress,
validator_addr: validatorAddress,
amount: { denom: symbol, amount },
side_chain_id: sideChainId,
})

return await this.broadcast(unDelegateMsg, delegateAddress)
}

public async bscReDelegate({
delegateAddress,
validatorSrcAddress,
validatorDstAddress,
amount,
symbol = "BNB",
sideChainId = "chapel", //default value is ganges(testnet)
}: {
delegateAddress: string
validatorSrcAddress: string
validatorDstAddress: string
amount: number
symbol?: string
sideChainId?: string
}) {
if (!amount) {
throw new Error("amount should not be empty")
}

if (!delegateAddress) {
throw new Error("delegate address should not be null")
}

if (!crypto.checkAddress(validatorSrcAddress, "bva")) {
throw new Error("validator source address is not valid")
}

if (!crypto.checkAddress(validatorDstAddress, "bva")) {
throw new Error("validator dest address is not valid")
}

amount = Number(new Big(amount).mul(Math.pow(10, 8)).toString())

const bscReDelegateMsg = new BscReDelegateMsg({
delegator_addr: delegateAddress,
validator_src_addr: validatorSrcAddress,
validator_dst_addr: validatorDstAddress,
amount: { denom: symbol, amount },
side_chain_id: sideChainId,
})

return await this.broadcast(bscReDelegateMsg, delegateAddress)
}

private async broadcast(
msg: BaseMsg,
fromAddress: string,
sequence?: number
) {
const signedTx = await this._bncClient._prepareTransaction(
msg.getMsg(),
msg.getSignMsg(),
fromAddress,
sequence
)
return this._bncClient._broadcastDelegate(signedTx)
}
}
1 change: 1 addition & 0 deletions src/types/msg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from "./dex"
export * from "./token"
export * from "./send"
export * from "./claim"
export * from "./stake"
80 changes: 80 additions & 0 deletions src/types/msg/stake/bscDelegateMsg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { BaseMsg, Msg, SignMsg, Coin } from ".."
import * as crypto from "../../../crypto"
import { AminoPrefix } from "../../tx"

export interface SignedBscDelegate extends SignMsg {
delegator_addr: string
validator_addr: string
delegation: Coin
side_chain_id: string
}

export interface BscDelegateData extends Msg {
delegator_addr: Buffer
validator_addr: Buffer
delegation: Coin
side_chain_id: string
aminoPrefix: AminoPrefix
}

export class BscDelegateMsg extends BaseMsg {
private delegator_addr: string
private validator_addr: string
private delegation: Coin
private side_chain_id: string

constructor({
delegator_addr,
validator_addr,
delegation,
side_chain_id,
}: {
delegator_addr: string
validator_addr: string
delegation: Coin
side_chain_id: string
}) {
super()
this.delegator_addr = delegator_addr
this.validator_addr = validator_addr
this.delegation = delegation
this.side_chain_id = side_chain_id
}

getSignMsg() {
const { denom, amount } = this.delegation
const signMsg: SignedBscDelegate = {
delegator_addr: this.delegator_addr,
validator_addr: this.validator_addr,
delegation: { denom, amount: String(amount) },
side_chain_id: this.side_chain_id,
}

return {
type: "cosmos-sdk/MsgSideChainDelegate",
value: signMsg,
}
}

getMsg() {
const data: BscDelegateData = {
delegator_addr: crypto.decodeAddress(this.delegator_addr),
validator_addr: crypto.decodeAddress(this.validator_addr),
delegation: this.delegation,
side_chain_id: this.side_chain_id,
aminoPrefix: AminoPrefix.MsgSideChainDelegate,
}

return data
}

static defaultMsg() {
return {
delegator_addr: Buffer.from(""),
validator_addr: Buffer.from(""),
delegation: [{ denom: "", amount: 0 }],
side_chain_id: "",
aminoPrefix: AminoPrefix.MsgSideChainDelegate,
}
}
}
Loading

0 comments on commit 451adee

Please sign in to comment.