Redsign qortal-ui repo

This commit is contained in:
AlphaX-Projects
2023-05-11 18:40:52 +02:00
parent edbe674fb9
commit 6d3dbcdfe8
3745 changed files with 20028 additions and 10558 deletions

22
crypto/api.js Normal file
View File

@@ -0,0 +1,22 @@
import { Sha256 } from 'asmcrypto.js'
import Base58 from './api/deps/Base58'
import Base64 from './api/deps/Base64'
import { base58PublicKeyToAddress } from './api/wallet/base58PublicKeyToAddress'
import { validateAddress } from './api/wallet/validateAddress'
import { decryptChatMessage, decryptChatMessageBase64 } from './api/transactions/chat/decryptChatMessage'
import _ from 'lodash'
window.Sha256 = Sha256
window.Base58 = Base58
window.Base64 = Base64
window._ = _
window.base58PublicKeyToAddress = base58PublicKeyToAddress
window.validateAddress = validateAddress
window.decryptChatMessage = decryptChatMessage
window.decryptChatMessageBase64 = decryptChatMessageBase64
export { initApi, store } from './api_deps.js'
export * from './api/deps/deps.js'
export * from './api/api.js'
export * from './api/registerUsername.js'
export { createWallet } from './api/createWallet.js'

209
crypto/api/PhraseWallet.js Normal file
View File

@@ -0,0 +1,209 @@
/*
Copyright 2017-2018 @ irontiga and vbcs (original developer)
*/
'use strict'
import Base58 from './deps/Base58.js'
import { Sha256, Sha512 } from 'asmcrypto.js'
import nacl from './deps/nacl-fast.js'
import utils from './deps/utils.js'
import { generateSaveWalletData } from './storeWallet.js'
import publicKeyToAddress from './wallet/publicKeyToAddress.js'
import AltcoinHDWallet from "./bitcoin/AltcoinHDWallet"
export default class PhraseWallet {
constructor(seed, walletVersion) {
this._walletVersion = walletVersion || 2
this.seed = seed
this.savedSeedData = {}
this.hasBeenSaved = false
}
set seed(seed) {
this._byteSeed = seed
this._base58Seed = Base58.encode(seed)
this._addresses = []
this.genAddress(0)
}
getAddress(nonce) {
return this._addresses[nonce]
}
get addresses() {
return this._addresses
}
get addressIDs() {
return this._addresses.map(addr => {
return addr.address
})
}
get seed() {
return this._byteSeed
}
addressExists(nonce) {
return this._addresses[nonce] != undefined
}
_genAddressSeed(seed) {
let newSeed = new Sha512().process(seed).finish().result
newSeed = new Sha512().process(utils.appendBuffer(newSeed, seed)).finish().result
return newSeed
}
genAddress(nonce) {
if (nonce >= this._addresses.length) {
this._addresses.length = nonce + 1
}
if (this.addressExists(nonce)) {
return this.addresses[nonce]
}
const nonceBytes = utils.int32ToBytes(nonce)
let addrSeed = new Uint8Array()
addrSeed = utils.appendBuffer(addrSeed, nonceBytes)
addrSeed = utils.appendBuffer(addrSeed, this._byteSeed)
addrSeed = utils.appendBuffer(addrSeed, nonceBytes)
if (this._walletVersion == 1) {
addrSeed = new Sha256().process(
new Sha256()
.process(addrSeed)
.finish()
.result
).finish().result
addrSeed = this._byteSeed
} else {
addrSeed = this._genAddressSeed(addrSeed).slice(0, 32)
}
const addrKeyPair = nacl.sign.keyPair.fromSeed(new Uint8Array(addrSeed));
const address = publicKeyToAddress(addrKeyPair.publicKey);
const qoraAddress = publicKeyToAddress(addrKeyPair.publicKey, true);
// Create Bitcoin HD Wallet
const btcSeed = [...addrSeed];
const btcWallet = new AltcoinHDWallet({
mainnet: {
private: 0x0488ADE4,
public: 0x0488B21E,
prefix: 0
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: 0x6F
}
}).createWallet(new Uint8Array(btcSeed), false);
// Create Litecoin HD Wallet
const ltcSeed = [...addrSeed];
const ltcWallet = new AltcoinHDWallet({
mainnet: {
private: 0x0488ADE4,
public: 0x0488B21E,
prefix: 0x30
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: 0x6F
}
}).createWallet(new Uint8Array(ltcSeed), false, 'LTC');
// Create Dogecoin HD Wallet
const dogeSeed = [...addrSeed];
const dogeWallet = new AltcoinHDWallet({
mainnet: {
private: 0x02FAC398,
public: 0x02FACAFD,
prefix: 0x1E
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: 0x71
}
}).createWallet(new Uint8Array(dogeSeed), false, 'DOGE');
// Create Digibyte HD Wallet
const dgbSeed = [...addrSeed];
const dgbWallet = new AltcoinHDWallet({
mainnet: {
private: 0x0488ADE4,
public: 0x0488B21E,
prefix: 0x1E
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: 0x7E
}
}).createWallet(new Uint8Array(dgbSeed), false, 'DGB');
// Create Ravencoin HD Wallet
const rvnSeed = [...addrSeed];
const rvnWallet = new AltcoinHDWallet({
mainnet: {
private: 0x0488ADE4,
public: 0x0488B21E,
prefix: 0x3C
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: 0x6F
}
}).createWallet(new Uint8Array(rvnSeed), false, 'RVN');
// Create Pirate Chain HD Wallet
const arrrSeed = [...addrSeed];
const arrrWallet = new AltcoinHDWallet({
mainnet: {
private: 0x0488ADE4,
public: 0x0488B21E,
prefix: [0x16, 0x9A]
},
testnet: {
private: 0x04358394,
public: 0x043587CF,
prefix: [0x14, 0x51]
}
}).createWallet(new Uint8Array(arrrSeed), false, 'ARRR');
this._addresses[nonce] = {
address,
btcWallet,
ltcWallet,
dogeWallet,
dgbWallet,
rvnWallet,
arrrWallet,
qoraAddress,
keyPair: {
publicKey: addrKeyPair.publicKey,
privateKey: addrKeyPair.secretKey
},
base58PublicKey: Base58.encode(addrKeyPair.publicKey),
seed: addrSeed,
nonce: nonce
}
return this._addresses[nonce]
}
generateSaveWalletData(...args) {
return generateSaveWalletData(this, ...args)
}
}

5
crypto/api/api.js Normal file
View File

@@ -0,0 +1,5 @@
export { request } from './fetch-request.js'
export { transactionTypes as transactions } from './transactions/transactions.js'
export { processTransaction, processTransactionVersion2, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction, signArbitraryWithFeeTransaction } from './createTransaction.js'
export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest.js'
export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers.js'

View File

