mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-23 08:01:22 +00:00
189 lines
4.2 KiB
TypeScript
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;
|
|
}
|
|
}
|