mirror of
				https://github.com/Qortal/qortal-ui.git
				synced 2025-11-04 06:37:47 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict'
 | 
						|
import {QORT_DECIMALS, TX_TYPES} from '../constants.js'
 | 
						|
import nacl from '../deps/nacl-fast.js'
 | 
						|
import Base58 from '../deps/Base58.js'
 | 
						|
import utils from '../deps/utils.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
 | 
						|
			}
 | 
						|
		]
 | 
						|
	}
 | 
						|
 | 
						|
	render(html) {
 | 
						|
		return html`render method to display requested transaction info`
 | 
						|
	}
 | 
						|
 | 
						|
	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
 | 
						|
	}
 | 
						|
}
 |