@@ -0,0 +1,862 @@
'use strict';
import Base58 from '../deps/Base58.js'
import { Sha256, Sha512 } from 'asmcrypto.js'
import jsSHA from 'jssha'
import RIPEMD160 from '../deps/ripemd160.js'
import utils from '../deps/utils.js'
import { EllipticCurve, BigInteger } from './ecbn.js'
export default class AltcoinHDWallet {
constructor(addressParams) {
/**
* Seed - 32 bytes
*/
this.seed = new Uint8Array(32)
/**
* Version Bytes - 4 byte
*/
this.versionBytes = addressParams
/**
* Depth - 1 byte
*/
this.depth = 0
/**
* Parent Fingerprint - 4 bytes
*/
this.parentFingerprint = '0x00000000' // master key
/**
* Child Index - 4 bytes
*/
this.childIndex = '0x00000000' // master key
/**
* Chain Code - 32 bytes
*/
this.chainCode = new Uint8Array(32)
/**
* Key Data - 33 bytes
*/
this.keyData = new Uint8Array(33)
/**
* Seed Hash - 64 bytes
*/
this.seedHash = new Uint8Array(64)
/**
* Private Key - 32 bytes
*/
this.privateKey = new Uint8Array(32)
/**
* Public Key - 33 bytes (compressed)
*/
this.publicKey = new Uint8Array(33)
/**
* Public Key Hash160 (used to derive the parent fingerprint for derived)
*/
this.publicKeyHash = new Uint8Array(20)
/**
* Master Private Key (Base58 encoded)
*/
this.masterPrivateKey = ''
/**
* Master Public Key (Base58 encoded)
*/
this.masterPublicKey = ''
/**
* Testnet Master Private Key (Base58 encoded) - THIS IS TESTNET
*/
this._tMasterPrivateKey = ''
/**
* Testnet Master Public Key (Base58 encoded) - THIS IS TESTNET
*/
this._tmasterPublicKey = ''
/**
* Child Keys Derivation from the Parent Keys
*/
/**
* Child Private Key - 32 bytes
*/
this.childPrivateKey = new Uint8Array(32)
/**
* Child Chain Code - 32 bytes
*/
this.childChainCode = new Uint8Array(32)
/**
* Child Public Key - 33 bytes (compressed)
*/
this.childPublicKey = new Uint8Array(33)
/**
* Child Public Key Hash160 (used to derive the parent fingerprint for derived)
*/
this.childPublicKeyHash = new Uint8Array(20)
/**
* Extended Private Child Key - Base58 encoded
*/
this.xPrivateChildKey = ''
/**
* Extended Public Child Key - Base58 encoded
*/
this.xPublicChildKey = ''
/**
* Grand Child Keys Derivation from the Child Keys
*/
/**
* Grand Child Private Key - 32 bytes
*/
this.grandChildPrivateKey = new Uint8Array(32)
/**
* Grand Child Chain Code - 32 bytes
*/
this.grandChildChainCode = new Uint8Array(32)
/**
* Grand Child Public Key - 33 bytes (compressed)
*/
this.grandChildPublicKey = new Uint8Array(33)
/**
* Grand Public Key Hash160 (used to derive the parent fingerprint for derived)
*/
this.grandChildPublicKeyHash = new Uint8Array(20)
/**
* Extended Private Grand Child Key - Base58 encoded
*/
this.xPrivateGrandChildKey = ''
/**
* Extended Public Grand Child Key - Base58 encoded
*/
this.xPublicGrandChildKey = ''
/**
* Litecoin Legacy Address - Derived from the Grand Child Public Key Hash
*/
this.litecoinLegacyAddress = ''
/**
* TESTNET Litecoin Legacy Address (Derived from the Grand Child Public Key Hash) - THIS IS TESTNET
*/
this._tlitecoinLegacyAddress = ''
/**
* Wallet - Wallet Object (keys...)
*/
this.wallet = {}
}
setSeed(seed) {
this.seed = seed
}
createWallet(seed, isBIP44, indicator = null) {
// Set Seeed
this.setSeed(seed)
// Generate Seed Hash
this.generateSeedHash(this.seed, isBIP44, indicator)
// Generate Private Key
this.generatePrivateKey(this.seedHash)
// Generate Chain Code
this.generateChainCode(this.seedHash)
// Generate Public Key from Private Key
this.generatePublicKey(this.privateKey)
// Generate Mainnet Master Private Key
this.generateMainnetMasterPrivateKey()
// Generate Mainnet Master Public Key
this.generateMainnetMasterPublicKey()
// Generate Testnet Master Private Key
this.generateTestnetMasterPrivateKey()
// Generate Testnet Master Public Key
this.generateTestnetMasterPublicKey()
// Generate Child and Grand Child Keys
this.generateDerivedChildKeys()
// Return Wallet Object Specification
return this.returnWallet()
}
generateSeedHash(seed, isBIP44, indicator = null) {
let buffer
if (isBIP44) {
buffer = utils.appendBuffer(seed.reverse(), utils.int32ToBytes(indicator))
} else {
if(indicator !== null) {
const indicatorString = utils.stringtoUTF8Array(indicator)
buffer = utils.appendBuffer(seed.reverse(), indicatorString)
}
else
{
buffer = seed.reverse()
}
}
const _reverseSeedHash = new Sha256().process(buffer).finish().result
this.seedHash = new Sha512().process(utils.appendBuffer(seed, _reverseSeedHash)).finish().result
}
generatePrivateKey(seedHash) {
const SECP256K1_CURVE_ORDER = new BigInteger("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
const privateKeyHash = seedHash.slice(0, 32)
this.seed58 = Base58.encode(privateKeyHash)
const _privateKeyHash = [...privateKeyHash]
let privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKeyHash)
const privateKey = (privateKeyBigInt.mod(SECP256K1_CURVE_ORDER.subtract(BigInteger.ONE))).add(BigInteger.ONE)
this.privateKey = privateKey.toByteArrayUnsigned()
}
generateChainCode(seedHash) {
this.chainCode = new Sha256().process(seedHash.slice(32, 64)).finish().result
}
generatePublicKey(privateKey) {
const _privateKey = [...privateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger()
/**
* Deriving Uncompressed Public Key (65 bytes)
*
* const publicKeyBytes = EllipticCurve.integerToBytes(x, 32)
* this.publicKey = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32))
* this.publicKey.unshift(0x04) // append point indicator
*/
// Compressed Public Key (33 bytes)
this.publicKey = EllipticCurve.integerToBytes(x, 32)
if (y.isEven()) {
this.publicKey.unshift(0x02) // append point indicator
} else {
this.publicKey.unshift(0x03) // append point indicator
}
// PublicKey Hash
const publicKeySHA256 = new Sha256().process(new Uint8Array(this.publicKey)).finish().result
const _publicKeyHash = new RIPEMD160().update(Buffer.from(publicKeySHA256)).digest('hex')
this.publicKeyHash = _publicKeyHash
}
generateMainnetMasterPrivateKey() {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private)))
// Append Depth
s.push(this.depth)
// Append Parent Fingerprint
s.push(...(utils.int32ToBytes(this.parentFingerprint)))
// Append Child Number
s.push(...(utils.int32ToBytes(this.childIndex)))
// Append Chain Code
s.push(...this.chainCode)
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s.push(0)
//if the private key length is less than 32 let's add leading zeros
if(this.privateKey.length<32){
for(let i=this.privateKey.length;i<32;i++){
s.push(0)
}
}
// Append Private Key
s.push(...this.privateKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this.masterPrivateKey = Base58.encode(s)
}
generateMainnetMasterPublicKey() {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public)))
// Append Depth
s.push(this.depth)
// Append Parent Fingerprint
s.push(...(utils.int32ToBytes(this.parentFingerprint)))
// Append Child Number
s.push(...(utils.int32ToBytes(this.childIndex)))
// Append Chain Code
s.push(...this.chainCode)
// Append Public Key
s.push(...this.publicKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this.masterPublicKey = Base58.encode(s)
}
generateTestnetMasterPrivateKey() {
// To be Used ONLY in Testnet...
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.testnet.private)))
// Append Depth
s.push(this.depth)
// Append Parent Fingerprint
s.push(...(utils.int32ToBytes(this.parentFingerprint)))
// Append Child Number
s.push(...(utils.int32ToBytes(this.childIndex)))
// Append Chain Code
s.push(...this.chainCode)
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s.push(0)
// Append Private Key
s.push(...this.privateKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this._tMasterPrivateKey = Base58.encode(s)
}
generateTestnetMasterPublicKey() {
// To be Used ONLY in Testnet...
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.testnet.public)))
// Append Depth
s.push(this.depth)
// Append Parent Fingerprint
s.push(...(utils.int32ToBytes(this.parentFingerprint)))
// Append Child Number
s.push(...(utils.int32ToBytes(this.childIndex)))
// Append Chain Code
s.push(...this.chainCode)
// Append Private Key
s.push(...this.publicKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this._tmasterPublicKey = Base58.encode(s)
}
generateDerivedChildKeys() {
// SPEC INFO: https://en.bitcoin.it/wiki/BIP_0032#Child_key_derivation_.28CKD.29_functions
// NOTE: will not be using some of derivations func as the value is known. (So I'd rather shove in the values and rewrite out the derivations later ?)
// NOTE: I "re-wrote" and "reduplicate" the code for child and grandChild keys derivations inorder to get the child and grandchild from the child
// TODO: Make this more better in the future
const path = 'm/0/0'
// let p = path.split('/')
// Get Public kEY
const derivePublicChildKey = () => {
const _privateKey = [...this.childPrivateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger()
// Compressed Public Key (33 bytes)
this.childPublicKey = EllipticCurve.integerToBytes(x, 32)
if (y.isEven()) {
this.childPublicKey.unshift(0x02) // append point indicator
} else {
this.childPublicKey.unshift(0x03) // append point indicator
}
// PublicKey Hash
const childPublicKeySHA256 = new Sha256().process(new Uint8Array(this.childPublicKey)).finish().result
const _childPublicKeyHash = new RIPEMD160().update(Buffer.from(childPublicKeySHA256)).digest('hex')
this.childPublicKeyHash = _childPublicKeyHash
// Call deriveExtendedPublicChildKey // WIll be hardcoding the values...
deriveExtendedPublicChildKey(1, 0)
}
const derivePrivateChildKey = (cI) => {
let ib = []
ib.push((cI >> 24) & 0xff)
ib.push((cI >> 16) & 0xff)
ib.push((cI >> 8) & 0xff)
ib.push(cI & 0xff)
const s = [...this.publicKey].concat(ib)
const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.chainCode, format: "UINT8ARRAY" } })
_hmacSha512.update(new Uint8Array(s))
const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)])
this.childChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC
// SECP256k1 init
const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.privateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki
this.childPrivateKey = ki.toByteArrayUnsigned()
// Call deriveExtendedPrivateChildKey
deriveExtendedPrivateChildKey(1, 0)
}
const deriveExtendedPrivateChildKey = (i, childIndex) => {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private)))
// Append Depth (using the index as depth)
i = parseInt(i)
s.push(i)
// Append Parent Fingerprint
s.push(...(this.publicKeyHash.slice(0, 4)))
// Append Child Index
s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff)
// Append Chain Code
s.push(...this.childChainCode)
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s.push(0)
// Append Private Key
s.push(...this.childPrivateKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this.xPrivateChildKey = Base58.encode(s)
}
const deriveExtendedPublicChildKey = (i, childIndex) => {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public)))
// Append Depth
i = parseInt(i)
s.push(i)
// Append Parent Fingerprint
s.push(...(this.publicKeyHash.slice(0, 4)))
// Append Child Index
s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff)
// Append Chain Code
s.push(...this.childChainCode)
// Append Public Key
s.push(...this.childPublicKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this.xPublicChildKey = Base58.encode(s)
}
/**
* GRAND CHILD KEYS
*
* NOTE: I know this is not the best way to generate this (even though it works the way it ought)
* Things to rewrite will be and not limited to deriving this through a for loop, removing hard code values, etc...
*/
const derivePublicGrandChildKey = () => {
const _privateKey = [...this.grandChildPrivateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger()
// Compressed Public Key (33 bytes)
this.grandChildPublicKey = EllipticCurve.integerToBytes(x, 32)
if (y.isEven()) {
this.grandChildPublicKey.unshift(0x02) // append point indicator
} else {
this.grandChildPublicKey.unshift(0x03) // append point indicator
}
// PublicKey Hash
const grandChildPublicKeySHA256 = new Sha256().process(new Uint8Array(this.grandChildPublicKey)).finish().result
const _grandChildPublicKeyHash = new RIPEMD160().update(Buffer.from(grandChildPublicKeySHA256)).digest('hex')
this.grandChildPublicKeyHash = _grandChildPublicKeyHash
// Call deriveExtendedPublicChildKey // WIll be hardcoding the values...
deriveExtendedPublicGrandChildKey(2, 0)
/**
* Derive Litecoin Legacy Address
*/
// Append Address Prefix
let prefix = [this.versionBytes.mainnet.prefix]
if (2 == this.versionBytes.mainnet.prefix.length) {
prefix = [this.versionBytes.mainnet.prefix[0]]
prefix.push([this.versionBytes.mainnet.prefix[1]])
}
const k = prefix.concat(...this.grandChildPublicKeyHash)
// Derive Checksum
const _addressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(k)).finish().result).finish().result
const addressCheckSum = _addressCheckSum.slice(0, 4)
// Append CheckSum
const _litecoinLegacyAddress = k.concat(...addressCheckSum)
// Convert to Base58
this.litecoinLegacyAddress = Base58.encode(_litecoinLegacyAddress)
/**
* Derive TESTNET Litecoin Legacy Address
*/
// Append Version Byte
const tK = [this.versionBytes.testnet.prefix].concat(...this.grandChildPublicKeyHash)
// Derive Checksum
const _tAddressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(tK)).finish().result).finish().result
const tAddressCheckSum = _tAddressCheckSum.slice(0, 4)
// Append CheckSum
const _tlitecoinLegacyAddress = tK.concat(...tAddressCheckSum)
// Convert to Base58
this._tlitecoinLegacyAddress = Base58.encode(_tlitecoinLegacyAddress)
}
const derivePrivateGrandChildKey = (cI, i) => {
let ib = []
ib.push((cI >> 24) & 0xff)
ib.push((cI >> 16) & 0xff)
ib.push((cI >> 8) & 0xff)
ib.push(cI & 0xff)
const s = [...this.childPublicKey].concat(ib)
const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.childChainCode, format: "UINT8ARRAY" } })
_hmacSha512.update(new Uint8Array(s))
const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)])
this.grandChildChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC
// SECP256k1 init
const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.childPrivateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki
this.grandChildPrivateKey = ki.toByteArrayUnsigned()
// Call deriveExtendedPrivateChildKey
deriveExtendedPrivateGrandChildKey(2, 0)
}
const deriveExtendedPrivateGrandChildKey = (i, childIndex) => {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private)))
// Append Depth (using the index as depth)
i = parseInt(i)
s.push(i)
// Append Parent Fingerprint
s.push(...(this.childPublicKeyHash.slice(0, 4)))
// Append Child Index
s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff)
// Append Chain Code
s.push(...this.grandChildChainCode)
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s.push(0)
// Append Private Key
s.push(...this.grandChildPrivateKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this.xPrivateGrandChildKey = Base58.encode(s)
}
const deriveExtendedPublicGrandChildKey = (i, childIndex) => {
// Serialization Variable
const s = []
// Append Version Byte
s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public)))
// Append Depth
i = parseInt(i)
s.push(i)
// Append Parent Fingerprint
s.push(...(this.childPublicKeyHash.slice(0, 4)))
// Append Child Index
s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff)
// Append Chain Code
s.push(...this.grandChildChainCode)
// Append Public Key
s.push(...this.grandChildPublicKey)
// Generate CheckSum
const _s = new Uint8Array(s)
const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result
const checkSum = _checkSum.slice(0, 4)
// Append CheckSum
s.push(...checkSum) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this.xPublicGrandChildKey = Base58.encode(s)
}
// Hard Code value..
let childIndex = 0
// Call derivePrivateChildKey //Hard code value
derivePrivateChildKey(childIndex)
// Call derivePublicChildKey
derivePublicChildKey()
// Call derivePrivateGrandChildKey // Hard Code value...
derivePrivateGrandChildKey(0, 2)
// Call derivePublicGrandChildKey
derivePublicGrandChildKey()
}
returnWallet() {
// Will be limiting the exported Wallet Object to just the Master keys and Legacy Addresses
const wallet = {
derivedMasterPrivateKey: this.masterPrivateKey,
derivedMasterPublicKey: this.masterPublicKey,
_tDerivedMasterPrivateKey: this._tMasterPrivateKey,
_tDerivedmasterPublicKey: this._tmasterPublicKey,
seed58: this.seed58,
// derivedPrivateChildKey: this.xPrivateChildKey,
// derivedPublicChildKey: this.xPublicChildKey,
// derivedPrivateGrandChildKey: this.xPrivateGrandChildKey,
// derivedPublicGrandChildKey: this.xPublicGrandChildKey,
address: this.litecoinLegacyAddress,
_taddress: this._tlitecoinLegacyAddress
}
this.wallet = wallet
return wallet
}
}

2620
crypto/api/bitcoin/ecbn.js Normal file

File diff suppressed because it is too large Load Diff

1940
crypto/api/bitcoin/jsbn.js Normal file

File diff suppressed because it is too large Load Diff

171
crypto/api/constants.js Normal file
View File

@@ -0,0 +1,171 @@
'use strict'
// Qortal TX types
const TX_TYPES = {
1: "Genesis",
2: "Payment",
3: "Name registration",
4: "Name update",
5: "Sell name",
6: "Cancel sell name",
7: "Buy name",
8: "Create poll",
9: "Vote in poll",
10: "Arbitrary",
11: "Issue asset",
12: "Transfer asset",
13: "Create asset order",
14: "Cancel asset order",
15: "Multi-payment transaction",
16: "Deploy AT",
17: "Message",
18: "Chat",
19: "Publicize",
20: "Airdrop",
21: "AT",
22: "Create group",
23: "Update group",
24: "Add group admin",
25: "Remove group admin",
26: "Group ban",
27: "Cancel group ban",
28: "Group kick",
29: "Group invite",
30: "Cancel group invite",
31: "Join group",
32: "Leave group",
33: "Group approval",
34: "Set group",
35: "Update asset",
36: "Account flags",
37: "Enable forging",
38: "Reward share",
39: "Account level",
40: "Transfer privs",
41: "Presence"
}
// Qortal error codes
const ERROR_CODES = {
1: "Valid OK",
2: "Invalid address",
3: "Negative amount",
4: "Nagative fee",
5: "No balance",
6: "Invalid reference",
7: "Invalid time length",
8: "Invalid value length",
9: "Name already registered",
10: "Name does not exist",
11: "Invalid name owner",
12: "Name already for sale",
13: "Name not for sale",
14: "Name buyer already owner",
15: "Invalid amount",
16: "Invalid seller",
17: "Name not lowercase",
18: "Invalid description length",
19: "Invalid options length",
20: "Invalid option length",
21: "Duplicate option",
22: "Poll already created",
23: "Poll already has votes",
24: "Poll does not exist",
25: "Option does not exist",
26: "Already voted for that option",
27: "Invalid data length",
28: "Invalid quantity",
29: "Asset does not exist",
30: "Invalid return",
31: "Have equals want",
32: "Order does not exist",
33: "Invalid order creator",
34: "Invalid payments length",
35: "Negative price",
36: "Invalid creation bytes",
37: "Invalid tags length",
38: "Invalid type length",
39: "Invalid AT transaction",
40: "Insufficient fee",
41: "Asset does not match AT",
43: "Asset already exists",
44: "Missing creator",
45: "Timestamp too old",
46: "Timestamp too new",
47: "Too many unconfirmed",
48: "Group already exists",
49: "Group does not exist",
50: "Invalid group owner",
51: "Already group memeber",
52: "Group owner can not leave",
53: "Not group member",
54: "Already group admin",
55: "Not group admin",
56: "Invalid lifetime",
57: "Invite unknown",
58: "Ban exists",
59: "Ban unknown",
60: "Banned from group",
61: "Join request",
62: "Invalid group approval threshold",
63: "Group ID mismatch",
64: "Invalid group ID",
65: "Transaction unknown",
66: "Transaction already confirmed",
67: "Invalid TX group",
68: "TX group ID mismatch",
69: "Multiple names forbidden",
70: "Invalid asset owner",
71: "AT is finished",
72: "No flag permission",
73: "Not minting accout",
77: "Invalid rewardshare percent",
78: "Public key unknown",
79: "Invalid public key",
80: "AT unknown",
81: "AT already exists",
82: "Group approval not required",
83: "Group approval decided",
84: "Maximum reward shares",
85: "Transaction already exists",
86: "No blockchain lock",
87: "Order already closed",
88: "Clock not synced",
89: "Asset not spendable",
90: "Account can not reward share",
91: "Self share exists",
92: "Account already exists",
93: "Invalid group block delay",
94: "Incorrect nonce",
95: "Ivalid timestamp signature",
96: "Address blocked",
97: "Name Blocked",
98: "Group approval required",
99: "Account not transferable",
999: "Ivalid but ok",
1000: "Not yet released."
}
// Qortal 8 decimals
const QORT_DECIMALS = 1e8
// Q for Qortal
const ADDRESS_VERSION = 58
// Proxy for api calls
const PROXY_URL = "/proxy/"
// Chat reference timestamp
const CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP = 1674316800000
// Used as a salt for all qora addresses. Salts used for storing your private keys in local storage will be randomly generated
const STATIC_SALT = new Uint8Array([54, 190, 201, 206, 65, 29, 123, 129, 147, 231, 180, 166, 171, 45, 95, 165, 78, 200, 208, 194, 44, 207, 221, 146, 45, 238, 68, 68, 69, 102, 62, 6])
const BCRYPT_ROUNDS = 10 // Remember that the total work spent on key derivation is BCRYPT_ROUNDS * KDF_THREADS
const BCRYPT_VERSION = "2a"
const STATIC_BCRYPT_SALT = `$${BCRYPT_VERSION}$${BCRYPT_ROUNDS}$IxVE941tXVUD4cW0TNVm.O`
const KDF_THREADS = 16
export { TX_TYPES, ERROR_CODES, QORT_DECIMALS, PROXY_URL, STATIC_SALT, ADDRESS_VERSION, KDF_THREADS, STATIC_BCRYPT_SALT, CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP }

View File

