'use strict' ;
import { TX _TYPES , QORT _DECIMALS } 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 ( ) {
// Defaults
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 ) {
// No prior transactions exist
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 ) { // Always Base58 encoded. Accepts Uint8Array or Base58 string.
// lastReference could be a string or an Uint8Array
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
}
// render function but NOT lit element
render ( html ) {
return html ` render method to display requested transaction info `
}
validParams ( ) {
let finalResult = {
valid : true
}
// const valid =
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
}
}