Skip to content

Commit 01f5d55

Browse files
Merge pull request #5614 from BitGo/add-missing-methods-for-tao
feat(abstract-substrate): add missing methods for TAO stake/unstake
2 parents a689480 + 635854c commit 01f5d55

File tree

3 files changed

+135
-2
lines changed

3 files changed

+135
-2
lines changed

modules/abstract-substrate/src/lib/iface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface TxData {
5656
eraPeriod?: number;
5757
payee?: string;
5858
keepAlive?: boolean;
59+
netuid?: number;
5960
}
6061

6162
/**

modules/abstract-substrate/src/lib/transaction.ts

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ export class Transaction extends BaseTransaction {
151151
tip: decodedTx.tip ? Number(decodedTx.tip) : 0,
152152
};
153153

154+
const txMethod = decodedTx.method.args;
154155
if (this.type === TransactionType.Send) {
155-
const txMethod = decodedTx.method.args;
156156
if (utils.isTransfer(txMethod)) {
157157
const keypairDest = new KeyPair({
158158
pub: Buffer.from(decodeAddress(txMethod.dest.id)).toString('hex'),
@@ -168,6 +168,26 @@ export class Transaction extends BaseTransaction {
168168
} else {
169169
throw new ParseTransactionError(`Serializing unknown Transfer type parameters`);
170170
}
171+
} else if (this.type === TransactionType.StakingActivate) {
172+
if (utils.isAddStake(txMethod)) {
173+
const keypairDest = new KeyPair({
174+
pub: Buffer.from(decodeAddress(txMethod.hotkey)).toString('hex'),
175+
});
176+
// hotkey address of validator
177+
result.to = keypairDest.getAddress(this.getAddressFormat());
178+
result.amount = txMethod.amountStaked.toString();
179+
result.netuid = txMethod.netuid;
180+
}
181+
} else if (this.type === TransactionType.StakingDeactivate) {
182+
if (utils.isRemoveStake(txMethod)) {
183+
const keypairDest = new KeyPair({
184+
pub: Buffer.from(decodeAddress(txMethod.hotkey)).toString('hex'),
185+
});
186+
// hotkey address of validator
187+
result.to = keypairDest.getAddress(this.getAddressFormat());
188+
result.amount = txMethod.amountUnstaked.toString();
189+
result.netuid = txMethod.netuid;
190+
}
171191
}
172192

173193
return result;
@@ -185,6 +205,30 @@ export class Transaction extends BaseTransaction {
185205
};
186206
}
187207

208+
explainStakeTransaction(json: TxData, explanationResult: TransactionExplanation): TransactionExplanation {
209+
return {
210+
...explanationResult,
211+
outputs: [
212+
{
213+
address: json.to?.toString() || '',
214+
amount: json.amount?.toString() || '',
215+
},
216+
],
217+
};
218+
}
219+
220+
explainUnstakeTransaction(json: TxData, explanationResult: TransactionExplanation): TransactionExplanation {
221+
return {
222+
...explanationResult,
223+
outputs: [
224+
{
225+
address: json.sender.toString() || '',
226+
amount: json.amount?.toString() || '',
227+
},
228+
],
229+
};
230+
}
231+
188232
/** @inheritdoc */
189233
explainTransaction(): TransactionExplanation {
190234
const result = this.toJson();
@@ -205,6 +249,10 @@ export class Transaction extends BaseTransaction {
205249
switch (this.type) {
206250
case TransactionType.Send:
207251
return this.explainTransferTransaction(result, explanationResult);
252+
case TransactionType.StakingActivate:
253+
return this.explainStakeTransaction(result, explanationResult);
254+
case TransactionType.StakingDeactivate:
255+
return this.explainUnstakeTransaction(result, explanationResult);
208256
default:
209257
throw new InvalidTransactionError('Transaction type not supported');
210258
}
@@ -225,6 +273,10 @@ export class Transaction extends BaseTransaction {
225273

226274
if (this.type === TransactionType.Send) {
227275
this.decodeInputsAndOutputsForSend(decodedTx);
276+
} else if (this.type === TransactionType.StakingActivate) {
277+
this.decodeInputsAndOutputsForStakingActivate(decodedTx);
278+
} else if (this.type === TransactionType.StakingDeactivate) {
279+
this.decodeInputsAndOutputsForStakingDeactivate(decodedTx);
228280
}
229281
}
230282

@@ -267,6 +319,70 @@ export class Transaction extends BaseTransaction {
267319
];
268320
}
269321

322+
private decodeInputsAndOutputsForStakingActivate(decodedTx: DecodedTx) {
323+
const txMethod = decodedTx.method.args;
324+
let to: string;
325+
let value: string;
326+
let from: string;
327+
if (utils.isAddStake(txMethod)) {
328+
const keypairDest = new KeyPair({
329+
pub: Buffer.from(decodeAddress(txMethod.hotkey)).toString('hex'),
330+
});
331+
to = keypairDest.getAddress(this.getAddressFormat());
332+
value = txMethod.amountStaked.toString();
333+
from = decodedTx.address;
334+
} else {
335+
throw new ParseTransactionError(`Loading inputs of unknown StakingActivate type parameters`);
336+
}
337+
this._outputs = [
338+
{
339+
address: to,
340+
value,
341+
coin: this._coinConfig.name,
342+
},
343+
];
344+
345+
this._inputs = [
346+
{
347+
address: from,
348+
value,
349+
coin: this._coinConfig.name,
350+
},
351+
];
352+
}
353+
354+
private decodeInputsAndOutputsForStakingDeactivate(decodedTx: DecodedTx) {
355+
const txMethod = decodedTx.method.args;
356+
let to: string;
357+
let value: string;
358+
let from: string;
359+
if (utils.isRemoveStake(txMethod)) {
360+
const keypairDest = new KeyPair({
361+
pub: Buffer.from(decodeAddress(txMethod.hotkey)).toString('hex'),
362+
});
363+
to = keypairDest.getAddress(this.getAddressFormat());
364+
value = txMethod.amountUnstaked.toString();
365+
from = decodedTx.address;
366+
} else {
367+
throw new ParseTransactionError(`Loading inputs of unknown StakingDeactivate type parameters`);
368+
}
369+
this._outputs = [
370+
{
371+
address: from,
372+
value,
373+
coin: this._coinConfig.name,
374+
},
375+
];
376+
377+
this._inputs = [
378+
{
379+
address: to,
380+
value,
381+
coin: this._coinConfig.name,
382+
},
383+
];
384+
}
385+
270386
/**
271387
* Constructs a signed payload using construct.signTx
272388
* This method will be called during the build step if a TSS signature

modules/abstract-substrate/src/lib/utils.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import bs58 from 'bs58';
1313
import base32 from 'hi-base32';
1414
import nacl from 'tweetnacl';
1515
import { KeyPair } from '.';
16-
import { HexString, Material, TransferAllArgs, TransferArgs, TxMethod } from './iface';
16+
import { HexString, Material, TransferAllArgs, TransferArgs, TxMethod, AddStakeArgs, RemoveStakeArgs } from './iface';
1717

1818
export class Utils implements BaseUtils {
1919
/** @inheritdoc */
@@ -195,6 +195,22 @@ export class Utils implements BaseUtils {
195195
return (arg as TransferAllArgs).dest?.id !== undefined && (arg as TransferAllArgs).keepAlive !== undefined;
196196
}
197197

198+
isAddStake(arg: TxMethod['args']): arg is AddStakeArgs {
199+
return (
200+
(arg as AddStakeArgs).amountStaked !== undefined &&
201+
(arg as AddStakeArgs).hotkey !== undefined &&
202+
(arg as AddStakeArgs).netuid !== undefined
203+
);
204+
}
205+
206+
isRemoveStake(arg: TxMethod['args']): arg is RemoveStakeArgs {
207+
return (
208+
(arg as RemoveStakeArgs).amountUnstaked !== undefined &&
209+
(arg as RemoveStakeArgs).hotkey !== undefined &&
210+
(arg as RemoveStakeArgs).netuid !== undefined
211+
);
212+
}
213+
198214
/**
199215
* extracts and returns the signature in hex format given a raw signed transaction
200216
*

0 commit comments

Comments
 (0)