@@ -0,0 +1,51 @@
import { transactionTypes as transactions } from './transactions/transactions.js'
import Base58 from './deps/Base58.js'
import { request } from './fetch-request'
import signChat from './transactions/chat/signChat.js'
import signArbitrary from './transactions/arbitrary/signArbitrary.js'
import signArbitraryWithFee from './transactions/arbitrary/signArbitraryWithFee.js'
export const createTransaction = (type, keyPair, params) => {
const tx = new transactions[type]()
tx.keyPair = keyPair
Object.keys(params).forEach(param => {
tx[param] = params[param]
})
return tx
}
// Compute Chat Nonce
export const computeChatNonce = bytes => request('/chat/compute', {
method: 'POST',
body: Base58.encode(bytes)
})
// Sign Chat Transactions
export const signChatTransaction = (chatBytes, nonce, keyPair) => {
return signChat(chatBytes, nonce, keyPair)
}
// Sign Arbitrary Transactions
export const signArbitraryTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => {
return signArbitrary(arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair)
}
export const signArbitraryWithFeeTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) => {
return signArbitraryWithFee(arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair)
}
// Process Transactions
export const processTransaction = bytes => request('/transactions/process', {
method: 'POST',
body: Base58.encode(bytes)
})
export const processTransactionVersion2 = bytes => request('/transactions/process?apiVersion=2', {
method: 'POST',
body: Base58.encode(bytes)
})

View File

@@ -0,0 +1,29 @@
import { kdf } from './kdf.js'
import PhraseWallet from './PhraseWallet.js'
import Base58 from './deps/Base58.js'
import { decryptStoredWallet } from './decryptStoredWallet.js'
export const createWallet = async (sourceType, source, statusUpdateFn) => {
let version, seed
switch (sourceType) {
case 'phrase':
version = 2
seed = await kdf(source.seedPhrase, void 0, statusUpdateFn)
break
case 'seed':
version = 1
seed = Base58.decode(source.seed)
break
case 'storedWallet':
case 'backedUpSeed':
version = source.wallet.version
seed = await decryptStoredWallet(source.password, source.wallet, statusUpdateFn)
break
default:
throw 'sourceType ' + sourceType + ' not recognized'
}
const wallet = new PhraseWallet(seed, version)
return wallet
}

View File

@@ -0,0 +1,23 @@
import Base58 from './deps/Base58.js'
import { kdf } from './kdf.js'
import { HmacSha512, AES_CBC } from 'asmcrypto.js'
export const decryptStoredWallet = async (password, wallet, statusFn = () => { }) => {
statusFn('Decoding saved data')
const encryptedSeedBytes = Base58.decode(wallet.encryptedSeed)
const iv = Base58.decode(wallet.iv)
const salt = Base58.decode(wallet.salt)
statusFn('Generating decryption key')
const key = await kdf(password, salt, statusFn)
const encryptionKey = key.slice(0, 32)
const macKey = key.slice(32, 63)
statusFn('Checking key')
const mac = new HmacSha512(macKey).process(encryptedSeedBytes).finish().result
if (Base58.encode(mac) !== wallet.mac) {
throw new Error('Incorrect password')
}
statusFn('Decrypting')
const decryptedBytes = AES_CBC.decrypt(encryptedSeedBytes, encryptionKey, false, iv)
return decryptedBytes
}

108
crypto/api/deps/Base58.js Normal file
View File

@@ -0,0 +1,108 @@
// Generated by CoffeeScript 1.8.0
// == Changed for ES6 modules == //
//(function() {
//var ALPHABET, ALPHABET_MAP, Base58, i;
//const Base58 = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.Base58 = {});
const Base58 = {};
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const ALPHABET_MAP = {};
let i = 0;
while (i < ALPHABET.length) {
ALPHABET_MAP[ALPHABET.charAt(i)] = i;
i++;
}
Base58.encode = function(buffer) {
buffer = new Uint8Array(buffer);
var carry, digits, j;
if (buffer.length === 0) {
return "";
}
i = void 0;
j = void 0;
digits = [0];
i = 0;
while (i < buffer.length) {
j = 0;
while (j < digits.length) {
digits[j] <<= 8;
j++;
}
digits[0] += buffer[i];
carry = 0;
j = 0;
while (j < digits.length) {
digits[j] += carry;
carry = (digits[j] / 58) | 0;
digits[j] %= 58;
++j;
}
while (carry) {
digits.push(carry % 58);
carry = (carry / 58) | 0;
}
i++;
}
i = 0;
while (buffer[i] === 0 && i < buffer.length - 1) {
digits.push(0);
i++;
}
return digits.reverse().map(function(digit) {
return ALPHABET[digit];
}).join("");
};
Base58.decode = function(string) {
var bytes, c, carry, j;
if (string.length === 0) {
return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(0);
}
i = void 0;
j = void 0;
bytes = [0];
i = 0;
while (i < string.length) {
c = string[i];
if (!(c in ALPHABET_MAP)) {
throw "Base58.decode received unacceptable input. Character '" + c + "' is not in the Base58 alphabet.";
}
j = 0;
while (j < bytes.length) {
bytes[j] *= 58;
j++;
}
bytes[0] += ALPHABET_MAP[c];
carry = 0;
j = 0;
while (j < bytes.length) {
bytes[j] += carry;
carry = bytes[j] >> 8;
bytes[j] &= 0xff;
++j;
}
while (carry) {
bytes.push(carry & 0xff);
carry >>= 8;
}
i++;
}
i = 0;
while (string[i] === "1" && i < string.length - 1) {
bytes.push(0);
i++;
}
return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(bytes.reverse());
};
// == Changed for ES6 modules == //
//}).call(this);
export default Base58;

24
crypto/api/deps/Base64.js Normal file
View File

