Skip to content

Commit

Permalink
Adding unstaking builder tao
Browse files Browse the repository at this point in the history
  • Loading branch information
joshisakshi committed Feb 20, 2025
1 parent d0d1ca0 commit 6107abc
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 13 deletions.
6 changes: 3 additions & 3 deletions modules/abstract-substrate/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export interface TxData {
chainName: string;
method?: string;
specName?: string;
amount?: string;
amount?: number;
to?: string;
tip?: number;
eraPeriod?: number;
Expand All @@ -75,9 +75,9 @@ export interface TransferAllArgs {
keepAlive: boolean;
}
export interface UnstakeArgs extends Args {
amount_staked: string;
amountUnstaked: number;
hotkey: string;
netuid: string;
netuid: number;
}
/**
* Decoded TxMethod from a transaction hex
Expand Down
4 changes: 2 additions & 2 deletions modules/abstract-substrate/src/lib/txnSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const TransferAllTransactionSchema = joi.object({
});

export const UnstakeTransactionSchema = joi.object({
amount: joi.string().required(),
amount: joi.number().required(),
hotkey: joi.string().required(),
netuid: joi.string().required(),
netuid: joi.number().required(),
});
16 changes: 8 additions & 8 deletions modules/sdk-coin-tao/src/lib/unstakeBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { InvalidTransactionError, TransactionType } from '@bitgo/sdk-core';
import { Transaction, TransactionBuilder, Interface, Schema } from '@bitgo/abstract-substrate';

export class UnstakeBuilder extends TransactionBuilder {
protected _amount: string;
protected _amount: number;
protected _hotkey: string;
protected _netuid: string;
protected _netuid: number;

constructor(_coinConfig: Readonly<CoinConfig>) {
super(_coinConfig);
Expand All @@ -25,7 +25,7 @@ export class UnstakeBuilder extends TransactionBuilder {
const baseTxInfo = this.createBaseTxInfo();
return this.removeStake(
{
amount_staked: this._amount,
amountUnstaked: this._amount,
hotkey: this._hotkey,
netuid: this._netuid,
},
Expand All @@ -45,7 +45,7 @@ export class UnstakeBuilder extends TransactionBuilder {
*
* @see https://wiki.polkadot.network/docs/learn-nominator#required-minimum-stake
*/
amount(amount: string): this {
amount(amount: number): this {
this.validateValue(new BigNumber(amount));
this._amount = amount;
return this;
Expand All @@ -64,7 +64,7 @@ export class UnstakeBuilder extends TransactionBuilder {
return this;
}

netuid(netuid: string): this {
netuid(netuid: number): this {
this._netuid = netuid;
return this;
}
Expand All @@ -74,7 +74,7 @@ export class UnstakeBuilder extends TransactionBuilder {
const tx = super.fromImplementation(rawTransaction);
if (this._method?.name === Interface.MethodNames.RemoveStake) {
const txMethod = this._method.args as Interface.UnstakeArgs;
this.amount(txMethod.amount_staked);
this.amount(txMethod.amountUnstaked);
this.hotkey(txMethod.hotkey);
this.netuid(txMethod.netuid);
} else {
Expand All @@ -88,7 +88,7 @@ export class UnstakeBuilder extends TransactionBuilder {
this.validateFields(this._amount, this._hotkey, this._netuid);
}

private validateFields(amount: string, hotkey: string, netuid: string): void {
private validateFields(amount: number, hotkey: string, netuid: number): void {
const validationResult = Schema.UnstakeTransactionSchema.validate({
amount,
hotkey,
Expand All @@ -106,7 +106,7 @@ export class UnstakeBuilder extends TransactionBuilder {
validateDecodedTransaction(decodedTxn: DecodedSigningPayload | DecodedSignedTx, rawTransaction: string): void {
if (decodedTxn.method?.name === Interface.MethodNames.RemoveStake) {
const txMethod = decodedTxn.method.args as unknown as Interface.UnstakeArgs;
const amountStaked = `${txMethod.amount_staked}`;
const amountStaked = `${txMethod.amountUnstaked}`;
const hotkey = txMethod.hotkey;
const netuid = txMethod.netuid;
const validationResult = Schema.UnstakeTransactionSchema.validate({ amountStaked, hotkey, netuid });
Expand Down
132 changes: 132 additions & 0 deletions modules/sdk-coin-tao/test/unit/transactionBuilder/unstakeBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import assert from 'assert';
import should from 'should';
import { spy, assert as SinonAssert } from 'sinon';
import { UnstakeBuilder } from '../../../src/lib/unstakeBuilder';
import { accounts, rawTx, mockTssSignature, genesisHash, specVersion, txVersion, chainName } from '../../resources';
import { buildTestConfig } from './base';
import utils from '../../../src/lib/utils';
describe('Tao Unstake Builder', function () {
const referenceBlock = '0x149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d';
let builder: UnstakeBuilder;
const sender = accounts.account1;
beforeEach(function () {
const config = buildTestConfig();
const material = utils.getMaterial(config.network.type);
// console.log('Material:', material);
builder = new UnstakeBuilder(config).material(material);
});
describe('setter validation', function () {
it('should validate stake amount', function () {
const spyValidateValue = spy(builder, 'validateValue');
assert.throws(
() => builder.amount(-1),
(e: Error) => e.message === 'Value cannot be less than zero'
);
should.doesNotThrow(() => builder.amount(1000));
SinonAssert.calledTwice(spyValidateValue);
});
});
describe('build unstake transaction', function () {
it('should build a unstake transaction', async function () {
builder
.amount(50000000000000)
.hotkey('5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR')
.netuid(0)
.sender({ address: sender.address })
.validity({ firstValid: 3933, maxDuration: 64 })
.referenceBlock(referenceBlock)
.sequenceId({ name: 'Nonce', keyword: 'nonce', value: 200 })
.fee({ amount: 0, type: 'tip' })
.addSignature({ pub: sender.publicKey }, Buffer.from(mockTssSignature, 'hex'));

const tx = await builder.build();
// console.log('Transaction built:', tx);
const txJson = tx.toJson();
console.log('Transaction JSON:', JSON.stringify(txJson, null, 2));
should.deepEqual(txJson.amount, 50000000000000);
should.deepEqual(txJson.hotkey, '5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR');
should.deepEqual(txJson.netuid, 0);
should.deepEqual(txJson.sender, sender.address);
should.deepEqual(txJson.blockNumber, 3933);
should.deepEqual(txJson.referenceBlock, referenceBlock);
should.deepEqual(txJson.genesisHash, genesisHash);
should.deepEqual(txJson.specVersion, specVersion);
should.deepEqual(txJson.nonce, 200);
should.deepEqual(txJson.tip, 0);
should.deepEqual(txJson.transactionVersion, txVersion);
should.deepEqual(txJson.chainName, chainName);
should.deepEqual(txJson.eraPeriod, 64);
});
it('should build an unsigned unstake transaction', async function () {
builder
.amount(50000000000000)
.hotkey('5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR')
.netuid(0)
.sender({ address: sender.address })
.validity({ firstValid: 3933, maxDuration: 64 })
.referenceBlock(referenceBlock)
.sequenceId({ name: 'Nonce', keyword: 'nonce', value: 200 })
.fee({ amount: 0, type: 'tip' });
// console.log('Builder after setting properties:', builder);
console.log('Building transaction...');
const tx = await builder.build();
const txJson = tx.toJson();
// console.log('Transaction JSON:', JSON.stringify(txJson, null, 2));
should.deepEqual(txJson.amount, 50000000000000);
should.deepEqual(txJson.hotkey, '5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR');
should.deepEqual(txJson.netuid, 0);
should.deepEqual(txJson.sender, sender.address);
should.deepEqual(txJson.blockNumber, 3933);
should.deepEqual(txJson.referenceBlock, referenceBlock);
should.deepEqual(txJson.genesisHash, genesisHash);
should.deepEqual(txJson.specVersion, specVersion);
should.deepEqual(txJson.nonce, 200);
should.deepEqual(txJson.tip, 0);
should.deepEqual(txJson.transactionVersion, txVersion);
should.deepEqual(txJson.chainName, chainName);
should.deepEqual(txJson.eraPeriod, 64);
});
it('should build from raw signed tx', async function () {
builder.from(rawTx.unstake.signed);
builder.validity({ firstValid: 3933, maxDuration: 64 }).referenceBlock(referenceBlock);
const tx = await builder.build();
const txJson = tx.toJson();
should.deepEqual(txJson.amount, 50000000000000);
should.deepEqual(txJson.hotkey, '5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR');
should.deepEqual(txJson.netuid, 0);
should.deepEqual(txJson.sender, '5F1mFBGhm7FrSKftDxzFPN8U1BqHKSAxEDhTV2Yx5JhCe2Nk');
should.deepEqual(txJson.blockNumber, 3933);
should.deepEqual(txJson.referenceBlock, referenceBlock);
should.deepEqual(txJson.genesisHash, genesisHash);
should.deepEqual(txJson.specVersion, specVersion);
should.deepEqual(txJson.nonce, 0);
should.deepEqual(txJson.tip, 0);
should.deepEqual(txJson.transactionVersion, txVersion);
should.deepEqual(txJson.chainName, chainName);
should.deepEqual(txJson.eraPeriod, 64);
});
it('should build from raw unsigned tx', async function () {
builder.from(rawTx.unstake.unsigned);
builder
.validity({ firstValid: 3933, maxDuration: 64 })
.referenceBlock(referenceBlock)
.sender({ address: '5F1mFBGhm7FrSKftDxzFPN8U1BqHKSAxEDhTV2Yx5JhCe2Nk' })
.addSignature({ pub: sender.publicKey }, Buffer.from(mockTssSignature, 'hex'));
const tx = await builder.build();
const txJson = tx.toJson();
should.deepEqual(txJson.amount, 50000000000000);
should.deepEqual(txJson.hotkey, '5H56KVtb3sSMxuhFsH51iFi1gei7tnBQjpVmj6hu9tK7CBDR');
should.deepEqual(txJson.netuid, 0);
should.deepEqual(txJson.sender, '5F1mFBGhm7FrSKftDxzFPN8U1BqHKSAxEDhTV2Yx5JhCe2Nk');
should.deepEqual(txJson.blockNumber, 3933);
should.deepEqual(txJson.referenceBlock, referenceBlock);
should.deepEqual(txJson.genesisHash, genesisHash);
should.deepEqual(txJson.specVersion, specVersion);
should.deepEqual(txJson.nonce, 0);
should.deepEqual(txJson.tip, 0);
should.deepEqual(txJson.transactionVersion, txVersion);
should.deepEqual(txJson.chainName, chainName);
should.deepEqual(txJson.eraPeriod, 64);
});
});
});

0 comments on commit 6107abc

Please sign in to comment.