PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-near/src/lib
Просмотр файла: transactionBuilder.ts
import BigNumber from 'bignumber.js';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import {
BaseAddress,
BaseKey,
BaseTransactionBuilder,
BuildTransactionError,
PublicKey as BasePublicKey,
Signature,
} from '@bitgo/sdk-core';
import { Transaction } from './transaction';
import * as nearAPI from 'near-api-js';
import { AddressValidationError } from './errors';
import utils from './utils';
import assert from 'assert';
import { KeyPair } from './keyPair';
import * as hex from '@stablelib/hex';
export abstract class TransactionBuilder extends BaseTransactionBuilder {
private _transaction: Transaction;
private _sender: string;
private _publicKey: string;
private _receiverId: string;
private _nonce: number;
private _recentBlockHash: string;
private _signer: KeyPair;
private _signatures: Signature[] = []; // only support single sig for now
protected _actions: nearAPI.transactions.Action[];
constructor(_coinConfig: Readonly<CoinConfig>) {
super(_coinConfig);
this._transaction = new Transaction(_coinConfig);
}
/**
* Initialize the transaction builder fields using the decoded transaction data
*
* @param {Transaction} tx the transaction data
*/
initBuilder(tx: Transaction): void {
this._transaction = tx;
const nearTransaction = tx.nearTransaction;
this._sender = nearTransaction.signerId;
this._nonce = nearTransaction.nonce;
this._receiverId = nearTransaction.receiverId;
this._publicKey = hex.encode(nearTransaction.publicKey.data);
this._recentBlockHash = nearAPI.utils.serialize.base_encode(nearTransaction.blockHash);
this._actions = nearTransaction.actions;
}
/** @inheritdoc */
protected fromImplementation(rawTransaction: string): Transaction {
this.validateRawTransaction(rawTransaction);
this.buildImplementation();
return this.transaction;
}
/** @inheritdoc */
protected async buildImplementation(): Promise<Transaction> {
this.transaction.nearTransaction = this.buildNearTransaction();
if (this._signer) {
this.transaction.sign(this._signer);
}
if (this._signatures?.length > 0) {
this.transaction.constructSignedPayload(this._signatures[0].signature);
}
this.transaction.loadInputsAndOutputs();
return this.transaction;
}
/** @inheritdoc */
protected signImplementation(key: BaseKey): Transaction {
this._signer = new KeyPair({ prv: key.key });
return this._transaction;
}
// region Getters and Setters
/** @inheritdoc */
protected get transaction(): Transaction {
return this._transaction;
}
/** @inheritdoc */
protected set transaction(transaction: Transaction) {
this._transaction = transaction;
}
// endregion
// region Validators
/** @inheritdoc */
validateAddress(address: BaseAddress, addressFormat?: string): void {
if (!utils.isValidAddress(address.address)) {
throw new AddressValidationError(address.address);
}
}
/** @inheritdoc */
validateKey(key: BaseKey): void {
try {
new KeyPair({ prv: key.key });
} catch {
throw new BuildTransactionError(`Key validation failed`);
}
}
/** @inheritdoc */
validateRawTransaction(rawTransaction: any): void {
try {
nearAPI.utils.serialize.deserialize(
nearAPI.transactions.SCHEMA,
nearAPI.transactions.SignedTransaction,
rawTransaction
);
} catch {
try {
nearAPI.utils.serialize.deserialize(
nearAPI.transactions.SCHEMA,
nearAPI.transactions.Transaction,
rawTransaction
);
} catch {
throw new BuildTransactionError('invalid raw transaction');
}
}
}
/** @inheritdoc */
validateTransaction(transaction: Transaction): void {
if (!transaction.nearTransaction) {
return;
}
this.validateAddress({ address: transaction.nearTransaction.signerId });
this.validateAddress({ address: transaction.nearTransaction.receiverId });
}
/** @inheritdoc */
validateValue(value: BigNumber): void {
if (value.isLessThan(0)) {
throw new BuildTransactionError('Value cannot be less than zero');
}
}
// endregion
/**
* Sets the public key and the address of the sender of this transaction.
*
* @param {string} address the account that is sending this transaction
* @param {string} pubKey the public key that is sending this transaction
* @returns {TransactionBuilder} This transaction builder
*/
public sender(address: string, pubKey: string): this {
if (!address || !utils.isValidAddress(address.toString())) {
throw new BuildTransactionError('Invalid or missing address, got: ' + address);
}
if (!pubKey || !utils.isValidPublicKey(pubKey)) {
throw new BuildTransactionError('Invalid or missing pubKey, got: ' + pubKey);
}
this._sender = address;
this._publicKey = pubKey;
return this;
}
/**
* Sets the account Id of the receiver of this transaction.
*
* @param {string} accountId the account id of the account that is receiving this transaction
* @returns {TransactionBuilder} This transaction builder
*/
public receiverId(accountId: string): this {
utils.isValidAddress(accountId);
this._receiverId = accountId;
return this;
}
/**
* Set the nonce
*
* @param {number} nonce - number that can be only used once
* @returns {TransactionBuilder} This transaction builder
*/
public nonce(nonce: number): this {
if (nonce < 0) {
throw new BuildTransactionError(`Invalid nonce: ${nonce}`);
}
this._nonce = nonce;
return this;
}
/**
* Sets the blockHash of this transaction.
*
* @param {string} blockHash the blockHash of this transaction
* @returns {TransactionBuilder} This transaction builder
*/
public recentBlockHash(blockHash: string): this {
if (!utils.isValidBlockId(blockHash)) {
throw new BuildTransactionError(`Invalid blockHash ${blockHash}`);
}
this._recentBlockHash = blockHash;
return this;
}
/**
* Sets the list of actions of this transaction.
*
* @param {nearAPI.transactions.Action[]} value the the list of actions
* @returns {TransactionBuilder} This transaction builder
*/
protected actions(value: nearAPI.transactions.Action[]): this {
this._actions = value;
return this;
}
/**
* Builds the NEAR transaction.
*
* @return {Transaction} near sdk transaction
*/
protected buildNearTransaction(): nearAPI.transactions.Transaction {
assert(this._sender, new BuildTransactionError('sender is required before building'));
assert(this._recentBlockHash, new BuildTransactionError('recent blockhash is required before building'));
const tx = nearAPI.transactions.createTransaction(
this._sender,
nearAPI.utils.PublicKey.fromString(nearAPI.utils.serialize.base_encode(hex.decode(this._publicKey))),
this._receiverId,
this._nonce,
this._actions,
nearAPI.utils.serialize.base_decode(this._recentBlockHash)
);
return tx;
}
/** @inheritDoc */
addSignature(publicKey: BasePublicKey, signature: Buffer): void {
this._signatures.push({ publicKey, signature });
}
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!