@@ -0,0 +1,24 @@
const Base64 = {};
Base64.decode = function (string) {
const binaryString = atob(string);
const binaryLength = binaryString.length;
const bytes = new Uint8Array(binaryLength);
for (let i = 0; i < binaryLength; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const decoder = new TextDecoder();
const decodedString = decoder.decode(bytes);
return decodedString;
};
export default Base64;

1379
crypto/api/deps/bcrypt.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
// "Generated from Java with JSweet 1.0.0 - http://www.jsweet.org";
// BAD IMPLEMENTATION. BROKEN, BUT MUST KEEP CAUSE OF NETWORK
//const RIPEMD160 = (function () {
// == Convert to ES6 module for export == //
const RIPEMD160 = (function () {
function RIPEMD160() {
this.MDbuf = [];
this.MDbuf[0] = 1732584193;
this.MDbuf[1] = -271733879;
this.MDbuf[2] = -1732584194;
this.MDbuf[3] = 271733878;
this.MDbuf[4] = -1009589776;
this.working = new Int32Array(16);
this.working_ptr = 0;
this.msglen = 0;
}
RIPEMD160.prototype.reset = function () {
this.MDbuf = [];
this.MDbuf[0] = 1732584193;
this.MDbuf[1] = -271733879;
this.MDbuf[2] = -1732584194;
this.MDbuf[3] = 271733878;
this.MDbuf[4] = -1009589776;
this.working = new Int32Array(16);
this.working_ptr = 0;
this.msglen = 0;
};
RIPEMD160.prototype.compress = function (X) {
var index = 0;
var a;
var b;
var c;
var d;
var e;
var A;
var B;
var C;
var D;
var E;
var temp;
var s;
A = a = this.MDbuf[0];
B = b = this.MDbuf[1];
C = c = this.MDbuf[2];
D = d = this.MDbuf[3];
E = e = this.MDbuf[4];
for (; index < 16; index++) {
temp = a + (b ^ c ^ d) + X[RIPEMD160.IndexArray[0][index]];
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = RIPEMD160.ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
temp = A + (B ^ (C | ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1352829926;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = RIPEMD160.ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 32; index++) {
temp = a + ((b & c) | (~b & d)) + X[RIPEMD160.IndexArray[0][index]] + 1518500249;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = RIPEMD160.ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
temp = A + ((B & D) | (C & ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1548603684;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = RIPEMD160.ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 48; index++) {
temp = a + ((b | ~c) ^ d) + X[RIPEMD160.IndexArray[0][index]] + 1859775393;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = RIPEMD160.ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
temp = A + ((B | ~C) ^ D) + X[RIPEMD160.IndexArray[1][index]] + 1836072691;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = RIPEMD160.ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 64; index++) {
temp = a + ((b & d) | (c & ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1894007588;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = RIPEMD160.ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
temp = A + ((B & C) | (~B & D)) + X[RIPEMD160.IndexArray[1][index]] + 2053994217;
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = RIPEMD160.ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
for (; index < 80; index++) {
temp = a + (b ^ (c | ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1454113458;
a = e;
e = d;
d = (c << 10) | (c >>> 22);
c = b;
s = RIPEMD160.ArgArray[0][index];
b = ((temp << s) | (temp >>> (32 - s))) + a;
temp = A + (B ^ C ^ D) + X[RIPEMD160.IndexArray[1][index]];
A = E;
E = D;
D = (C << 10) | (C >>> 22);
C = B;
s = RIPEMD160.ArgArray[1][index];
B = ((temp << s) | (temp >>> (32 - s))) + A;
}
D += c + this.MDbuf[1];
this.MDbuf[1] = this.MDbuf[2] + d + E;
this.MDbuf[2] = this.MDbuf[3] + e + A;
this.MDbuf[3] = this.MDbuf[4] + a + B;
this.MDbuf[4] = this.MDbuf[0] + b + C;
this.MDbuf[0] = D;
};
RIPEMD160.prototype.MDfinish = function (array, lswlen, mswlen) {
var X = array;
X[(lswlen >> 2) & 15] ^= 1 << (((lswlen & 3) << 3) + 7);
if (((lswlen & 63) > 55)) {
this.compress(X);
for (var i = 0; i < 14; i++) {
X[i] = 0;
}
}
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
this.compress(X);
};
RIPEMD160.prototype.update = function (input) {
for (var i = 0; i < input.length; i++) {
this.working[this.working_ptr >> 2] ^= input[i] << ((this.working_ptr & 3) << 3);
this.working_ptr++;
if ((this.working_ptr == 64)) {
this.compress(this.working);
for (var j = 0; j < 16; j++) {
this.working[j] = 0;
}
this.working_ptr = 0;
}
}
this.msglen += input.length;
};
RIPEMD160.prototype.digestBin = function () {
this.MDfinish(this.working, this.msglen, 0);
//var res = new Int8Array();
var res = [];
for (var i = 0; i < 20; i++) {
res[i] = ((this.MDbuf[i >> 2] >>> ((i & 3) << 3)) & 255);
}
return new Uint8Array(res);
};
RIPEMD160.prototype.digest = function (input) {
this.update(new Int8Array(input));
return this.digestBin();
};
RIPEMD160.ArgArray = [[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6], [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]];
RIPEMD160.IndexArray = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13], [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]];
return RIPEMD160;
})();
export default RIPEMD160

3
crypto/api/deps/deps.js Normal file
View File

@@ -0,0 +1,3 @@
export { default as Base58 } from './Base58.js'
export { default as utils } from './utils.js'

264
crypto/api/deps/ed2curve.js Normal file
View File

@@ -0,0 +1,264 @@
/*
* ed2curve: convert Ed25519 signing key pair into Curve25519
* key pair suitable for Diffie-Hellman key exchange.
*
* Written by Dmitry Chestnykh in 2014. Public domain.
*/
/* jshint newcap: false */
/*
Change to es6 import/export
*/
import nacl from './nacl-fast.js'
// (function(root, f) {
// 'use strict';
// if (typeof module !== 'undefined' && module.exports) module.exports = f(require('tweetnacl'));
// else root.ed2curve = f(root.nacl);
// }(this, function(nacl) {
// 'use strict';
// if (!nacl) throw new Error('tweetnacl not loaded');
// -- Operations copied from TweetNaCl.js. --
var gf = function(init) {
var i, r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r;
};
var gf0 = gf(),
gf1 = gf([1]),
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
function car25519(o) {
var c;
var i;
for (i = 0; i < 16; i++) {
o[i] += 65536;
c = Math.floor(o[i] / 65536);
o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0);
o[i] -= (c * 65536);
}
}
function sel25519(p, q, b) {
var t, c = ~(b-1);
for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
function unpack25519(o, n) {
var i;
for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
o[15] &= 0x7fff;
}
// addition
function A(o, a, b) {
var i;
for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0;
}
// subtraction
function Z(o, a, b) {
var i;
for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0;
}
// multiplication
function M(o, a, b) {
var i, j, t = new Float64Array(31);
for (i = 0; i < 31; i++) t[i] = 0;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
t[i+j] += a[i] * b[j];
}
}
for (i = 0; i < 15; i++) {
t[i] += 38 * t[i+16];
}
for (i = 0; i < 16; i++) o[i] = t[i];
car25519(o);
car25519(o);
}
// squaring
function S(o, a) {
M(o, a, a);
}
// inversion
function inv25519(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if(a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function pack25519(o, n) {
var i, j, b;
var m = gf(), t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
m[i-1] &= 0xffff;
}
m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
b = (m[15]>>16) & 1;
m[14] &= 0xffff;
sel25519(t, m, 1-b);
}
for (i = 0; i < 16; i++) {
o[2*i] = t[i] & 0xff;
o[2*i+1] = t[i] >> 8;
}
}
function par25519(a) {
var d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
}
function vn(x, xi, y, yi, n) {
var i, d = 0;
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i];
return (1 & ((d - 1) >>> 8)) - 1;
}
function crypto_verify_32(x, xi, y, yi) {
return vn(x, xi, y, yi, 32);
}
function neq25519(a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32);
pack25519(c, a);
pack25519(d, b);
return crypto_verify_32(c, 0, d, 0);
}
function pow2523(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 250; a >= 0; a--) {
S(c, c);
if (a !== 1) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function set25519(r, a) {
var i;
for (i = 0; i < 16; i++) r[i] = a[i] | 0;
}
function unpackneg(r, p) {
var t = gf(), chk = gf(), num = gf(),
den = gf(), den2 = gf(), den4 = gf(),
den6 = gf();
set25519(r[2], gf1);
unpack25519(r[1], p);
S(num, r[1]);
M(den, num, D);
Z(num, num, r[2]);
A(den, r[2], den);
S(den2, den);
S(den4, den2);
M(den6, den4, den2);
M(t, den6, num);
M(t, t, den);
pow2523(t, t);
M(t, t, num);
M(t, t, den);
M(t, t, den);
M(r[0], t, den);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) M(r[0], r[0], I);
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) return -1;
if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0]);
M(r[3], r[0], r[1]);
return 0;
}
// ----
// Converts Ed25519 public key to Curve25519 public key.
// montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p
function convertPublicKey(pk) {
var z = new Uint8Array(32),
q = [gf(), gf(), gf(), gf()],
a = gf(), b = gf();
if (unpackneg(q, pk)) return null; // reject invalid key
var y = q[1];
A(a, gf1, y);
Z(b, gf1, y);
inv25519(b, b);
M(a, a, b);
pack25519(z, a);
return z;
}
// Converts Ed25519 secret key to Curve25519 secret key.
function convertSecretKey(sk) {
var d = new Uint8Array(64), o = new Uint8Array(32), i;
nacl.lowlevel.crypto_hash(d, sk, 32);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
for (i = 0; i < 32; i++) o[i] = d[i];
for (i = 0; i < 64; i++) d[i] = 0;
return o;
}
function convertKeyPair(edKeyPair) {
var publicKey = convertPublicKey(edKeyPair.publicKey);
if (!publicKey) return null;
return {
publicKey: publicKey,
secretKey: convertSecretKey(edKeyPair.secretKey)
};
}
// return {
// convertPublicKey: convertPublicKey,
// convertSecretKey: convertSecretKey,
// convertKeyPair: convertKeyPair,
// };
export default {
convertPublicKey: convertPublicKey,
convertSecretKey: convertSecretKey,
convertKeyPair: convertKeyPair,
}
// }));

2422
crypto/api/deps/nacl-fast.js Normal file

File diff suppressed because it is too large Load Diff

336
crypto/api/deps/qora.js Normal file
View File

@@ -0,0 +1,336 @@
// QORA
const TYPES = {
GENESIS_TRANSACTION: 1,
PAYMENT_TRANSACTION: 2,
REGISTER_NAME_TRANSACTION: 3,
UPDATE_NAME_TRANSACTION: 4,
SELL_NAME_TRANSACTION: 5,
CANCEL_SELL_NAME_TRANSACTION: 6,
BUY_NAME_TRANSACTION: 7,
CREATE_POLL_TRANSACTION: 8,
VOTE_ON_POLL_TRANSACTION: 9,
ARBITRARY_TRANSACTION: 10,
ISSUE_ASSET_TRANSACTION: 11,
TRANSFER_ASSET_TRANSACTION: 12,
CREATE_ORDER_TRANSACTION: 13,
CANCEL_ORDER_TRANSACTION: 14,
MULTI_PAYMENT_TRANSACTION: 15,
DEPLOY_AT_TRANSACTION: 16,
MESSAGE_TRANSACTION: 17
};
function getKeyPairFromSeed(seed, returnBase58)
{
if(typeof(seed) == "string") {
seed = new Uint8Array(Base58.decode(seed));
}
var keyPair = nacl.sign.keyPair.fromSeed(seed);
var base58privateKey = Base58.encode(keyPair.secretKey);
var base58publicKey = Base58.encode(keyPair.publicKey);
if(returnBase58) {
return {
privateKey: Base58.encode(keyPair.secretKey),
publicKey: Base58.encode(keyPair.publicKey)
};
} else {
return {
privateKey: keyPair.secretKey,
publicKey: keyPair.publicKey
};
}
}
function stringtoUTF8Array(message) {
if (typeof message == 'string') {
var s = unescape(encodeURIComponent(message)); // UTF-8
message = new Uint8Array(s.length);
for (var i = 0; i < s.length; i++) {
message[i] = s.charCodeAt(i) & 0xff;
}
}
return message;
}
function int32ToBytes (word) {
var byteArray = [];
for (var b = 0; b < 32; b += 8) {
byteArray.push((word >>> (24 - b % 32)) & 0xFF);
}
return byteArray;
}
function int64ToBytes (int64) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for ( var index = 0; index < byteArray.length; index ++ ) {
var byte = int64 & 0xff;
byteArray [ byteArray.length - index - 1 ] = byte;
int64 = (int64 - byte) / 256 ;
}
return byteArray;
}
function appendBuffer (buffer1, buffer2) {
buffer1 = new Uint8Array(buffer1);
buffer2 = new Uint8Array(buffer2);
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(buffer1, 0);
tmp.set(buffer2, buffer1.byteLength);
return tmp;
}
function equal (buf1, buf2)
{
if (buf1.byteLength != buf2.byteLength) return false;
var dv1 = new Uint8Array(buf1);
var dv2 = new Uint8Array(buf2);
for (var i = 0; i != buf1.byteLength; i++)
{
if (dv1[i] != dv2[i]) return false;
}
return true;
}
function generateAccountSeed(seed, nonce, returnBase58)
{
if(typeof(seed) == "string") {
seed = Base58.decode(seed);
}
nonceBytes = int32ToBytes(nonce);
var resultSeed = new Uint8Array();
resultSeed = appendBuffer(resultSeed, nonceBytes);
resultSeed = appendBuffer(resultSeed, seed);
resultSeed = appendBuffer(resultSeed, nonceBytes);
if(returnBase58) {
return Base58.encode(SHA256.digest(SHA256.digest(resultSeed)));
} else {
return new SHA256.digest(SHA256.digest(resultSeed));
}
}
function getAccountAddressFromPublicKey(publicKey)
{
var ADDRESS_VERSION = 58; // Q
if(typeof(publicKey) == "string") {
publicKey = Base58.decode(publicKey);
}
var publicKeyHashSHA256 = SHA256.digest(publicKey);
var ripemd160 = new RIPEMD160();
var publicKeyHash = ripemd160.digest(publicKeyHashSHA256);
var addressArray = new Uint8Array();
addressArray = appendBuffer(addressArray, [ADDRESS_VERSION]);
addressArray = appendBuffer(addressArray, publicKeyHash);
var checkSum = SHA256.digest(SHA256.digest(addressArray));
addressArray = appendBuffer(addressArray, checkSum.subarray(0, 4));
return Base58.encode(addressArray);
}
function getAccountAddressType(address)
{
try {
var ADDRESS_VERSION = 58; // Q
var AT_ADDRESS_VERSION = 23; // A
if(typeof(address) == "string") {
address = Base58.decode(address);
}
var checkSum = address.subarray(address.length - 4, address.length)
var addressWitoutChecksum = address.subarray(0, address.length - 4);
var checkSumTwo = SHA256.digest(SHA256.digest(addressWitoutChecksum));
checkSumTwo = checkSumTwo.subarray(0, 4);
if (equal(checkSum, checkSumTwo))
{
if(address[0] == ADDRESS_VERSION)
{
return "standard";
}
if(address[0] == AT_ADDRESS_VERSION)
{
return "at";
}
}
return "invalid";
} catch (e) {
return "invalid";
}
}
function isValidAddress(address)
{
return (getAccountAddressType(address) != "invalid");
}
function generateSignaturePaymentTransaction(keyPair, lastReference, recipient, amount, fee, timestamp) {
const data = generatePaymentTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp);
return nacl.sign.detached(data, keyPair.privateKey);
}
function generatePaymentTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, signature) {
return appendBuffer(generatePaymentTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp),
signature);
}
function generatePaymentTransactionBase(publicKey, lastReference, recipient, amount, fee, timestamp) {
const txType = TYPES.PAYMENT_TRANSACTION;
const typeBytes = int32ToBytes(txType);
const timestampBytes = int64ToBytes(timestamp);
const amountBytes = int64ToBytes(amount * 100000000);
const feeBytes = int64ToBytes(fee * 100000000);
var data = new Uint8Array();
data = appendBuffer(data, typeBytes);
data = appendBuffer(data, timestampBytes);
data = appendBuffer(data, lastReference);
data = appendBuffer(data, publicKey);
data = appendBuffer(data, recipient);
data = appendBuffer(data, amountBytes);
data = appendBuffer(data, feeBytes);
return data;
}
function generateSignatureMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) {
const data = generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted);
return nacl.sign.detached(data, keyPair.privateKey);
}
function generateMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted, signature) {
return appendBuffer(generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted),
signature);
}
function generateMessageTransactionBase(publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) {
txType = TYPES.MESSAGE_TRANSACTION;
const typeBytes = int32ToBytes(txType);
const timestampBytes = int64ToBytes(timestamp);
const amountBytes = int64ToBytes(amount * 100000000);
const feeBytes = int64ToBytes(fee * 100000000);
const messageLength = int32ToBytes(message.length);
const key = int64ToBytes(0);
isTextB = new Uint8Array(1);
isTextB[0] = isText;
isEncryptedB = new Uint8Array(1);
isEncryptedB[0] = isEncrypted;
var data = new Uint8Array();
data = appendBuffer(data, typeBytes);
data = appendBuffer(data, timestampBytes);
data = appendBuffer(data, lastReference);
data = appendBuffer(data, publicKey);
data = appendBuffer(data, recipient);
data = appendBuffer(data, key);
data = appendBuffer(data, amountBytes);
data = appendBuffer(data, messageLength);
data = appendBuffer(data, message);
data = appendBuffer(data, isEncryptedB);
data = appendBuffer(data, isTextB);
data = appendBuffer(data, feeBytes);
return data;
}
function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) {
const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp);
return nacl.sign.detached(data, keyPair.privateKey);
}
function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) {
return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp),
signature);
}
function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) {
const txType = TYPES.ARBITRARY_TRANSACTION;
const typeBytes = int32ToBytes(txType);
const timestampBytes = int64ToBytes(timestamp);
const feeBytes = int64ToBytes(fee * 100000000);
const serviceBytes = int32ToBytes(service);
const dataSizeBytes = int32ToBytes(arbitraryData.length);
const paymentsLengthBytes = int32ToBytes(0); // Support payments - not yet.
var data = new Uint8Array();
data = appendBuffer(data, typeBytes);
data = appendBuffer(data, timestampBytes);
data = appendBuffer(data, lastReference);
data = appendBuffer(data, publicKey);
data = appendBuffer(data, paymentsLengthBytes);
// Here it is necessary to insert the payments, if there are
data = appendBuffer(data, serviceBytes);
data = appendBuffer(data, dataSizeBytes);
data = appendBuffer(data, arbitraryData);
data = appendBuffer(data, feeBytes);
return data;
}
function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) {
const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp);
return nacl.sign.detached(data, keyPair.privateKey);
}
function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) {
return appendBuffer( generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp),
signature );
}
function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) {
const txType = TYPES.REGISTER_NAME_TRANSACTION;
const typeBytes = int32ToBytes(txType);
const timestampBytes = int64ToBytes(timestamp);
const feeBytes = int64ToBytes(fee * 100000000);
const nameSizeBytes = int32ToBytes(name.length);
const valueSizeBytes = int32ToBytes(value.length);
var data = new Uint8Array();
data = appendBuffer(data, typeBytes);
data = appendBuffer(data, timestampBytes);
data = appendBuffer(data, lastReference);
data = appendBuffer(data, publicKey);
data = appendBuffer(data, owner);
data = appendBuffer(data, nameSizeBytes);
data = appendBuffer(data, name);
data = appendBuffer(data, valueSizeBytes);
data = appendBuffer(data, value);
data = appendBuffer(data, feeBytes);
return data;
}

View File

@@ -0,0 +1,226 @@
// Extracted from https://github.com/crypto-browserify/ripemd160
const ARRAY16 = new Array(16);
const zl = initU8Array([
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
]);
const zr = initU8Array([
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
]);
const sl = initU8Array([
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
]);
const sr = initU8Array([
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
]);
const hl = initU32Array([0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]);
const hr = initU32Array([0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]);
function rotl(x, n) {
return (x << n) | (x >>> (32 - n));
}
function fn1(a, b, c, d, e, m, k, s) {
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0;
}
function fn2(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0;
}
function fn3(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0;
}
function fn4(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0;
}
function fn5(a, b, c, d, e, m, k, s) {
return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0;
}
function readInt32LE(buffer, offset) {
offset >>>= 0;
return (buffer[offset])
| (buffer[offset + 1] << 8)
| (buffer[offset + 2] << 16)
| (buffer[offset + 3] << 24);
}
function writeUInt32LE(buffer, value, offset) {
value = +value;
offset >>>= 0;
buffer[offset + 3] = (value >>> 24);
buffer[offset + 2] = (value >>> 16);
buffer[offset + 1] = (value >>> 8);
buffer[offset] = (value & 0xff);
return offset + 4;
}
function writeInt32LE(buffer, value, offset) {
value = +value;
offset >>>= 0;
buffer[offset] = (value & 0xff);
buffer[offset + 1] = (value >>> 8);
buffer[offset + 2] = (value >>> 16);
buffer[offset + 3] = (value >>> 24);
return offset + 4;
}
function initU32Array(data) {
if (typeof Uint32Array !== 'undefined') {
return new Uint32Array(data);
}
else {
return data;
}
}
function initU8Array(data) {
if (typeof Uint8Array !== 'undefined') {
return new Uint8Array(data);
}
else {
return data;
}
}
function createU8Array(size) {
if (typeof Uint8Array !== 'undefined') {
return new Uint8Array(size);
}
else {
return new Array(size);
}
}
export class RIPEMD160 {
constructor() {
this._block = createU8Array(64);
this._blockSize = 64;
this._blockOffset = 0;
this._length = [0, 0, 0, 0];
this._finalized = false;
this._a = 0x67452301;
this._b = 0xefcdab89;
this._c = 0x98badcfe;
this._d = 0x10325476;
this._e = 0xc3d2e1f0;
}
update(data) {
if (this._finalized)
throw new Error('Digest already called');
// consume data
const block = this._block;
let offset = 0;
while (this._blockOffset + data.length - offset >= this._blockSize) {
for (let i = this._blockOffset; i < this._blockSize;)
block[i++] = data[offset++];
this._update();
this._blockOffset = 0;
}
while (offset < data.length)
block[this._blockOffset++] = data[offset++];
// update length
for (let j = 0, carry = data.length * 8; carry > 0; ++j) {
this._length[j] += carry;
carry = (this._length[j] / 0x0100000000) | 0;
if (carry > 0)
this._length[j] -= 0x0100000000 * carry;
}
return this;
}
_update() {
const words = ARRAY16;
for (let j = 0; j < 16; ++j) {
words[j] = readInt32LE(this._block, j * 4);
}
let al = this._a | 0;
let bl = this._b | 0;
let cl = this._c | 0;
let dl = this._d | 0;
let el = this._e | 0;
let ar = this._a | 0;
let br = this._b | 0;
let cr = this._c | 0;
let dr = this._d | 0;
let er = this._e | 0;
// computation
for (let i = 0; i < 80; i += 1) {
let tl;
let tr;
if (i < 16) {
tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]);
tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]);
}
else if (i < 32) {
tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]);
tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]);
}
else if (i < 48) {
tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]);
tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]);
}
else if (i < 64) {
tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]);
tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]);
}
else { // if (i<80) {
tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]);
tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]);
}
al = el;
el = dl;
dl = rotl(cl, 10);
cl = bl;
bl = tl;
ar = er;
er = dr;
dr = rotl(cr, 10);
cr = br;
br = tr;
}
// update state
const t = (this._b + cl + dr) | 0;
this._b = (this._c + dl + er) | 0;
this._c = (this._d + el + ar) | 0;
this._d = (this._e + al + br) | 0;
this._e = (this._a + bl + cr) | 0;
this._a = t;
}
digest() {
if (this._finalized) {
throw new Error('Digest already called');
}
this._finalized = true;
// create padding and handle blocks
this._block[this._blockOffset++] = 0x80;
if (this._blockOffset > 56) {
this._block.fill(0, this._blockOffset, 64);
this._update();
this._blockOffset = 0;
}
this._block.fill(0, this._blockOffset, 56);
writeUInt32LE(this._block, this._length[0], 56);
writeUInt32LE(this._block, this._length[1], 60);
this._update();
// produce result
const buffer = createU8Array(20);
writeInt32LE(buffer, this._a, 0);
writeInt32LE(buffer, this._b, 4);
writeInt32LE(buffer, this._c, 8);
writeInt32LE(buffer, this._d, 12);
writeInt32LE(buffer, this._e, 16);
// reset state
this._block.fill(0);
this._blockOffset = 0;
for (let i = 0; i < 4; ++i) {
this._length[i] = 0;
}
return buffer;
}
}
export default RIPEMD160;

