-
Notifications
You must be signed in to change notification settings - Fork 294
Adding unfreeze and withdraw for tron unstaking #6013
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export enum TronResource { | ||
BANDWIDTH = 'BANDWIDTH', | ||
ENERGY = 'ENERGY', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,8 @@ import { | |
TransferContract, | ||
TriggerSmartContract, | ||
VoteWitnessContract, | ||
UnfreezeBalanceV2Contract, | ||
WithdrawExpireUnfreezeContract, | ||
} from './iface'; | ||
|
||
/** | ||
|
@@ -162,6 +164,30 @@ export class Transaction extends BaseTransaction { | |
value: totalVoteCount.toString(), | ||
}; | ||
break; | ||
case ContractType.UnfreezeBalanceV2: | ||
this._type = TransactionType.StakingUnlock; | ||
const unfreezeValues = (rawData.contract[0] as UnfreezeBalanceV2Contract).parameter.value; | ||
output = { | ||
address: unfreezeValues.owner_address, | ||
value: unfreezeValues.unfreeze_balance.toString(), | ||
}; | ||
input = { | ||
address: unfreezeValues.owner_address, | ||
value: unfreezeValues.unfreeze_balance.toString(), | ||
}; | ||
break; | ||
case ContractType.WithdrawExpireUnfreeze: | ||
this._type = TransactionType.StakingWithdraw; | ||
const withdrawValues = (rawData.contract[0] as WithdrawExpireUnfreezeContract).parameter.value; | ||
output = { | ||
address: withdrawValues.owner_address, | ||
value: '0', // no value field | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just trying to understand, why this is 0 in StakingWithdraw type? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just set as a placeholder as we don't provide any explicit value for the amount to be withdrawn |
||
}; | ||
input = { | ||
address: withdrawValues.owner_address, | ||
value: '0', | ||
}; | ||
break; | ||
default: | ||
throw new ParseTransactionError('Unsupported contract type'); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { InvalidTransactionError, TransactionType } from '@bitgo/sdk-core'; | ||
import { TransactionBuilder } from './transactionBuilder'; | ||
import { Transaction } from './transaction'; | ||
import { TransactionReceipt } from './iface'; | ||
import { TronResource } from './resourceTypes'; | ||
|
||
interface RawUnfreezeBalanceContract { | ||
parameter: { | ||
value: { | ||
resource?: string; | ||
unfreeze_balance?: number; | ||
owner_address?: string; | ||
}; | ||
}; | ||
type: string; | ||
} | ||
|
||
export class UnfreezeBalanceTxBuilder extends TransactionBuilder { | ||
/** @inheritdoc */ | ||
protected get transactionType(): TransactionType { | ||
return TransactionType.StakingUnlock; | ||
} | ||
|
||
initBuilder(rawTransaction: TransactionReceipt | string): void { | ||
this.transaction = this.fromImplementation(rawTransaction); | ||
this.transaction.setTransactionType(this.transactionType); | ||
} | ||
|
||
validateTransaction(transaction: Transaction | TransactionReceipt): void { | ||
if (transaction && typeof (transaction as Transaction).toJson === 'function') { | ||
super.validateTransaction(transaction as Transaction); | ||
const rawTx = (transaction as Transaction).toJson(); | ||
this.validateUnfreezeTransaction(rawTx); | ||
} else { | ||
this.validateUnfreezeTransaction(transaction as TransactionReceipt); | ||
} | ||
} | ||
|
||
/** | ||
* Validates if the transaction is a valid unfreeze transaction | ||
* @param {TransactionReceipt} transaction - The transaction to validate | ||
* @throws {InvalidTransactionError} when the transaction is invalid | ||
*/ | ||
private validateUnfreezeTransaction(transaction: TransactionReceipt): void { | ||
if (!transaction?.raw_data?.contract?.length) { | ||
throw new InvalidTransactionError('Invalid transaction: missing or empty contract array'); | ||
} | ||
|
||
const contract = transaction.raw_data.contract[0] as RawUnfreezeBalanceContract; | ||
|
||
// Validate contract type | ||
if (contract.type !== 'UnfreezeBalanceV2Contract') { | ||
throw new InvalidTransactionError( | ||
`Invalid unfreeze transaction: expected contract type UnfreezeBalanceV2Contract but got ${contract.type}` | ||
); | ||
} | ||
|
||
// Validate parameter value | ||
if (!contract?.parameter?.value) { | ||
throw new InvalidTransactionError('Invalid unfreeze transaction: missing parameter value'); | ||
} | ||
|
||
const value = contract.parameter.value; | ||
|
||
// Validate resource | ||
if (!Object.values(TronResource).includes(value.resource as TronResource)) { | ||
throw new InvalidTransactionError( | ||
`Invalid unfreeze transaction: resource must be ${Object.values(TronResource).join(' or ')}, got ${ | ||
value.resource | ||
}` | ||
); | ||
} | ||
|
||
// Validate unfreeze_balance | ||
if (!value.unfreeze_balance || value.unfreeze_balance <= 0) { | ||
throw new InvalidTransactionError('Invalid unfreeze transaction: unfreeze_balance must be positive'); | ||
} | ||
|
||
// Validate owner_address | ||
if (!value.owner_address || typeof value.owner_address !== 'string' || value.owner_address.length === 0) { | ||
throw new InvalidTransactionError('Invalid unfreeze transaction: missing or invalid owner_address'); | ||
} | ||
} | ||
|
||
/** | ||
* Check if the transaction is a valid unfreeze transaction | ||
* @param {TransactionReceipt} transaction - Transaction to check | ||
* @returns True if the transaction is a valid unfreeze transaction | ||
*/ | ||
canSign(transaction: TransactionReceipt): boolean { | ||
try { | ||
this.validateUnfreezeTransaction(transaction); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be used in freeze PR as well