Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Stake #279

Merged
merged 2 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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