142
crypto/api/deps/sha256.js Normal file
View File

@@ -0,0 +1,142 @@
// SHA-256 hash function. Copyright-free.
// Requires typed arrays.
const SHA256 = {};
SHA256.K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
// The digest function returns the hash value (digest)
// as a 32 byte (typed) array.
// message: the string or byte array to hash
SHA256.digest = function(message) {
var h0 = 0x6a09e667;
var h1 = 0xbb67ae85;
var h2 = 0x3c6ef372;
var h3 = 0xa54ff53a;
var h4 = 0x510e527f;
var h5 = 0x9b05688c;
var h6 = 0x1f83d9ab;
var h7 = 0x5be0cd19;
var K = SHA256.K;
if (typeof message == 'string') {
var s = unescape(encodeURIComponent(message)); // UTF-8
message = new Uint8Array(s.length);
for (var i = 0; i < s.length; i++) {
message[i] = s.charCodeAt(i) & 0xff;
}
}
var length = message.length;
var byteLength = Math.floor((length + 72) / 64) * 64;
var wordLength = byteLength / 4;
var bitLength = length * 8;
var m = new Uint8Array(byteLength);
m.set(message);
m[length] = 0x80;
m[byteLength - 4] = bitLength >>> 24;
m[byteLength - 3] = (bitLength >>> 16) & 0xff;
m[byteLength - 2] = (bitLength >>> 8) & 0xff;
m[byteLength - 1] = bitLength & 0xff;
var words = new Int32Array(wordLength);
var byteIndex = 0;
for (var i = 0; i < words.length; i++) {
var word = m[byteIndex++] << 24;
word |= m[byteIndex++] << 16;
word |= m[byteIndex++] << 8;
word |= m[byteIndex++];
words[i] = word;
}
var w = new Int32Array(64);
for (var j = 0; j < wordLength; j += 16) {
for (i = 0; i < 16; i++) {
w[i] = words[j + i];
}
for (i = 16; i < 64; i++) {
var v = w[i - 15];
var s0 = (v >>> 7) | (v << 25);
s0 ^= (v >>> 18) | (v << 14);
s0 ^= (v >>> 3);
v = w[i - 2];
var s1 = (v >>> 17) | (v << 15);
s1 ^= (v >>> 19) | (v << 13);
s1 ^= (v >>> 10);
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffff;
}
var a = h0;
var b = h1;
var c = h2;
var d = h3;
var e = h4;
var f = h5;
var g = h6;
var h = h7;
for (i = 0; i < 64; i++) {
s1 = (e >>> 6) | (e << 26);
s1 ^= (e >>> 11) | (e << 21);
s1 ^= (e >>> 25) | (e << 7);
var ch = (e & f) ^ (~e & g);
var temp1 = (h + s1 + ch + K[i] + w[i]) & 0xffffffff;
s0 = (a >>> 2) | (a << 30);
s0 ^= (a >>> 13) | (a << 19);
s0 ^= (a >>> 22) | (a << 10);
var maj = (a & b) ^ (a & c) ^ (b & c);
var temp2 = (s0 + maj) & 0xffffffff;
h = g
g = f
f = e
e = (d + temp1) & 0xffffffff;
d = c;
c = b;
b = a;
a = (temp1 + temp2) & 0xffffffff;
}
h0 = (h0 + a) & 0xffffffff;
h1 = (h1 + b) & 0xffffffff;
h2 = (h2 + c) & 0xffffffff;
h3 = (h3 + d) & 0xffffffff;
h4 = (h4 + e) & 0xffffffff;
h5 = (h5 + f) & 0xffffffff;
h6 = (h6 + g) & 0xffffffff;
h7 = (h7 + h) & 0xffffffff;
}
var hash = new Uint8Array(32);
for (var i = 0; i < 4; i++) {
hash[i] = (h0 >>> (8 * (3 - i))) & 0xff;
hash[i + 4] = (h1 >>> (8 * (3 - i))) & 0xff;
hash[i + 8] = (h2 >>> (8 * (3 - i))) & 0xff;
hash[i + 12] = (h3 >>> (8 * (3 - i))) & 0xff;
hash[i + 16] = (h4 >>> (8 * (3 - i))) & 0xff;
hash[i + 20] = (h5 >>> (8 * (3 - i))) & 0xff;
hash[i + 24] = (h6 >>> (8 * (3 - i))) & 0xff;
hash[i + 28] = (h7 >>> (8 * (3 - i))) & 0xff;
}
return hash;
}
// The hash function returns the hash value as a hex string.
// message: the string or byte array to hash
SHA256.hash = function(message) {
var digest = SHA256.digest(message);
var hex = '';
for (var i = 0; i < digest.length; i++) {
var s = '0' + digest[i].toString(16);
hex += s.length > 2 ? s.substring(1) : s;
}
return hex;
}
// == Convert to ES6 Module == //
export default SHA256;

74
crypto/api/deps/utils.js Normal file
View File

@@ -0,0 +1,74 @@
'use strict'
const utils = {
int32ToBytes(word) {
var byteArray = []
for (var b = 0; b < 32; b += 8) {
byteArray.push((word >>> (24 - b % 32)) & 0xFF)
}
return byteArray
},
stringtoUTF8Array(message) {
if (typeof message === 'string') {
var s = unescape(encodeURIComponent(message)) // UTF-8
message = new Uint8Array(s.length)
for (var i = 0; i < s.length; i++) {
message[i] = s.charCodeAt(i) & 0xff
}
}
return message
},
// ...buffers then buffers.foreach and append to buffer1
appendBuffer(buffer1, buffer2) {
buffer1 = new Uint8Array(buffer1)
buffer2 = new Uint8Array(buffer2)
let tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
tmp.set(buffer1, 0)
tmp.set(buffer2, buffer1.byteLength)
return tmp
},
int64ToBytes(int64) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]
for (var index = 0; index < byteArray.length; index++) {
var byte = int64 & 0xff
byteArray[byteArray.length - index - 1] = byte
int64 = (int64 - byte) / 256
}
return byteArray
},
hexToBytes(hexString) {
return new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
},
stringToHex(bytes) {
return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '')
},
equal(buf1, buf2) {
if (buf1.byteLength != buf2.byteLength) return false
var dv1 = new Uint8Array(buf1)
var dv2 = new Uint8Array(buf2)
for (var i = 0; i != buf1.byteLength; i++) {
if (dv1[i] != dv2[i]) return false
}
return true
},
bytesToHex(byteArray) {
var _byteArrayToHex = []
for (var index = 0; index < byteArray.length; index++) {
_byteArrayToHex.push((byteArray[index] >>> 4).toString(16))
_byteArrayToHex.push((byteArray[index] & 15).toString(16));
}
return _byteArrayToHex.join("")
}
}
export default utils

View File

@@ -0,0 +1,30 @@
import { watchConfig, waitForConfig } from '../config.js'
let config = {}
watchConfig((c) => {
config = c
})
export async function request(url, options) {
options = options || {}
const body = options.body
const method = options.method || 'GET'
const headers = options.headers || {}
await waitForConfig()
const n = config.nodeConfig.knownNodes[config.nodeConfig.node]
const node = n.protocol + '://' + n.domain + ':' + n.port
return fetch(node + url, {
method,
headers,
body,
}).then(async (response) => {
try {
const json = await response.clone().json()
return json
} catch (e) {
return await response.text()
}
})
}

39
crypto/api/kdf.js Normal file
View File

@@ -0,0 +1,39 @@
import { store } from '../api_deps.js'
import { stateAwait } from './utils/stateAwait.js'
import { Sha512 } from 'asmcrypto.js'
import utils from '../api/deps/utils.js'
export const kdf = async (seed, salt, status = () => { }) => {
const state = store.getState()
const config = state.config
const workers = state.app.workers.workers
status('Waiting for workers to be ready')
await stateAwait(state => state.app.workers.ready)
status('Deriving key parts')
salt = new Uint8Array(salt)
const seedParts = await Promise.all(workers.map((worker, index) => {
const nonce = index
return worker.request('kdf', {
key: seed,
salt,
nonce,
staticSalt: config.crypto.staticSalt,
staticBcryptSalt: config.crypto.staticBcryptSalt
}).then(data => {
let jsonData
try {
jsonData = JSON.parse(data)
data = jsonData
} catch (e) {
// ...
}
if (seed !== data.key) throw new Error('Error, incorrect key. ' + seed + ' !== ' + data.key)
if (nonce !== data.nonce) throw new Error('Error, incorrect nonce')
return data.result
})
}))
status('Combining key parts')
const result = new Sha512().process(utils.stringtoUTF8Array(config.crypto.staticSalt + seedParts.reduce((a, c) => a + c))).finish().result
status('Key is ready ')
return result
}

View File

@@ -0,0 +1,39 @@
/**
* Not to be confused with register name...this is a special use case
*/
import { request, createTransaction, processTransaction } from './api.js'
const TX_TYPE = 3 // NAME_REGISTRATION
const CHECK_LAST_REF_INTERVAL = 30 * 1000 // err 30 seconds
const pendingAddresses = {}
const checkLastRefs = () => {
Object.entries(pendingAddresses).forEach(([address, fn]) => {
request('addresses/lastreference/' + address).then(res => {
if (res === 'false') return
fn(res)
delete pendingAddresses[address]
clearInterval(lastRefInterval)
})
})
}
const lastRefInterval = setInterval(() => checkLastRefs(), CHECK_LAST_REF_INTERVAL)
const callOnLastRef = (address, fn) => {
pendingAddresses[address] = fn
}
export const registerUsername = async ({ name, address, lastRef, keyPair }) => {
callOnLastRef(address, lastreference => {
const txBytes = createTransaction(TX_TYPE, keyPair, {
registrantPublicKey: keyPair.publicKey,
registrantAddress: address,
name,
value: address,
lastReference: lastreference
})
processTransaction(txBytes).then(res => { })
})
}

29
crypto/api/storeWallet.js Normal file
View File

@@ -0,0 +1,29 @@
import { HmacSha512, AES_CBC } from 'asmcrypto.js'
import { kdf } from './kdf.js'
import Base58 from './deps/Base58.js'
const getRandomValues = window.crypto ? window.crypto.getRandomValues.bind(window.crypto) : window.msCrypto.getRandomValues.bind(window.msCrypto)
export const generateSaveWalletData = async (wallet, password, kdfThreads, statusUpdateFn) => {
statusUpdateFn('Generating random values')
let iv = new Uint8Array(16)
getRandomValues(iv)
let salt = new Uint8Array(32)
getRandomValues(salt)
const key = await kdf(password, salt, statusUpdateFn)
statusUpdateFn('Encrypting seed')
const encryptionKey = key.slice(0, 32)
const macKey = key.slice(32, 63)
const encryptedSeed = AES_CBC.encrypt(wallet._byteSeed, encryptionKey, false, iv)
statusUpdateFn('Generating mac')
const mac = new HmacSha512(macKey).process(encryptedSeed).finish().result
return {
address0: wallet._addresses[0].address,
encryptedSeed: Base58.encode(encryptedSeed),
salt: Base58.encode(salt),
iv: Base58.encode(iv),
version: wallet._walletVersion,
mac: Base58.encode(mac),
kdfThreads
}
}

140
crypto/api/tradeRequest.js Normal file
View File

