Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added bitgo-wasm-solana-0.0.1.tgz
Binary file not shown.
Binary file modified modules/sdk-coin-sol/bitgo-wasm-solana-0.0.1.tgz
Binary file not shown.
2 changes: 1 addition & 1 deletion modules/sdk-coin-sol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@bitgo/sdk-core": "^36.29.0",
"@bitgo/sdk-lib-mpc": "^10.8.1",
"@bitgo/statics": "^58.23.0",
"@bitgo/wasm-solana": "file:bitgo-wasm-solana-0.0.1.tgz",
"@bitgo/wasm-solana": "file:../../../BitGoWasm/packages/wasm-solana/bitgo-wasm-solana-0.0.1.tgz",
"@solana/spl-stake-pool": "1.1.8",
"@solana/spl-token": "0.3.1",
"@solana/web3.js": "1.92.1",
Expand Down
19 changes: 17 additions & 2 deletions modules/sdk-coin-sol/src/lib/ataInitializationBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TransactionBuilder } from './transactionBuilder';
import { BuildTransactionError, DuplicateMethodError, TransactionType } from '@bitgo/sdk-core';
import { BaseTransaction, BuildTransactionError, DuplicateMethodError, TransactionType } from '@bitgo/sdk-core';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { Transaction } from './transaction';
import { AtaInit, TokenAssociateRecipient } from './iface';
Expand All @@ -10,6 +10,7 @@ import {
validateMintAddress,
validateOwnerAddress,
} from './utils';
import { WasmTransaction } from './wasm';
import assert from 'assert';
import * as _ from 'lodash';

