diff --git a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts index 6db2e7657a..152a8326f7 100644 --- a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts +++ b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts @@ -4,6 +4,7 @@ import { AuthorizeStakeParams, CreateAccountParams, DeactivateStakeParams, + DecodedTransferInstruction, DelegateStakeParams, InitializeStakeParams, SplitStakeParams, @@ -395,6 +396,20 @@ function parseStakingDeactivateInstructions( }); } break; + + case ValidInstructionTypesEnum.Transfer: + if ( + unstakingInstructions.length > 0 && + unstakingInstructions[unstakingInstructions.length - 1].transfer === undefined + ) { + unstakingInstructions[unstakingInstructions.length - 1].transfer = + SystemInstruction.decodeTransfer(instruction); + } else { + unstakingInstructions.push({ + transfer: SystemInstruction.decodeTransfer(instruction), + }); + } + break; } } @@ -423,13 +438,23 @@ interface UnstakingInstructions { assign?: AssignParams; split?: SplitStakeParams; deactivate?: DeactivateStakeParams; + transfer?: DecodedTransferInstruction; } function validateUnstakingInstructions(unstakingInstructions: UnstakingInstructions) { if (!unstakingInstructions.deactivate) { throw new NotSupported('Invalid deactivate stake transaction, missing deactivate stake account instruction'); - } else if (unstakingInstructions.allocate || unstakingInstructions.assign || unstakingInstructions.split) { - if (!unstakingInstructions.allocate) { + } else if ( + unstakingInstructions.allocate || + unstakingInstructions.assign || + unstakingInstructions.split || + unstakingInstructions.transfer + ) { + if (!unstakingInstructions.transfer) { + throw new NotSupported( + 'Invalid partial deactivate stake transaction, missing funding of unstake address instruction' + ); + } else if (!unstakingInstructions.allocate) { throw new NotSupported( 'Invalid partial deactivate stake transaction, missing allocate unstake account instruction' ); diff --git a/modules/sdk-coin-sol/src/lib/stakingDeactivateBuilder.ts b/modules/sdk-coin-sol/src/lib/stakingDeactivateBuilder.ts index 80f7d97334..c2ab5aef55 100644 --- a/modules/sdk-coin-sol/src/lib/stakingDeactivateBuilder.ts +++ b/modules/sdk-coin-sol/src/lib/stakingDeactivateBuilder.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core'; import { InstructionBuilderTypes } from './constants'; -import { StakingDeactivate } from './iface'; +import { StakingDeactivate, Transfer } from './iface'; import { Transaction } from './transaction'; import { TransactionBuilder } from './transactionBuilder'; import { isValidStakingAmount, validateAddress } from './utils'; @@ -12,6 +12,7 @@ export class StakingDeactivateBuilder extends TransactionBuilder { protected _stakingAddress: string; protected _stakingAddresses: string[]; protected _amount?: string; + protected _fundUnstakeAddress = 2282880; protected _unstakingAddress: string; constructor(_coinConfig: Readonly) { @@ -135,12 +136,21 @@ export class StakingDeactivateBuilder extends TransactionBuilder { 'When partially unstaking the unstaking address must be set before building the transaction' ); } - + this._instructionsData = []; if (this._unstakingAddress) { assert( this._amount, 'If an unstaking address is given then a partial amount to unstake must also be set before building the transaction' ); + const stakingFundUnstakeAddress: Transfer = { + type: InstructionBuilderTypes.Transfer, + params: { + fromAddress: this._sender, + amount: this._fundUnstakeAddress.toString(), + toAddress: this._unstakingAddress, + }, + }; + this._instructionsData.push(stakingFundUnstakeAddress); } const stakingDeactivateData: StakingDeactivate = { @@ -152,7 +162,7 @@ export class StakingDeactivateBuilder extends TransactionBuilder { unstakingAddress: this._unstakingAddress, }, }; - this._instructionsData = [stakingDeactivateData]; + this._instructionsData.push(stakingDeactivateData); } return await super.buildImplementation(); }