@@ -0,0 +1,140 @@
// Trade Bot
import TradeBotCreateRequest from './transactions/trade-portal/tradebot/TradeBotCreateRequest.js'
import TradeBotRespondRequest from './transactions/trade-portal/tradebot/TradeBotRespondRequest.js'
import signTradeBotTransaction from './transactions/trade-portal/tradebot/signTradeBotTransaction.js'
import DeleteTradeOffer from './transactions/trade-portal/tradeoffer/DeleteTradeOffer.js'
import { request } from './fetch-request'
// TradeBotCreateRequest
export const tradeBotCreateRequest = (requestObject) => {
const txn = new TradeBotCreateRequest().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradebot/create?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'text/plain',
'Content-Type': 'application/json'
},
body: JSON.stringify(txn)
})
}
// TradeBotRespondRequest
export const tradeBotRespondRequest = (requestObject) => {
const txn = new TradeBotRespondRequest().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradebot/respond?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(txn)
})
}
// Sign Trade Transactions
export const signTradeBotTxn = (unsignedTxn, keyPair) => {
return signTradeBotTransaction(unsignedTxn, keyPair)
}
// Delete Trade Offer
export const deleteTradeOffer = (requestObject) => {
const txn = new DeleteTradeOffer().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradeoffer?apiKey=${myNode.apiKey}`, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(txn)
})
}
// Send BTC
export const sendBtc = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/btc/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}
// Send LTC
export const sendLtc = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/ltc/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}
// Send DOGE
export const sendDoge = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/doge/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}
// Send DGB
export const sendDgb = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/dgb/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}
// Send RVN
export const sendRvn = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/rvn/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}
// Send ARRR
export const sendArrr = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/arrr/send?apiKey=${myNode.apiKey}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(requestObject)
})
}

View File

@@ -0,0 +1,35 @@
'use strict'
import TransactionBase from './TransactionBase.js'
import { QORT_DECIMALS } from '../constants.js'
export default class PaymentTransaction extends TransactionBase {
constructor() {
super()
this.type = 20
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
}
set amount(amount) {
this._amount = amount * QORT_DECIMALS
this._amountBytes = this.constructor.utils.int64ToBytes(amount)
}
set reference(seed) {
const sha = seed => new Sha512().process(seed).finish().result
let reference = sha(sha(seed))
reference += reference
}
get params() {
const params = super.params
params.push(
this._recipient,
this._amountBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,22 @@
'use strict'
import TransactionBase from './TransactionBase.js'
export default class DelegationTransaction extends TransactionBase {
constructor() {
super()
this.type = 18
}
set superNodeAddress(superNodeAddress) {
this._superNodeAddress = superNodeAddress instanceof Uint8Array ? superNodeAddress : this.constructor.Base58.decode(superNodeAddress)
}
get params() {
const params = super.params
params.push(
this._superNodeAddress,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,91 @@
'use strict'
import TransactionBase from './TransactionBase.js'
import { store } from '../../api.js'
export default class DeployAtTransaction extends TransactionBase {
constructor() {
super()
this.type = 16
}
render(html) {
return html`
${this._groupdialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<div>${this._atDeployDialog1}: <span style="color: #000;">${this._rName}</span></div>
<br>
<div>${this.atDeployDialog2}: <span style="color: #000;">${this._rDescription}</span></div>
<br>
</div>
</div>
${this._groupdialog6}
`
}
set atDeployDialog1(atDeployDialog1) {
this._atDeployDialog1 = atDeployDialog1
}
set atDeployDialog2(atDeployDialog2) {
this._atDeployDialog2 = atDeployDialog2
}
set fee(fee) {
this._fee = fee
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set rAmount(rAmount) {
this._rAmount = Math.round(rAmount * store.getState().config.coin.decimals)
this._rAmountBytes = this.constructor.utils.int64ToBytes(this._rAmount)
}
set rName(rName) {
this._rName = rName
this._rNameBytes = this.constructor.utils.stringtoUTF8Array(this._rName.toLocaleLowerCase())
this._rNameLength = this.constructor.utils.int32ToBytes(this._rNameBytes.length)
}
set rDescription(rDescription) {
this._rDescription = rDescription
this._rDescriptionBytes = this.constructor.utils.stringtoUTF8Array(this._rDescription.toLocaleLowerCase())
this._rDescriptionLength = this.constructor.utils.int32ToBytes(this._rDescriptionBytes.length)
}
set atType(atType) {
this._atType = atType
this._atTypeBytes = this.constructor.utils.stringtoUTF8Array(this._atType)
this._atTypeLength = this.constructor.utils.int32ToBytes(this._atTypeBytes.length)
}
set rTags(rTags) {
this._rTags = rTags
this._rTagsBytes = this.constructor.utils.stringtoUTF8Array(this._rTags.toLocaleLowerCase())
this._rTagsLength = this.constructor.utils.int32ToBytes(this._rTagsBytes.length)
}
set rCreationBytes(rCreationBytes) {
const decode = this.constructor.Base58.decode(rCreationBytes)
this._rCreationBytes = this.constructor.utils.stringtoUTF8Array(decode)
this._rCreationBytesLength = this.constructor.utils.int32ToBytes(this._rCreationBytes.length)
}
set rAssetId(rAssetId) {
this._rAssetId = this.constructor.utils.int64ToBytes(rAssetId)
}
get params() {
const params = super.params
params.push(
this._rNameLength,
this._rNameBytes,
this._rDescriptionLength,
this._rDescriptionBytes,
this._atTypeLength,
this._atTypeBytes,
this._rTagsLength,
this._rTagsBytes,
this._rCreationBytesLength,
this._rCreationBytes,
this._rAmountBytes,
this._rAssetId,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,47 @@
'use strict'
import PaymentTransaction from './PaymentTransaction.js'
import { QORT_DECIMALS } from '../constants.js'
export default class MessageTransaction extends PaymentTransaction {
constructor() {
super()
this.type = 17
this._key = this.constructor.utils.int64ToBytes(0);
this._isEncrypted = new Uint8Array(1); // Defaults to false
this._isText = new Uint8Array(1); // Defaults to false
}
set message(message /* UTF8 String */) {
// ...yes? no?
this.messageText = message
// Not sure about encoding here...
this._message = this.constructor.utils.stringtoUTF8Array(message)
this._messageLength = this.constructor.utils.int64ToBytes(this._message.length)
}
set isEncrypted(isEncrypted) {
this._isEncrypted[0] = isEncrypted
}
set isText(isText) {
this._isText[0] = isText
}
get _params() {
return [
this._typeBytes,
this._timestampBytes,
this._lastReference,
this._keyPair.publicKey,
this._recipient,
this._key,
this._amountBytes,
this._messageLength,
this._message,
this._isEncrypted,
this._isText,
this._feeBytes
]
}
}

View File

@@ -0,0 +1,63 @@
'use strict'
import TransactionBase from './TransactionBase.js'
import Base58 from '../deps/Base58.js'
import { store } from '../../api.js'
export default class PaymentTransaction extends TransactionBase {
constructor() {
super()
this.type = 2
}
render(html) {
const conf = store.getState().config
return html`
<table>
<tr>
<th>${this._dialogto}:</th>
</tr>
<tr>
<td>${this.dialogAddress} ${' '}-</td>
<td>${Base58.encode(this._recipient)}</td>
</tr>
${this.recipientName ? html`
<tr>
<td>${this.dialogName} ${' '}-</td>
<td>${this.recipientName}</td>
</tr>
` : ''}
<tr>
<th>${this._dialogamount}</th>
<td>${this._amount / conf.coin.decimals} ${conf.coin.symbol}</td>
</tr>
</table>
`
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
}
set dialogto(dialogto) {
this._dialogto = dialogto
}
set dialogamount(dialogamount) {
this._dialogamount = dialogamount
}
set amount(amount) {
this._amount = Math.round(amount * store.getState().config.coin.decimals)
this._amountBytes = this.constructor.utils.int64ToBytes(this._amount)
}
get params() {
const params = super.params
params.push(
this._recipient,
this._amountBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,27 @@
"use strict";
import ChatBase from "./chat/ChatBase.js"
import { QORT_DECIMALS } from "../constants.js"
export default class PublicizeTransaction extends ChatBase {
constructor() {
super()
this.type = 19
this.fee = 0
}
set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params;
params.push(
this._proofOfWorkNonce,
this._feeBytes
)
return params;
}
}

View File

@@ -0,0 +1,168 @@
'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() {
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
}
}

View File

@@ -0,0 +1,42 @@
'use strict'
import TransactionBase from './TransactionBase.js'
import Base58 from '../deps/Base58.js'
import { store } from '../../api.js'
import { QORT_DECIMALS } from '../constants.js'
export default class TransferPrivsTransaction extends TransactionBase {
constructor() {
super()
this.type = 40
}
render(html) {
const conf = store.getState().config
return html`
Are you sure to transfer privileges to this account ?
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
On pressing confirm, the transfer privileges request will be sent!
`
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,38 @@
import nacl from '../../deps/nacl-fast.js'
import utils from '../../deps/utils.js'
import Base58 from '../../deps/Base58.js'
const signArbitrary = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => {
if (!arbitraryBytesBase58) {
throw new Error('ArbitraryBytesBase58 not defined')
}
if (!nonce) {
throw new Error('Nonce not defined')
}
if (!keyPair) {
throw new Error('keyPair not defined')
}
const arbitraryBytes = Base58.decode(arbitraryBytesBase58)
const _arbitraryBytesBuffer = Object.keys(arbitraryBytes).map(function (key) { return arbitraryBytes[key]; })
const arbitraryBytesBuffer = new Uint8Array(_arbitraryBytesBuffer)
const arbitraryBytesForSigning = Base58.decode(arbitraryBytesForSigningBase58)
const _arbitraryBytesForSigningBuffer = Object.keys(arbitraryBytesForSigning).map(function (key) { return arbitraryBytesForSigning[key]; })
const arbitraryBytesForSigningBuffer = new Uint8Array(_arbitraryBytesForSigningBuffer)
const _nonce = utils.int32ToBytes(nonce)
arbitraryBytesBuffer.set(_nonce, 112)
arbitraryBytesForSigningBuffer.set(_nonce, 112)
const signature = nacl.sign.detached(arbitraryBytesForSigningBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(arbitraryBytesBuffer, signature)
return signedBytes
}
export default signArbitrary

View File

@@ -0,0 +1,33 @@
import nacl from '../../deps/nacl-fast.js'
import utils from '../../deps/utils.js'
import Base58 from '../../deps/Base58.js'
const signArbitraryWithFee = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) => {
if (!arbitraryBytesBase58) {
throw new Error('ArbitraryBytesBase58 not defined')
}
if (!keyPair) {
throw new Error('keyPair not defined')
}
const arbitraryBytes = Base58.decode(arbitraryBytesBase58)
const _arbitraryBytesBuffer = Object.keys(arbitraryBytes).map(function (key) { return arbitraryBytes[key]; })
const arbitraryBytesBuffer = new Uint8Array(_arbitraryBytesBuffer)
const arbitraryBytesForSigning = Base58.decode(arbitraryBytesForSigningBase58)
const _arbitraryBytesForSigningBuffer = Object.keys(arbitraryBytesForSigning).map(function (key) { return arbitraryBytesForSigning[key]; })
const arbitraryBytesForSigningBuffer = new Uint8Array(_arbitraryBytesForSigningBuffer)
const signature = nacl.sign.detached(arbitraryBytesForSigningBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(arbitraryBytesBuffer, signature)
return signedBytes
}
export default signArbitraryWithFee

View File

@@ -0,0 +1,37 @@
'use strict'
(function () {
function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) => {
const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp)
return nacl.sign.detached(data, keyPair.privateKey)
}
function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) => {
return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), signature)
}
function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) => {
const txType = TYPES.ARBITRARY_TRANSACTION
const typeBytes = int32ToBytes(txType)
const timestampBytes = int64ToBytes(timestamp)
const feeBytes = int64ToBytes(fee * 100000000)
const serviceBytes = int32ToBytes(service)
const dataSizeBytes = int32ToBytes(arbitraryData.length)
const paymentsLengthBytes = int32ToBytes(0) // Support payments - not yet.
var data = new Uint8Array()
data = appendBuffer(data, typeBytes)
data = appendBuffer(data, timestampBytes)
data = appendBuffer(data, lastReference)
data = appendBuffer(data, publicKey)
data = appendBuffer(data, paymentsLengthBytes)
// Here it is necessary to insert the payments, if there are
data = appendBuffer(data, serviceBytes)
data = appendBuffer(data, dataSizeBytes)
data = appendBuffer(data, arbitraryData)
data = appendBuffer(data, feeBytes)
return data
}
}())

View File

@@ -0,0 +1,141 @@
'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 ChatBase {
static get utils() {
return utils
}
static get nacl() {
return nacl
}
static get Base58() {
return Base58
}
constructor() {
this.fee = 0
this.groupID = 0
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)) {
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 chatBytes() {
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._chatBytes = result
return this._chatBytes
}
validParams() {
let finalResult = {
valid: true
}
this.tests.some(test => {
const result = test()
if (result !== true) {
finalResult = {
valid: false,
message: result
}
return true
}
})
return finalResult
}
}

View File

@@ -0,0 +1,92 @@
'use strict'
import ChatBase from "./ChatBase.js"
import nacl from '../../deps/nacl-fast.js'
import ed2curve from '../../deps/ed2curve.js'
import { Sha256 } from 'asmcrypto.js'
import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants.js'
export default class ChatTransaction extends ChatBase {
constructor() {
super()
this.type = 18
this.fee = 0
}
set recipientPublicKey(recipientPublicKey) {
this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey
this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey)
}
set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this._hasReceipient = new Uint8Array(1)
this._hasReceipient[0] = 1
}
set hasChatReference(hasChatReference) {
this._hasChatReference = new Uint8Array(1)
this._hasChatReference[0] = hasChatReference
}
set chatReference(chatReference) {
this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference)
}
set message(message) {
this.messageText = message;
this._message = this.constructor.utils.stringtoUTF8Array(message)
this._messageLength = this.constructor.utils.int32ToBytes(this._message.length)
}
set isEncrypted(isEncrypted) {
this._isEncrypted = new Uint8Array(1)
this._isEncrypted[0] = isEncrypted
if (isEncrypted === 1) {
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey)
const sharedSecret = new Uint8Array(32)
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
this._chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
this._encryptedMessage = nacl.secretbox(this._message, this._lastReference.slice(0, 24), this._chatEncryptionSeed)
}
this._myMessage = isEncrypted === 1 ? this._encryptedMessage : this._message
this._myMessageLenth = isEncrypted === 1 ? this.constructor.utils.int32ToBytes(this._myMessage.length) : this._messageLength
}
set isText(isText) {
this._isText = new Uint8Array(1)
this._isText[0] = isText
}
get params() {
const params = super.params
params.push(
this._proofOfWorkNonce,
this._hasReceipient,
this._recipient,
this._myMessageLenth,
this._myMessage,
this._isEncrypted,
this._isText,
this._feeBytes
)
// After the feature trigger timestamp we need to include chat reference
if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
params.push(this._hasChatReference)
if (this._hasChatReference[0] == 1) {
params.push(this._chatReference)
}
}
return params
}
}

View File

@@ -0,0 +1,68 @@
'use strict'
import ChatBase from "./ChatBase.js"
import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants.js'
export default class GroupChatTransaction extends ChatBase {
constructor() {
super();
this.type = 18
this.fee = 0
}
set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)
}
set hasReceipient(hasReceipient) {
this._hasReceipient = new Uint8Array(1)
this._hasReceipient[0] = hasReceipient
}
set message(message) {
this.messageText = message
this._message = this.constructor.utils.stringtoUTF8Array(message)
this._messageLength = this.constructor.utils.int32ToBytes(this._message.length)
}
set hasChatReference(hasChatReference) {
this._hasChatReference = new Uint8Array(1)
this._hasChatReference[0] = hasChatReference
}
set chatReference(chatReference) {
this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference)
}
set isEncrypted(isEncrypted) {
this._isEncrypted = new Uint8Array(1);
this._isEncrypted[0] = isEncrypted
}
set isText(isText) {
this._isText = new Uint8Array(1)
this._isText[0] = isText
}
get params() {
const params = super.params
params.push(
this._proofOfWorkNonce,
this._hasReceipient,
this._messageLength,
this._message,
this._isEncrypted,
this._isText,
this._feeBytes
)
// After the feature trigger timestamp we need to include chat reference
if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
params.push(this._hasChatReference)
if (this._hasChatReference[0] == 1) {
params.push(this._chatReference)
}
}
return params
}
}

View File

@@ -0,0 +1,57 @@
import nacl from '../../deps/nacl-fast.js'
import Base58 from '../../deps/Base58.js'
import ed2curve from '../../deps/ed2curve.js'
import { Sha256 } from 'asmcrypto.js'
export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => {
let _encryptedMessage = Base58.decode(encryptedMessage)
const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey)
const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference)
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey)
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
const _decryptedMessage = nacl.secretbox.open(_encryptedMessage, _lastReference.slice(0, 24), _chatEncryptionSeed)
let decryptedMessage = ''
_decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage)
return decryptedMessage
}
export const decryptChatMessageBase64 = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => {
let _encryptedMessage = atob(encryptedMessage);
const binaryLength = _encryptedMessage.length;
const bytes = new Uint8Array(binaryLength);
for (let i = 0; i < binaryLength; i++) {
bytes[i] = _encryptedMessage.charCodeAt(i);
}
const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey)
const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference)
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey)
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
const _decryptedMessage = nacl.secretbox.open(bytes, _lastReference.slice(0, 24), _chatEncryptionSeed)
if (_decryptedMessage === false) {
return _decryptedMessage
}
return new TextDecoder('utf-8').decode(_decryptedMessage)
}

View File

@@ -0,0 +1,43 @@
import nacl from '../../deps/nacl-fast.js'
import utils from '../../deps/utils.js'
const signChat = (chatBytes, nonce, keyPair) => {
if (!chatBytes) {
throw new Error('Chat Bytes not defined')
}
if (!nonce) {
throw new Error('Nonce not defined')
}
if (!keyPair) {
throw new Error('keyPair not defined')
}
const _nonce = utils.int32ToBytes(nonce)
if (chatBytes.length === undefined) {
const _chatBytesBuffer = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; })
const chatBytesBuffer = new Uint8Array(_chatBytesBuffer)
chatBytesBuffer.set(_nonce, 112)
const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(chatBytesBuffer, signature)
return signedBytes
} else {
const chatBytesBuffer = new Uint8Array(chatBytes)
chatBytesBuffer.set(_nonce, 112)
const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(chatBytesBuffer, signature)
return signedBytes
}
}
export default signChat

View File

@@ -0,0 +1,53 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class AddGroupAdminTransaction extends TransactionBase {
constructor() {
super()
this.type = 24
}
render(html) {
return html`
${this._addAdminDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._addAdminDialog2}
`
}
set addAdminDialog1(addAdminDialog1) {
this._addAdminDialog1 = addAdminDialog1
}
set addAdminDialog2(addAdminDialog2) {
this._addAdminDialog2 = addAdminDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,53 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class CancelGroupBanTransaction extends TransactionBase {
constructor() {
super()
this.type = 27
}
render(html) {
return html`
${this._cancelBanMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._cancelBanMemberDialog2}
`
}
set cancelBanMemberDialog1(cancelBanMemberDialog1) {
this._cancelBanMemberDialog1 = cancelBanMemberDialog1
}
set cancelBanMemberDialog2(cancelBanMemberDialog2) {
this._cancelBanMemberDialog2 = cancelBanMemberDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,60 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class CancelGroupInviteTransaction extends TransactionBase {
constructor() {
super()
this.type = 30
}
render(html) {
return html`
${this._cancelInviteDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._memberName}</span>
</div>
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._cancelInviteDialog2}
`
}
set memberName(memberName) {
this._memberName = memberName
}
set cancelInviteDialog1(cancelInviteDialog1) {
this._cancelInviteDialog1 = cancelInviteDialog1
}
set cancelInviteDialog2(cancelInviteDialog2) {
this._cancelInviteDialog2 = cancelInviteDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,98 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class CreateGroupTransaction extends TransactionBase {
constructor() {
super()
this.type = 22
}
render(html) {
return html`
${this._groupdialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<div>${this._groupdialog7}: <span style="color: #000;">${this._rGroupName}</span></div>
<br>
<div>${this._groupdialog8}: <span style="color: #000;">${this._rGroupDesc}</span></div>
<br>
<div>${this._groupdialog9}: <span style="color: #000;">${this.myGroupType === 1 ? "Public" : "Private"}</span></div>
</div>
${this._groupdialog6}
`
}
set groupdialog5(groupdialog5) {
this._groupdialog5 = groupdialog5
}
set groupdialog6(groupdialog6) {
this._groupdialog6 = groupdialog6
}
set groupdialog7(groupdialog7) {
this._groupdialog7 = groupdialog7
}
set groupdialog8(groupdialog8) {
this._groupdialog8 = groupdialog8
}
set groupdialog9(groupdialog9) {
this._groupdialog9 = groupdialog9
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set rGroupName(rGroupName) {
this._rGroupName = rGroupName
this._rGroupNameBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupName.toLocaleLowerCase())
this._rGroupNameLength = this.constructor.utils.int32ToBytes(this._rGroupNameBytes.length)
}
set rGroupDesc(rGroupDesc) {
this._rGroupDesc = rGroupDesc
this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupDesc.toLocaleLowerCase())
this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length)
}
set rGroupType(rGroupType) {
this.myGroupType = rGroupType
this._rGroupType = new Uint8Array(1)
this._rGroupType[0] = rGroupType
}
set rGroupApprovalThreshold(rGroupApprovalThreshold) {
this._rGroupApprovalThreshold = new Uint8Array(1)
this._rGroupApprovalThreshold[0] = rGroupApprovalThreshold
}
set rGroupMinimumBlockDelay(rGroupMinimumBlockDelay) {
this._rGroupMinimumBlockDelay = rGroupMinimumBlockDelay
this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMinimumBlockDelay)
}
set rGroupMaximumBlockDelay(rGroupMaximumBlockDelay) {
this._rGroupMaximumBlockDelay = rGroupMaximumBlockDelay
this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMaximumBlockDelay)
}
get params() {
const params = super.params
params.push(
this._rGroupNameLength,
this._rGroupNameBytes,
this._rGroupDescLength,
this._rGroupDescBytes,
this._rGroupType,
this._rGroupApprovalThreshold,
this._rGroupMinimumBlockDelayBytes,
this._rGroupMaximumBlockDelayBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,67 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class GroupBanTransaction extends TransactionBase {
constructor() {
super()
this.type = 26
}
render(html) {
return html`
${this._banMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._banMemberDialog2}
`
}
set banMemberDialog1(banMemberDialog1) {
this._banMemberDialog1 = banMemberDialog1
}
set banMemberDialog2(banMemberDialog2) {
this._banMemberDialog2 = banMemberDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set rBanReason(rBanReason) {
this._rBanReason = rBanReason
this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase())
this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length)
}
set rBanTime(rBanTime) {
this._rBanTime = rBanTime
this._rBanTimeBytes = this.constructor.utils.int32ToBytes(this._rBanTime)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._rBanReasonLength,
this._rBanReasonBytes,
this._rBanTimeBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,59 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class GroupInviteTransaction extends TransactionBase {
constructor() {
super()
this.type = 29
}
render(html) {
return html`
${this._inviteMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._inviteMemberDialog2}
`
}
set inviteMemberDialog1(inviteMemberDialog1) {
this._inviteMemberDialog1 = inviteMemberDialog1
}
set inviteMemberDialog2(inviteMemberDialog2) {
this._inviteMemberDialog2 = inviteMemberDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set rInviteTime(rInviteTime) {
this._rInviteTime = rInviteTime
this._rInviteTimeBytes = this.constructor.utils.int32ToBytes(this._rInviteTime)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._rInviteTimeBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,61 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class GroupKickTransaction extends TransactionBase {
constructor() {
super()
this.type = 28
}
render(html) {
return html`
${this._kickMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._kickMemberDialog2}
`
}
set kickMemberDialog1(kickMemberDialog1) {
this._kickMemberDialog1 = kickMemberDialog1
}
set kickMemberDialog2(kickMemberDialog2) {
this._kickMemberDialog2 = kickMemberDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set rBanReason(rBanReason) {
this._rBanReason = rBanReason
this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase())
this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._rBanReasonLength,
this._rBanReasonBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,55 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class JoinGroupTransaction extends TransactionBase {
constructor() {
super()
this.type = 31
}
render(html) {
return html`
${this._groupdialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rGroupName}</span>
</div>
${this._groupdialog2}
`
}
set groupdialog1(groupdialog1) {
this._groupdialog1 = groupdialog1
}
set groupdialog2(groupdialog2) {
this._groupdialog2 = groupdialog2
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set registrantAddress(registrantAddress) {
this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress)
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set rGroupName(rGroupName) {
this._rGroupName = rGroupName
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,55 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class LeaveGroupTransaction extends TransactionBase {
constructor() {
super()
this.type = 32
}
render(html) {
return html`
${this._groupdialog3}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rGroupName}</span>
</div>
${this._groupdialog4}
`
}
set groupdialog3(groupdialog3) {
this._groupdialog3 = groupdialog3
}
set groupdialog4(groupdialog4) {
this._groupdialog4 = groupdialog4
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set registrantAddress(registrantAddress) {
this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress)
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set rGroupName(rGroupName) {
this._rGroupName = rGroupName
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,53 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class RemoveGroupAdminTransaction extends TransactionBase {
constructor() {
super()
this.type = 25
}
render(html) {
return html`
${this._kickAdminDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span>
</div>
${this._kickAdminDialog2}
`
}
set kickAdminDialog1(kickAdminDialog1) {
this._kickAdminDialog1 = kickAdminDialog1
}
set kickAdminDialog2(kickAdminDialog2) {
this._kickAdminDialog2 = kickAdminDialog2
}
set rGroupId(rGroupId) {
this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
get params() {
const params = super.params
params.push(
this._rGroupIdBytes,
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,72 @@
'use strict';
import TransactionBase from '../TransactionBase.js'
import Base58 from '../../deps/Base58.js'
import { store } from '../../../api.js'
import { QORT_DECIMALS } from "../../constants.js"
export default class UpdateGroupTransaction extends TransactionBase {
constructor() {
super()
this.type = 23
}
render(html) {
const conf = store.getState().config
return html`
Are you sure to update this group ?
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
</div>
On pressing confirm, the group details will be updated!
`
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set newOwner(newOwner) {
this._newOwner = newOwner instanceof Uint8Array ? newOwner : this.constructor.Base58.decode(newOwner)
}
set newIsOpen(newIsOpen) {
this._rGroupType = new Uint8Array(1)
this._rGroupType[0] = newIsOpen
}
set newDescription(newDescription) {
this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(newDescription.toLocaleLowerCase())
this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length)
}
set newApprovalThreshold(newApprovalThreshold) {
this._rGroupApprovalThreshold = new Uint8Array(1)
this._rGroupApprovalThreshold[0] = newApprovalThreshold;
}
set newMinimumBlockDelay(newMinimumBlockDelay) {
this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMinimumBlockDelay)
}
set newMaximumBlockDelay(newMaximumBlockDelay) {
this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMaximumBlockDelay)
}
set _groupId(_groupId){
this._groupBytes = this.constructor.utils.int32ToBytes(_groupId)
}
get params() {
const params = super.params
params.push(
this._groupBytes,
this._newOwner,
this._rGroupDescLength,
this._rGroupDescBytes,
this._rGroupType,
this._rGroupApprovalThreshold,
this._rGroupMinimumBlockDelayBytes,
this._rGroupMaximumBlockDelayBytes,
this._feeBytes
)
console.log('verify params', params)
return params
}
}

View File

@@ -0,0 +1,70 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class BuyNameTransacion extends TransactionBase {
constructor() {
super()
this.type = 7
}
render(html) {
return html`
${this._buyNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span>
</div>
${this._buyNameDialog2}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.showSellPrice}</span>
</div>
${this._buyNameDialog3}
`
}
set buyNameDialog1(buyNameDialog1) {
this._buyNameDialog1 = buyNameDialog1
}
set buyNameDialog2(buyNameDialog2) {
this._buyNameDialog2 = buyNameDialog2
}
set buyNameDialog3(buyNameDialog3) {
this._buyNameDialog3 = buyNameDialog3
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set name(name) {
this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
}
set sellPrice(sellPrice) {
this.showSellPrice = sellPrice
this._sellPrice = sellPrice * QORT_DECIMALS
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient
}
get params() {
const params = super.params
params.push(
this._nameLength,
this._nameBytes,
this._sellPriceBytes,
this._recipient,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,49 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class CancelSellNameTransacion extends TransactionBase {
constructor() {
super()
this.type = 6
}
render(html) {
return html`
${this._cancelSellNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span>
</div>
${this._cancelSellNameDialog2}
`
}
set cancelSellNameDialog1(cancelSellNameDialog1) {
this._cancelSellNameDialog1 = cancelSellNameDialog1
}
set cancelSellNameDialog2(cancelSellNameDialog2) {
this._cancelSellNameDialog2 = cancelSellNameDialog2
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set name(name) {
this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
}
get params() {
const params = super.params
params.push(
this._nameLength,
this._nameBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,57 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class RegisterNameTransaction extends TransactionBase {
constructor() {
super()
this.type = 3
}
render(html) {
return html`
${this._dialogyou}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span>
</div>
${this._dialogonpress}
`
}
set dialogyou(dialogyou) {
this._dialogyou = dialogyou
}
set dialogonpress(dialogonpress) {
this._dialogonpress = dialogonpress
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set name(name) {
this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
}
set value(value) {
this.valueText = value.length === 0 ? "Registered Name on the Qortal Chain" : value
this._valueBytes = this.constructor.utils.stringtoUTF8Array(this.valueText)
this._valueLength = this.constructor.utils.int32ToBytes(this._valueBytes.length)
}
get params() {
const params = super.params
params.push(
this._nameLength,
this._nameBytes,
this._valueLength,
this._valueBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,64 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class SellNameTransacion extends TransactionBase {
constructor() {
super()
this.type = 5
}
render(html) {
return html`
${this._sellNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span>
</div>
${this._sellNameDialog2}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.showSellPrice}</span>
</div>
${this._sellNameDialog3}
`
}
set sellNameDialog1(sellNameDialog1) {
this._sellNameDialog1 = sellNameDialog1
}
set sellNameDialog2(sellNameDialog2) {
this._sellNameDialog2 = sellNameDialog2
}
set sellNameDialog3(sellNameDialog3) {
this._sellNameDialog3 = sellNameDialog3
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set name(name) {
this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
}
set sellPrice(sellPrice) {
this.showSellPrice = sellPrice
this._sellPrice = sellPrice * QORT_DECIMALS
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
}
get params() {
const params = super.params
params.push(
this._nameLength,
this._nameBytes,
this._sellPriceBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,73 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js'
export default class UpdateNameTransaction extends TransactionBase {
constructor() {
super()
this.type = 4
}
render(html) {
return html`
${this._dialogUpdateName1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span>
</div>
${this._dialogUpdateName2}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.newNameText}</span>
</div>
${this._dialogUpdateName3}
`
}
set dialogUpdateName1(dialogUpdateName1) {
this._dialogUpdateName1 = dialogUpdateName1
}
set dialogUpdateName2(dialogUpdateName2) {
this._dialogUpdateName2 = dialogUpdateName2
}
set dialogUpdateName3(dialogUpdateName3) {
this._dialogUpdateName3 = dialogUpdateName3
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set name(name) {
this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
}
set newName(newName) {
this.newNameText = newName
this._newNameBytes = this.constructor.utils.stringtoUTF8Array(newName)
this._newNameLength = this.constructor.utils.int32ToBytes(this._newNameBytes.length)
}
set newData(newData) {
this.newDataText = newData.length === 0 ? "Registered Name on the Qortal Chain" : newData
this._newDataBytes = this.constructor.utils.stringtoUTF8Array(this.newDataText)
this._newDataLength = this.constructor.utils.int32ToBytes(this._newDataBytes.length)
}
get params() {
const params = super.params
params.push(
this._nameLength,
this._nameBytes,
this._newNameLength,
this._newNameBytes,
this._newDataLength,
this._newDataBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,36 @@
'use strict'
(function () {
function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) => {
const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp)
return nacl.sign.detached(data, keyPair.privateKey)
}
function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) => {
return appendBuffer(generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), signature)
}
function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) => {
const txType = TYPES.REGISTER_NAME_TRANSACTION
const typeBytes = int32ToBytes(txType)
const timestampBytes = int64ToBytes(timestamp)
const feeBytes = int64ToBytes(fee * 100000000)
const nameSizeBytes = int32ToBytes(name.length)
const valueSizeBytes = int32ToBytes(value.length)
let data = new Uint8Array()
data = appendBuffer(data, typeBytes)
data = appendBuffer(data, timestampBytes)
data = appendBuffer(data, lastReference)
data = appendBuffer(data, publicKey)
data = appendBuffer(data, owner)
data = appendBuffer(data, nameSizeBytes)
data = appendBuffer(data, name)
data = appendBuffer(data, valueSizeBytes)
data = appendBuffer(data, value)
data = appendBuffer(data, feeBytes)
return data
}
}())

View File

@@ -0,0 +1,55 @@
'use strict'
import TransactionBase from '../TransactionBase.js'
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
import { Base58 } from '../../deps/deps.js'
export default class RemoveRewardShareTransaction extends TransactionBase {
constructor() {
super()
this.type = 38
}
render(html) {
return html`
${this._rewarddialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.constructor.Base58.encode(this._recipient)}</span>
</div>
${this._rewarddialog6}
`
}
set rewarddialog5(rewarddialog5) {
this._rewarddialog5 = rewarddialog5
}
set rewarddialog6(rewarddialog6) {
this._rewarddialog6 = rewarddialog6
}
set rewardShareKeyPairPublicKey(rewardShareKeyPairPublicKey) {
this._rewardShareKeyPairPublicKey = Base58.decode(rewardShareKeyPairPublicKey)
}
set recipient(recipient) {
const _address = publicKeyToAddress(this._keyPair.publicKey)
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.fee = _address === recipient ? 0 : 0.001
}
set percentageShare(share) {
this._percentageShare = share * 100
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
}
get params() {
const params = super.params
params.push(
this._recipient,
this._rewardShareKeyPairPublicKey,
this._percentageShareBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,78 @@
'use strict'
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
import TransactionBase from "../TransactionBase.js"
import nacl from '../../deps/nacl-fast.js'
import ed2curve from '../../deps/ed2curve.js'
import { Sha256 } from 'asmcrypto.js'
export default class RewardShareTransaction extends TransactionBase {
constructor() {
super()
this.type = 38
}
render(html) {
return html`
${this._rewarddialog1} <strong>${this._percentageShare / 1e8}%</strong> ${this._rewarddialog2} <strong>${this.constructor.Base58.encode(this._recipient)}</strong>?
${this._rewarddialog3}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._base58RewardShareSeed}</span>
</div>
${this._rewarddialog4}
`
}
set rewarddialog1(rewarddialog1) {
this._rewarddialog1 = rewarddialog1
}
set rewarddialog2(rewarddialog2) {
this._rewarddialog2 = rewarddialog2
}
set rewarddialog3(rewarddialog3) {
this._rewarddialog3 = rewarddialog3
}
set rewarddialog4(rewarddialog4) {
this._rewarddialog4 = rewarddialog4
}
set recipientPublicKey(recipientPublicKey) {
this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey
this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey)
this.recipient = publicKeyToAddress(this._recipientPublicKey)
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.001)
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey)
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey);
this._rewardShareSeed = new Sha256().process(sharedSecret).finish().result
this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed)
}
set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
}
set percentageShare(share) {
this._percentageShare = share * 100
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
}
get params() {
const params = super.params
params.push(
this._recipient,
this._rewardShareKeyPair.publicKey,
this._percentageShareBytes,
this._feeBytes
)
return params
}
}

View File

@@ -0,0 +1,63 @@
/**
* CrossChain - TradeBot Create Request (Sell Action)
*
* These are special types of transactions (JSON ENCODED)
*/
export default class TradeBotCreateRequest {
constructor() {
// ...
}
createTransaction(txnReq) {
this.creatorPublicKey(txnReq.creatorPublicKey)
this.qortAmount(txnReq.qortAmount)
this.fundingQortAmount(txnReq.fundingQortAmount)
this.foreignBlockchain(txnReq.foreignBlockchain)
this.foreignAmount(txnReq.foreignAmount)
this.tradeTimeout(txnReq.tradeTimeout)
this.receivingAddress(txnReq.receivingAddress)
return this.txnRequest()
}
creatorPublicKey(creatorPublicKey) {
this._creatorPublicKey = creatorPublicKey
}
qortAmount(qortAmount) {
this._qortAmount = qortAmount
}
fundingQortAmount(fundingQortAmount) {
this._fundingQortAmount = fundingQortAmount
}
foreignBlockchain(foreignBlockchain) {
this._foreignBlockchain = foreignBlockchain
}
foreignAmount(foreignAmount) {
this._foreignAmount = foreignAmount
}
tradeTimeout(tradeTimeout) {
this._tradeTimeout = tradeTimeout
}
receivingAddress(receivingAddress) {
this._receivingAddress = receivingAddress
}
txnRequest() {
return {
creatorPublicKey: this._creatorPublicKey,
qortAmount: this._qortAmount,
fundingQortAmount: this._fundingQortAmount,
foreignBlockchain: this._foreignBlockchain,
foreignAmount: this._foreignAmount,
tradeTimeout: this._tradeTimeout,
receivingAddress: this._receivingAddress
}
}
}

View File

@@ -0,0 +1,39 @@
/**
* CrossChain - TradeBot Respond Request (Buy Action)
*
* These are special types of transactions (JSON ENCODED)
*/
export default class TradeBotRespondRequest {
constructor() {
// ...
}
createTransaction(txnReq) {
this.atAddress(txnReq.atAddress)
this.foreignKey(txnReq.foreignKey)
this.receivingAddress(txnReq.receivingAddress)
return this.txnRequest()
}
atAddress(atAddress) {
this._atAddress = atAddress
}
foreignKey(foreignKey) {
this._foreignKey = foreignKey
}
receivingAddress(receivingAddress) {
this._receivingAddress = receivingAddress
}
txnRequest() {
return {
atAddress: this._atAddress,
foreignKey: this._foreignKey,
receivingAddress: this._receivingAddress
}
}
}

View File

@@ -0,0 +1,31 @@
import Base58 from '../../../deps/Base58.js'
import nacl from '../../../deps/nacl-fast.js'
import utils from '../../../deps/utils.js'
const signTradeBotTransaction = (unsignedTxn, keyPair) => {
if (!unsignedTxn) {
throw new Error('Unsigned Transaction Bytes not defined')
}
if (!keyPair) {
throw new Error('keyPair not defined')
}
const txnBuffer = Base58.decode(unsignedTxn)
if (keyPair.privateKey.length === undefined) {
const _privateKey = Object.keys(keyPair.privateKey).map(function (key) { return keyPair.privateKey[key]; })
const privateKey = new Uint8Array(_privateKey)
const signature = nacl.sign.detached(txnBuffer, privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
return signedBytes
} else {
const signature = nacl.sign.detached(txnBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
return signedBytes
}
}
export default signTradeBotTransaction

View File

@@ -0,0 +1,33 @@
/**
* CrossChain - DELETE TradeOffer
*
* These are special types of transactions (JSON ENCODED)
*/
export default class DeleteTradeOffer {
constructor() {
// ...
}
createTransaction(txnReq) {
this.creatorPublicKey(txnReq.creatorPublicKey)
this.atAddress(txnReq.atAddress)
return this.txnRequest()
}
creatorPublicKey(creatorPublicKey) {
this._creatorPublicKey = creatorPublicKey
}
atAddress(atAddress) {
this._atAddress = atAddress
}
txnRequest() {
return {
creatorPublicKey: this._creatorPublicKey,
atAddress: this._atAddress
}
}
}

View File

@@ -0,0 +1,25 @@
import { request } from '../../../fetch-request.js'
import { deleteTradeOffer, signTradeBotTxn } from '../../../tradeRequest.js'
import { processTransaction } from '../../../createTransaction.js'
export const cancelAllOffers = async (requestObject) => {
const keyPair = requestObject.keyPair
const publicKey = requestObject.base58PublicKey
const address = requestObject.address
const getMyOpenOffers = async () => {
const res = await request('/crosschain/tradeoffers')
const myOpenTradeOrders = await res.filter(order => order.mode === "OFFERING" && order.qortalCreator === address)
return myOpenTradeOrders
}
const myOpenOffers = await getMyOpenOffers()
let response = true
myOpenOffers.forEach(async (openOffer) => {
let unsignedTxn = await deleteTradeOffer({ creatorPublicKey: publicKey, atAddress: openOffer.qortalAtAddress })
let signedTxnBytes = await signTradeBotTxn(unsignedTxn, keyPair)
await processTransaction(signedTxnBytes)
})
return response
}

View File

@@ -0,0 +1,52 @@
import PaymentTransaction from './PaymentTransaction.js'
import RegisterNameTransaction from './names/RegisterNameTransaction.js'
import UpdateNameTransaction from './names/UpdateNameTransaction.js'
import SellNameTransacion from './names/SellNameTransacion.js'
import CancelSellNameTransacion from './names/CancelSellNameTransacion.js'
import BuyNameTransacion from './names/BuyNameTransacion.js'
import MessageTransaction from './MessageTransaction.js'
import ChatTransaction from './chat/ChatTransaction.js'
import GroupChatTransaction from './chat/GroupChatTransaction.js'
import PublicizeTransaction from './PublicizeTransaction.js'
import CreateGroupTransaction from './groups/CreateGroupTransaction.js'
import AddGroupAdminTransaction from './groups/AddGroupAdminTransaction.js'
import RemoveGroupAdminTransaction from './groups/RemoveGroupAdminTransaction.js'
import GroupBanTransaction from './groups/GroupBanTransaction.js'
import CancelGroupBanTransaction from './groups/CancelGroupBanTransaction.js'
import GroupKickTransaction from './groups/GroupKickTransaction.js'
import GroupInviteTransaction from './groups/GroupInviteTransaction.js'
import CancelGroupInviteTransaction from './groups/CancelGroupInviteTransaction.js'
import JoinGroupTransaction from './groups/JoinGroupTransaction.js'
import UpdateGroupTransaction from './groups/UpdateGroupTransaction.js'
import LeaveGroupTransaction from './groups/LeaveGroupTransaction.js'
import RewardShareTransaction from './reward-share/RewardShareTransaction.js'
import RemoveRewardShareTransaction from './reward-share/RemoveRewardShareTransaction.js'
import TransferPrivsTransaction from './TransferPrivsTransaction.js'
import DeployAtTransaction from './DeployAtTransaction.js'
export const transactionTypes = {
2: PaymentTransaction,
3: RegisterNameTransaction,
4: UpdateNameTransaction,
5: SellNameTransacion,
6: CancelSellNameTransacion,
7: BuyNameTransacion,
16: DeployAtTransaction,
17: MessageTransaction,
18: ChatTransaction,
181: GroupChatTransaction,
19: PublicizeTransaction,
22: CreateGroupTransaction,
24: AddGroupAdminTransaction,
25: RemoveGroupAdminTransaction,
26: GroupBanTransaction,
27: CancelGroupBanTransaction,
28: GroupKickTransaction,
29: GroupInviteTransaction,
30: CancelGroupInviteTransaction,
31: JoinGroupTransaction,
32: LeaveGroupTransaction,
38: RewardShareTransaction,
381: RemoveRewardShareTransaction,
40: TransferPrivsTransaction
}

View File

@@ -0,0 +1,11 @@
export const randomBase58Generator = (digits) => {
digits = digits || 0
let base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split('')
let result = ''
let char
while (result.length < digits) {
char = base58[Math.random() * 57 >> 0]
if (result.indexOf(char) === -1) result += char
}
return result
}

View File

@@ -0,0 +1,31 @@
import { store } from '../../api.js'
let subscriptions = []
// Have to wait with init because something import stateAwait before the store gets initialized
let initialized = false
const init = () => {
initialized = true
store.subscribe(() => {
const state = store.getState()
subscriptions = subscriptions.filter(fn => fn(state))
})
}
export const stateAwait = fn => {
return new Promise((resolve, reject) => {
// Check immediately...then if not true store it
if (!initialized) {
init()
}
if (fn(store.getState())) resolve()
subscriptions.push(state => {
if (fn(state)) {
resolve()
return true
}
return false
})
})
}

View File

@@ -0,0 +1,8 @@
import publicKeyToAddress from './publicKeyToAddress'
import Base58 from '../deps/Base58.js'
export const base58PublicKeyToAddress = (base58pubkey, qora = false) => {
const decodePubKey = Base58.decode(base58pubkey)
const address = publicKeyToAddress(decodePubKey, qora)
return address
}

View File

@@ -0,0 +1,35 @@
import Base58 from '../deps/Base58.js'
import BROKEN_RIPEMD160 from '../deps/broken-ripemd160.js'
import RIPEMD160 from '../deps/ripemd160.js'
import utils from '../deps/utils.js'
import { ADDRESS_VERSION } from '../constants.js'
import { Buffer } from 'buffer'
import { Sha256 } from 'asmcrypto.js'
const repeatSHA256 = (passphrase, hashes) => {
let hash = passphrase
for (let i = 0; i < hashes; i++) {
hash = new Sha256().process(hash).finish().result
}
return hash
}
const publicKeyToAddress = (publicKey, qora = false) => {
const publicKeySha256 = new Sha256().process(publicKey).finish().result
const _publicKeyHash = qora ? new BROKEN_RIPEMD160().digest(publicKeySha256) : new RIPEMD160().update(Buffer.from(publicKeySha256)).digest('hex')
const publicKeyHash = qora ? _publicKeyHash : _publicKeyHash
let address = new Uint8Array()
address = utils.appendBuffer(address, [ADDRESS_VERSION])
address = utils.appendBuffer(address, publicKeyHash)
const checkSum = repeatSHA256(address, 2)
address = utils.appendBuffer(address, checkSum.subarray(0, 4))
address = Base58.encode(address)
return address
}
export default publicKeyToAddress

View File

@@ -0,0 +1,10 @@
import Base58 from '../deps/Base58.js'
export const validateAddress = (address) => {
const decodePubKey = Base58.decode(address)
if (!(decodePubKey instanceof Uint8Array && decodePubKey.length == 25)) {
return false
}
return true
}

3
crypto/api_deps.js Normal file
View File

@@ -0,0 +1,3 @@
let store
export { store }
export const initApi = (s) => { store = s }

37
crypto/config.js Normal file
View File

@@ -0,0 +1,37 @@
import { store } from './api.js'
let config = false
let loaded = false
const configWatchers = []
const waitingForConfig = []
const subscribeToStore = () => {
if (!store) return setTimeout(() => subscribeToStore(), 50)
store.subscribe(() => {
const cA = store.getState().app
const c = store.getState().config
if (!c.loaded) return
if (!loaded) waitingForConfig.forEach(r => r(cA))
configWatchers.forEach(fn => fn(cA))
config = cA
})
}
subscribeToStore()
export function getConfig() {
return config
}
export function watchConfig(fn) {
fn(config)
configWatchers.push(fn)
}
export function waitForConfig() {
return new Promise((resolve, reject) => {
if (config) return resolve(config)
waitingForConfig.push(resolve)
})
}