feat(staking):add factory and fix nonce problem

test
neeboo 5 years ago
parent d1f465ee94
commit f89b6ce146
  1. 2
      examples/staking_create.js
  2. 2
      examples/staking_transfer.js
  3. 205
      packages/harmony-staking/src/factory.ts
  4. 1
      packages/harmony-staking/src/index.ts
  5. 151
      packages/harmony-staking/test/testSign.test.ts

@ -6,7 +6,7 @@ const {
Delegate,
Undelegate,
CollectRewards,
} = require('../packages/harmony-staking');
} = require('@harmony-js/staking');
const createMsg = CreateValidator({
validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',

@ -6,7 +6,7 @@ const {
CommissionRate,
StakingTransaction,
CreateValidator,
} = require('../packages/harmony-staking'); //../packages/harmony-staking
} = require('@harmony-js/staking'); //../packages/harmony-staking
const { TxStatus } = require('@harmony-js/transaction');
const LOCALNET = `http://localhost:9500`;

@ -0,0 +1,205 @@
import { Messenger } from '@harmony-js/network';
import { Signature } from '@harmony-js/crypto';
import {
Directive,
CreateValidator,
EditValidator,
Delegate,
Undelegate,
CollectRewards,
Description,
CommissionRate,
Decimal,
StakingTransaction,
} from './stakingTransaction';
import { Unit } from '@harmony-js/utils';
import { TxStatus } from '@harmony-js/transaction';
export interface DescriptionInterface {
name: string;
identity: string;
website: string;
securityContact: string;
details: string;
}
export interface CommissionRateInterface {
rate: string;
maxRate: string;
maxChangeRate: string;
}
export class StakingFactory {
public messenger: Messenger;
public stakeMsg?: CreateValidator | EditValidator | Delegate | Undelegate | CollectRewards;
public directive?: Directive;
public nonce: number | string;
public gasPrice: number | string;
public gasLimit: number | string;
public chainId: number;
public signature: Signature;
constructor(messenger: Messenger) {
this.messenger = messenger;
this.nonce = 0;
this.gasPrice = new Unit('100').asGwei().toHex();
this.gasLimit = new Unit('210000').asWei().toHex();
this.chainId = 1;
this.signature = {
v: 0,
r: '',
s: '',
};
}
createValidator({
validatorAddress,
description,
commissionRate,
minSelfDelegation,
maxTotalDelegation,
slotPubKeys,
amount,
}: {
validatorAddress: string;
description: DescriptionInterface;
commissionRate: CommissionRateInterface;
minSelfDelegation: number;
maxTotalDelegation: number;
slotPubKeys: string[];
amount: number;
}) {
this.stakeMsg = new CreateValidator(
validatorAddress,
new Description(
description.name,
description.identity,
description.website,
description.securityContact,
description.details,
),
new CommissionRate(
new Decimal(commissionRate.rate),
new Decimal(commissionRate.maxRate),
new Decimal(commissionRate.maxChangeRate),
),
minSelfDelegation,
maxTotalDelegation,
slotPubKeys,
amount,
);
this.directive = Directive.DirectiveCreateValidator;
return this;
}
editValidator({
validatorAddress,
description,
commissionRate,
minSelfDelegation,
maxTotalDelegation,
slotKeyToRemove,
slotKeyToAdd,
}: {
validatorAddress: string;
description: DescriptionInterface;
commissionRate: string;
minSelfDelegation: number;
maxTotalDelegation: number;
slotKeyToRemove: string;
slotKeyToAdd: string;
}) {
this.stakeMsg = new EditValidator(
validatorAddress,
new Description(
description.name,
description.identity,
description.website,
description.securityContact,
description.details,
),
new Decimal(commissionRate),
minSelfDelegation,
maxTotalDelegation,
slotKeyToRemove,
slotKeyToAdd,
);
this.directive = Directive.DirectiveEditValidator;
return this;
}
delegate({
delegatorAddress,
validatorAddress,
amount,
}: {
delegatorAddress: string;
validatorAddress: string;
amount: number;
}) {
this.stakeMsg = new Delegate(delegatorAddress, validatorAddress, amount);
this.directive = Directive.DirectiveDelegate;
return this;
}
undelegate({
delegatorAddress,
validatorAddress,
amount,
}: {
delegatorAddress: string;
validatorAddress: string;
amount: number;
}) {
this.stakeMsg = new Undelegate(delegatorAddress, validatorAddress, amount);
this.directive = Directive.DirectiveUndelegate;
return this;
}
collectRewards({ delegatorAddress }: { delegatorAddress: string }) {
this.stakeMsg = new CollectRewards(delegatorAddress);
this.directive = Directive.DirectiveCollectRewards;
return this;
}
setTxParams({
nonce,
gasPrice,
gasLimit,
chainId,
signature,
}: {
nonce: number | string;
gasPrice: number | string;
gasLimit: number | string;
chainId: number;
signature: Signature;
}) {
this.nonce = nonce;
this.gasPrice = gasPrice;
this.gasLimit = gasLimit;
this.chainId = chainId;
this.signature = signature;
return this;
}
build() {
if (this.directive === undefined) {
throw new Error('cannot build stakingTransaction without Directive');
}
if (this.stakeMsg === undefined) {
throw new Error('cannot build stakingTransaction without stakeMsg');
}
return new StakingTransaction(
this.directive,
this.stakeMsg,
this.nonce !== undefined ? this.nonce : 0,
this.gasPrice !== undefined ? this.gasPrice : new Unit('100').asGwei().toHex(),
this.gasLimit !== undefined ? this.gasLimit : new Unit('210000').asWei().toHex(),
this.chainId !== undefined ? this.chainId : 1,
this.messenger,
TxStatus.INTIALIZED,
);
}
}

@ -1 +1,2 @@
export * from './stakingTransaction';
export * from './factory';

@ -25,6 +25,7 @@ import {
Description,
CommissionRate,
Decimal,
StakingFactory,
} from '../src';
import testTransactions from './transactions.json';
@ -73,6 +74,43 @@ describe('test sign staking transaction', () => {
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign create validator staking transaction using factory', () => {
const testTx: any = testTransactions[0];
const address = getAddressFromPrivateKey(testTx.privateKey);
expect(isValidAddress(address)).toEqual(true);
const stakingFactory = new StakingFactory(msgHttp);
const stakingTx = stakingFactory
.createValidator({
validatorAddress: testTx.validatorAddress,
description: {
...testTx.description,
},
commissionRate: {
...testTx.commissionRates,
},
minSelfDelegation: testTx.minSelfDelegation,
maxTotalDelegation: testTx.maxTotalDelegation,
slotPubKeys: testTx.slotPubKeys,
amount: testTx.amount,
})
.setTxParams({
nonce: testTx.nonce,
gasPrice: testTx.gasPrice,
gasLimit: testTx.gasLimit,
chainId: testTx.chainID,
signature: {
v: 0,
r: '',
s: '',
},
})
.build();
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign edit validator staking transaction', () => {
const testTx: any = testTransactions[1];
const address = getAddressFromPrivateKey(testTx.privateKey);
@ -107,6 +145,38 @@ describe('test sign staking transaction', () => {
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign edit validator staking transaction using factory', () => {
const testTx: any = testTransactions[1];
const address = getAddressFromPrivateKey(testTx.privateKey);
expect(isValidAddress(address)).toEqual(true);
const stakingFactory = new StakingFactory(msgHttp);
const stakingTx = stakingFactory
.editValidator({
validatorAddress: testTx.validatorAddress,
description: { ...testTx.description },
commissionRate: testTx.commissionRate,
minSelfDelegation: testTx.minSelfDelegation,
maxTotalDelegation: testTx.maxTotalDelegation,
slotKeyToRemove: testTx.slotKeyToRemove,
slotKeyToAdd: testTx.slotKeyToAdd,
})
.setTxParams({
nonce: testTx.nonce,
gasPrice: testTx.gasPrice,
gasLimit: testTx.gasLimit,
chainId: testTx.chainID,
signature: {
v: 0,
r: '',
s: '',
},
})
.build();
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign delegate staking transaction', () => {
const testTx: any = testTransactions[2];
const address = getAddressFromPrivateKey(testTx.privateKey);
@ -131,6 +201,35 @@ describe('test sign staking transaction', () => {
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign delegate staking transaction using factory', () => {
const testTx: any = testTransactions[2];
const address = getAddressFromPrivateKey(testTx.privateKey);
expect(isValidAddress(address)).toEqual(true);
const stakingFactory = new StakingFactory(msgHttp);
const stakingTx = stakingFactory
.delegate({
delegatorAddress: testTx.delegatorAddress,
validatorAddress: testTx.validatorAddress,
amount: testTx.amount,
})
.setTxParams({
nonce: testTx.nonce,
gasPrice: testTx.gasPrice,
gasLimit: testTx.gasLimit,
chainId: testTx.chainID,
signature: {
v: 0,
r: '',
s: '',
},
})
.build();
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign undelegate staking transaction', () => {
const testTx: any = testTransactions[3];
const address = getAddressFromPrivateKey(testTx.privateKey);
@ -155,6 +254,34 @@ describe('test sign staking transaction', () => {
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign undelegate staking transaction using factory', () => {
const testTx: any = testTransactions[3];
const address = getAddressFromPrivateKey(testTx.privateKey);
expect(isValidAddress(address)).toEqual(true);
const stakingFactory = new StakingFactory(msgHttp);
const stakingTx = stakingFactory
.undelegate({
delegatorAddress: testTx.delegatorAddress,
validatorAddress: testTx.validatorAddress,
amount: testTx.amount,
})
.setTxParams({
nonce: testTx.nonce,
gasPrice: testTx.gasPrice,
gasLimit: testTx.gasLimit,
chainId: testTx.chainID,
signature: {
v: 0,
r: '',
s: '',
},
})
.build();
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign collect rewards staking transaction', () => {
const testTx: any = testTransactions[4];
const address = getAddressFromPrivateKey(testTx.privateKey);
@ -175,6 +302,30 @@ describe('test sign staking transaction', () => {
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign collect rewards staking transaction using factory', () => {
const testTx: any = testTransactions[4];
const address = getAddressFromPrivateKey(testTx.privateKey);
expect(isValidAddress(address)).toEqual(true);
const stakingFactory = new StakingFactory(msgHttp);
const stakingTx = stakingFactory
.collectRewards({
delegatorAddress: testTx.delegatorAddress,
})
.setTxParams({
nonce: testTx.nonce,
gasPrice: testTx.gasPrice,
gasLimit: testTx.gasLimit,
chainId: testTx.chainID,
signature: {
v: 0,
r: '',
s: '',
},
})
.build();
const signed = stakingTx.rlpSign(testTx.privateKey);
expect(signed[1]).toEqual(testTx.encoded);
});
it('should test sign create validator staking transaction using wallet', async () => {
const testTx: any = testTransactions[0];
const responses = [

Loading…
Cancel
Save