Qortal-Hub/src/transactions/TransactionBase.ts
2025-05-24 11:53:08 +02:00

189 lines
4.2 KiB
TypeScript

// @ts-nocheck
import nacl from '../encryption/nacl-fast.js';
import Base58 from '../encryption/Base58.js';
import utils from '../utils/utils';
import { QORT_DECIMALS, TX_TYPES } from '../constants/constants.js';
export default class TransactionBase {
static get utils() {
return utils;
}
static get nacl() {
return nacl;
}
static get Base58() {
return Base58;
}
constructor() {
this.fee = 0;
this.groupID = 0;
this.timestamp = Date.now();
this.tests = [
() => {
if (!(this._type >= 1 && this._type in TX_TYPES)) {
return 'Invalid type: ' + this.type;
}
return true;
},
() => {
if (this._fee < 0) {
return 'Invalid fee: ' + this._fee / QORT_DECIMALS;
}
return true;
},
() => {
if (this._groupID < 0 || !Number.isInteger(this._groupID)) {
return 'Invalid groupID: ' + this._groupID;
}
return true;
},
() => {
if (!new Date(this._timestamp).getTime() > 0) {
return 'Invalid timestamp: ' + this._timestamp;
}
return true;
},
() => {
if (
!(
this._lastReference instanceof Uint8Array &&
this._lastReference.byteLength == 64
)
) {
if (this._lastReference == 0) {
return 'Invalid last reference. Please ensure that you have at least 0.001 QORT for the transaction fee.';
}
return 'Invalid last reference: ' + this._lastReference;
}
return true;
},
() => {
if (!this._keyPair) {
return 'keyPair must be specified';
}
if (
!(
this._keyPair.publicKey instanceof Uint8Array &&
this._keyPair.publicKey.byteLength === 32
)
) {
return 'Invalid publicKey';
}
if (
!(
this._keyPair.privateKey instanceof Uint8Array &&
this._keyPair.privateKey.byteLength === 64
)
) {
return 'Invalid privateKey';
}
return true;
},
];
}
set keyPair(keyPair) {
this._keyPair = keyPair;
}
set type(type) {
this.typeText = TX_TYPES[type];
this._type = type;
this._typeBytes = this.constructor.utils.int32ToBytes(this._type);
}
set groupID(groupID) {
this._groupID = groupID;
this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID);
}
set timestamp(timestamp) {
this._timestamp = timestamp;
this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp);
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS;
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee);
}
set lastReference(lastReference) {
this._lastReference =
lastReference instanceof Uint8Array
? lastReference
: this.constructor.Base58.decode(lastReference);
}
get params() {
return [
this._typeBytes,
this._timestampBytes,
this._groupIDBytes,
this._lastReference,
this._keyPair.publicKey,
];
}
get signedBytes() {
if (!this._signedBytes) {
this.sign();
}
return this._signedBytes;
}
validParams() {
let finalResult = {
valid: true,
};
this.tests.some((test) => {
const result = test();
if (result !== true) {
finalResult = {
valid: false,
message: result,
};
return true; // exists the loop
}
});
return finalResult;
}
generateBase() {
const isValid = this.validParams();
if (!isValid.valid) {
throw new Error(isValid.message);
}
let result = new Uint8Array();
this.params.forEach((item) => {
result = this.constructor.utils.appendBuffer(result, item);
});
this._base = result;
return result;
}
sign() {
if (!this._keyPair) {
throw new Error('keyPair not defined');
}
if (!this._base) {
this.generateBase();
}
this._signature = this.constructor.nacl.sign.detached(
this._base,
this._keyPair.privateKey
);
this._signedBytes = this.constructor.utils.appendBuffer(
this._base,
this._signature
);
return this._signature;
}
}