Expand All @@ -35,6 +36,20 @@ export class AtaInitializationBuilder extends TransactionBuilder {
/** @inheritDoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritDoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract ATA initialization parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
this._tokenAssociateRecipients = [];
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.CreateAssociatedTokenAccount) {
Expand Down Expand Up @@ -132,7 +147,7 @@ export class AtaInitializationBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._sender, 'Sender must be set before building the transaction');
if (this._tokenAssociateRecipients.length === 0) {
assert(this._mint && this._tokenName, 'Mint must be set before building the transaction');
Expand Down
19 changes: 17 additions & 2 deletions modules/sdk-coin-sol/src/lib/closeAtaBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core';
import { BaseTransaction, BuildTransactionError, TransactionType } from '@bitgo/sdk-core';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import assert from 'assert';
import { InstructionBuilderTypes } from './constants';
import { AtaClose } from './iface';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
import { validateAddress } from './utils';
import { WasmTransaction } from './wasm';

export class CloseAtaBuilder extends TransactionBuilder {
protected _accountAddress: string;
Expand Down Expand Up @@ -42,6 +43,20 @@ export class CloseAtaBuilder extends TransactionBuilder {
/** @inheritDoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritDoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract close ATA parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.CloseAssociatedTokenAccount) {
const ataCloseInstruction: AtaClose = instruction;
Expand All @@ -53,7 +68,7 @@ export class CloseAtaBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._accountAddress, 'Account Address must be set before building the transaction');
assert(this._destinationAddress, 'Destination Address must be set before building the transaction');
assert(this._authorityAddress, 'Authority Address must be set before building the transaction');
Expand Down
65 changes: 44 additions & 21 deletions modules/sdk-coin-sol/src/lib/customInstructionBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { BuildTransactionError, SolInstruction, SolVersionedInstruction, TransactionType } from '@bitgo/sdk-core';
import {
BaseTransaction,
BuildTransactionError,
SolInstruction,
SolVersionedInstruction,
TransactionType,
} from '@bitgo/sdk-core';
import { PublicKey, SystemProgram, SYSVAR_RECENT_BLOCKHASHES_PUBKEY } from '@solana/web3.js';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
import { InstructionBuilderTypes } from './constants';
import { CustomInstruction, VersionedCustomInstruction, VersionedTransactionData } from './iface';
import { isSolLegacyInstruction } from './utils';
import { WasmTransaction } from './wasm';
import assert from 'assert';

/**
Expand All @@ -28,7 +35,20 @@ export class CustomInstructionBuilder extends TransactionBuilder {
*/
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritDoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract custom instruction parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.CustomInstruction) {
const customInstruction = instruction as CustomInstruction;
Expand Down Expand Up @@ -125,22 +145,28 @@ export class CustomInstructionBuilder extends TransactionBuilder {
throw new BuildTransactionError('messageHeader.numReadonlyUnsignedAccounts must be a non-negative number');
}

let processedData = data;
if (this._nonceInfo && this._nonceInfo.params) {
processedData = this.injectNonceAdvanceInstruction(data);
const isTestnet = this._coinConfig.name === 'tsol';

if (isTestnet) {
// Testnet: store on builder for WASM path, nonce injection in wasm/builder.ts
this._versionedTransactionData = data;
this.addCustomInstructions(data.versionedInstructions);
} else {
// Mainnet: original behavior unchanged - store on Transaction, inject nonce here
let processedData = data;
if (this._nonceInfo && this._nonceInfo.params) {
processedData = this.injectNonceAdvanceInstruction(data);
}
this.addCustomInstructions(processedData.versionedInstructions);
if (!this._transaction) {
this._transaction = new Transaction(this._coinConfig);
}
this._transaction.setVersionedTransactionData(processedData);
this._transaction.setTransactionType(TransactionType.CustomTx);
}

this.addCustomInstructions(processedData.versionedInstructions);

if (!this._transaction) {
this._transaction = new Transaction(this._coinConfig);
}
this._transaction.setVersionedTransactionData(processedData);

this._transaction.setTransactionType(TransactionType.CustomTx);

if (!this._sender && processedData.staticAccountKeys.length > 0) {
this._sender = processedData.staticAccountKeys[0];
if (!this._sender && data.staticAccountKeys.length > 0) {
this._sender = data.staticAccountKeys[0];
}

return this;
Expand All @@ -153,11 +179,8 @@ export class CustomInstructionBuilder extends TransactionBuilder {
}

/**
* Inject nonce advance instruction into versioned transaction data for durable nonce support.
* Reorders accounts so signers appear first (required by Solana MessageV0 format).
* @param data - Original versioned transaction data
* @returns Modified versioned transaction data with nonce advance instruction
* @private
* Inject nonce advance instruction into versioned transaction data.
* Used by mainnet legacy path for durable nonce support.
*/
private injectNonceAdvanceInstruction(data: VersionedTransactionData): VersionedTransactionData {
const { walletNonceAddress, authWalletAddress } = this._nonceInfo!.params;
Expand Down Expand Up @@ -317,7 +340,7 @@ export class CustomInstructionBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._customInstructions.length > 0, 'At least one custom instruction must be specified');

// Set the instructions data to our custom instructions
Expand Down
2 changes: 2 additions & 0 deletions modules/sdk-coin-sol/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ export { WalletInitializationBuilder } from './walletInitializationBuilder';
export { Interface, Utils };
export { MessageBuilderFactory } from './messages';
export { InstructionBuilderTypes } from './constants';
export { mapToTransactionIntent, IntentMapperParams } from './wasmIntentMapper';
export { buildUnsignedTransaction } from './wasmTransactionBuilder';
22 changes: 19 additions & 3 deletions modules/sdk-coin-sol/src/lib/stakingActivateBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { SolStakingTypeEnum } from '@bitgo/public-types';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core';
import { BaseTransaction, BuildTransactionError, TransactionType } from '@bitgo/sdk-core';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
import { InstructionBuilderTypes } from './constants';

import assert from 'assert';
import { StakingActivate, StakingActivateExtraParams } from './iface';
import { isValidStakingAmount, validateAddress } from './utils';
import { WasmTransaction } from './wasm';

export class StakingActivateBuilder extends TransactionBuilder {
protected _amount: string;
Expand All @@ -27,6 +28,20 @@ export class StakingActivateBuilder extends TransactionBuilder {
/** @inheritdoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritdoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract staking activate parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.StakingActivate) {
const activateInstruction: StakingActivate = instruction;
Expand Down Expand Up @@ -105,7 +120,7 @@ export class StakingActivateBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._sender, 'Sender must be set before building the transaction');
assert(this._stakingAddress, 'Staking Address must be set before building the transaction');
assert(this._validator, 'Validator must be set before building the transaction');
Expand All @@ -123,7 +138,8 @@ export class StakingActivateBuilder extends TransactionBuilder {
amount: this._amount,
validator: this._validator,
stakingType: this._stakingType,
extraParams: this._extraParams,
// Only include extraParams if defined (matches legacy behavior where key is omitted when undefined)
...(this._extraParams && { extraParams: this._extraParams }),
},
};
this._instructionsData = [stakingAccountData];
Expand Down
19 changes: 17 additions & 2 deletions modules/sdk-coin-sol/src/lib/stakingAuthorizeBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { TransactionType } from '@bitgo/sdk-core';
import { BaseTransaction, TransactionType } from '@bitgo/sdk-core';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
import { InstructionBuilderTypes } from './constants';

import assert from 'assert';
import { StakingAuthorize } from './iface';
import { validateAddress } from './utils';
import { WasmTransaction } from './wasm';

export class StakingAuthorizeBuilder extends TransactionBuilder {
protected _stakingAddress: string;
Expand All @@ -24,6 +25,20 @@ export class StakingAuthorizeBuilder extends TransactionBuilder {
/** @inheritdoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritdoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract staking authorize parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.StakingAuthorize) {
const AuthorizeInstruction: StakingAuthorize = instruction;
Expand Down Expand Up @@ -77,7 +92,7 @@ export class StakingAuthorizeBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._stakingAddress, 'Staking Address must be set before building the transaction');
assert(this._newAuthorizedAddress, 'new authorized Address must be set before building the transaction');
assert(this._oldAuthorizedAddress, 'old authorized Address must be set before building the transaction');
Expand Down
22 changes: 19 additions & 3 deletions modules/sdk-coin-sol/src/lib/stakingDeactivateBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { SolStakingTypeEnum } from '@bitgo/public-types';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import assert from 'assert';

import { BuildTransactionError, Recipient, TransactionType } from '@bitgo/sdk-core';
import { BaseTransaction, BuildTransactionError, Recipient, TransactionType } from '@bitgo/sdk-core';
import { InstructionBuilderTypes, STAKE_ACCOUNT_RENT_EXEMPT_AMOUNT } from './constants';
import { StakingDeactivate, StakingDeactivateExtraParams, Transfer } from './iface';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
import { isValidStakingAmount, validateAddress } from './utils';
import { WasmTransaction } from './wasm';

export class StakingDeactivateBuilder extends TransactionBuilder {
protected _stakingAddress: string;
Expand All @@ -29,6 +30,20 @@ export class StakingDeactivateBuilder extends TransactionBuilder {
/** @inheritdoc */
initBuilder(tx: Transaction): void {
super.initBuilder(tx);
this.initFromInstructionsData();
}

/** @inheritdoc */
initBuilderFromWasm(wasmTx: WasmTransaction): void {
super.initBuilderFromWasm(wasmTx);
this.initFromInstructionsData();
}

/**
* Extract staking deactivate parameters from instructionsData.
* Called by both initBuilder and initBuilderFromWasm.
*/
private initFromInstructionsData(): void {
const stakingAddresses: string[] = [];
for (const instruction of this._instructionsData) {
if (instruction.type === InstructionBuilderTypes.StakingDeactivate) {
Expand Down Expand Up @@ -164,7 +179,7 @@ export class StakingDeactivateBuilder extends TransactionBuilder {
}

/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
protected async buildImplementation(): Promise<BaseTransaction> {
assert(this._sender, 'Sender must be set before building the transaction');

if (this._stakingAddresses && this._stakingAddresses.length > 0) {
Expand Down Expand Up @@ -223,7 +238,8 @@ export class StakingDeactivateBuilder extends TransactionBuilder {
unstakingAddress: this._unstakingAddress,
recipients: this._recipients,
stakingType: this._stakingType,
extraParams: this._extraParams,
// Only include extraParams if defined (matches legacy behavior where key is omitted when undefined)
...(this._extraParams && { extraParams: this._extraParams }),
},
};
this._instructionsData.push(stakingDeactivateData);
Expand Down
Loading