PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-sol/src/lib
Просмотр файла: stakingRawMsgAuthorizeBuilder.ts
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import {
BaseAddress,
BaseKey,
BaseTransaction,
BaseTransactionBuilder,
NotSupported,
TransactionType,
} from '@bitgo/sdk-core';
import { Transaction } from './transaction';
import {
Transaction as SOLTransaction,
Message as SOLMessage,
SystemProgram,
SystemInstruction,
StakeProgram,
} from '@solana/web3.js';
import assert from 'assert';
import BigNumber from 'bignumber.js';
import { nonceAdvanceInstruction, validInstructionData, validInstructionData2 } from './constants';
export class StakingRawMsgAuthorizeBuilder extends BaseTransactionBuilder {
protected _transaction: Transaction;
protected _transactionMessage: string;
constructor(_coinConfig: Readonly<CoinConfig>) {
super(_coinConfig);
this._transaction = new Transaction(_coinConfig);
}
protected get transactionType(): TransactionType {
return TransactionType.StakingAuthorizeRaw;
}
/** @inheritdoc */
initBuilder(tx: Transaction): void {
if (this.validateTransaction(tx)) {
this.transactionMessage(tx.solTransaction.serializeMessage().toString('base64'));
}
}
/**
* The raw message generated by Solana CLI.
*
* @param {string} msg msg generated by 'solana stake-authorize-check.
* @returns {StakeBuilder} This staking builder.
*
*/
transactionMessage(msg: string): this {
this.validateMessage(msg);
this._transactionMessage = msg;
return this;
}
/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
assert(this._transactionMessage, 'missing transaction message');
this.validateMessage(this._transactionMessage);
const solTransaction = SOLTransaction.populate(
SOLMessage.from(Buffer.from(this._transactionMessage, 'base64')),
[]
);
// this is workaround for solana web3.js generate wrong signing message
const serialized = solTransaction.serialize({ requireAllSignatures: false }).toString('base64');
this.transaction.fromRawTransaction(serialized);
this.transaction.setTransactionType(this.transactionType);
assert(this._transactionMessage === this.transaction.signablePayload.toString('base64'), 'wrong signing message');
return this.transaction;
}
validateTransaction(tx: Transaction): boolean {
return this.validateMessage(tx.solTransaction.serializeMessage().toString('base64'));
}
async build(): Promise<Transaction> {
return this.buildImplementation();
}
protected validateMessage(msg: string): boolean {
const tx = SOLTransaction.populate(SOLMessage.from(Buffer.from(msg, 'base64')), []);
const instructions = tx.instructions;
if (instructions.length !== 2 && instructions.length !== 3) {
throw new Error(`Invalid transaction, expected 2 instruction, got ${instructions.length}`);
}
for (const instruction of instructions) {
switch (instruction.programId.toString()) {
case SystemProgram.programId.toString():
const instructionName = SystemInstruction.decodeInstructionType(instruction);
if (instructionName !== nonceAdvanceInstruction) {
throw new Error(`Invalid system instruction : ${instructionName}`);
}
break;
case StakeProgram.programId.toString():
const data = instruction.data.toString('hex');
if (data !== validInstructionData && data !== validInstructionData2) {
throw new Error(`Invalid staking instruction data: ${data}`);
}
break;
default:
throw new Error(
`Invalid transaction, instruction program id not supported: ${instruction.programId.toString()}`
);
}
}
return true;
}
protected fromImplementation(rawTransaction: string): Transaction {
const tx = new Transaction(this._coinConfig);
tx.fromRawTransaction(rawTransaction);
this.initBuilder(tx);
return this.transaction;
}
protected signImplementation(key: BaseKey): BaseTransaction {
throw new NotSupported('Method not supported on this builder');
}
protected get transaction(): Transaction {
return this._transaction;
}
validateAddress(address: BaseAddress, addressFormat?: string): void {
throw new NotSupported('Method not supported on this builder');
}
validateKey(key: BaseKey): void {
throw new NotSupported('Method not supported on this builder');
}
validateRawTransaction(rawTransaction: string): void {
const tx = new Transaction(this._coinConfig);
tx.fromRawTransaction(rawTransaction);
this.validateTransaction(tx);
}
validateValue(value: BigNumber): void {
throw new NotSupported('Method not supported on this builder');
}
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!