diff --git a/lib/detect-platform.js b/lib/detect-platform.js new file mode 100644 index 00000000..1763e086 --- /dev/null +++ b/lib/detect-platform.js @@ -0,0 +1,11 @@ +const os = require('os') + +const isMac = os.platform() === "darwin" +const isWindows = os.platform() === "win32" +const isLinux = os.platform() === "linux" + +module.exports = { + isMac, + isWindows, + isLinux, +} \ No newline at end of file diff --git a/qortal-ui-core/src/plugins/routes.js b/qortal-ui-core/src/plugins/routes.js index f51001f8..4e81f894 100644 --- a/qortal-ui-core/src/plugins/routes.js +++ b/qortal-ui-core/src/plugins/routes.js @@ -22,8 +22,10 @@ import framePasteMenu from '../functional-components/frame-paste-menu.js'; const createTransaction = api.createTransaction; const processTransaction = api.processTransaction; +const processTransactionVersion2 = api.processTransactionVersion2; const signChatTransaction = api.signChatTransaction; const signArbitraryTransaction = api.signArbitraryTransaction; +const signArbitraryWithFeeTransaction = api.signArbitraryWithFeeTransaction; const tradeBotCreateRequest = api.tradeBotCreateRequest; const tradeBotRespondRequest = api.tradeBotRespondRequest; const signTradeBotTxn = api.signTradeBotTxn; @@ -144,8 +146,16 @@ export const routes = { if (!req.disableModal && !req.data.disableModal) { await requestTransactionDialog.requestTransaction(tx); } - - const res = await processTransaction(tx.signedBytes); + + let res + + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(tx.signedBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(tx.signedBytes); + } + let extraData = {} if(req.data.type === 38 && tx && tx._rewardShareKeyPair && tx._rewardShareKeyPair.secretKey){ extraData.rewardSharePrivateKey = Base58.encode(tx._rewardShareKeyPair.secretKey) @@ -191,7 +201,16 @@ export const routes = { _keyPair, req.data.params ); - const res = await processTransaction(tx.signedBytes); + let res + + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(tx.signedBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(tx.signedBytes); + } + + response = { success: true, data: res, @@ -242,8 +261,16 @@ export const routes = { req.data.chatNonce, store.getState().app.wallet._addresses[req.data.nonce].keyPair ); + + let res - const res = await processTransaction(signedChatBytes); + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(signedChatBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(signedChatBytes); + } + response = res; } catch (e) { console.error(e); @@ -262,8 +289,41 @@ export const routes = { req.data.arbitraryNonce, store.getState().app.wallet._addresses[req.data.nonce].keyPair ); + let res - const res = await processTransaction(signedArbitraryBytes); + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(signedArbitraryBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(signedArbitraryBytes); + } + + response = res; + } catch (e) { + console.error(e); + console.error(e.message); + response = false; + } + return response; + }, + + sign_arbitrary_with_fee: async (req) => { + let response; + try { + const signedArbitraryBytes = await signArbitraryWithFeeTransaction( + req.data.arbitraryBytesBase58, + req.data.arbitraryBytesForSigningBase58, + store.getState().app.wallet._addresses[req.data.nonce].keyPair + ); + let res + + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(signedArbitraryBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(signedArbitraryBytes); + } + response = res; } catch (e) { console.error(e); @@ -293,8 +353,14 @@ export const routes = { unsignedTxn, store.getState().app.selectedAddress.keyPair ); + let res - const res = await processTransaction(signedTxnBytes); + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(signedTxnBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(signedTxnBytes); + } response = res; } catch (e) { console.error(e); @@ -327,8 +393,15 @@ export const routes = { unsignedTxn, store.getState().app.selectedAddress.keyPair ); + + let res - const res = await processTransaction(signedTxnBytes); + if(req.data.apiVersion && req.data.apiVersion === 2){ + res = await processTransactionVersion2(signedTxnBytes) + } + if(!req.data.apiVersion){ + res = await processTransaction(signedTxnBytes); + } response = res; } catch (e) { diff --git a/qortal-ui-crypto/api/api.js b/qortal-ui-crypto/api/api.js index 98da919b..36a635cc 100644 --- a/qortal-ui-crypto/api/api.js +++ b/qortal-ui-crypto/api/api.js @@ -1,5 +1,5 @@ export { request } from './fetch-request.js' export { transactionTypes as transactions } from './transactions/transactions.js' -export { processTransaction, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction } from './createTransaction.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' diff --git a/qortal-ui-crypto/api/createTransaction.js b/qortal-ui-crypto/api/createTransaction.js index 2a56aa56..b4bf7802 100644 --- a/qortal-ui-crypto/api/createTransaction.js +++ b/qortal-ui-crypto/api/createTransaction.js @@ -3,6 +3,7 @@ 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) => { @@ -31,8 +32,20 @@ export const signArbitraryTransaction = (arbitraryBytesBase58, arbitraryBytesFor 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) +}) + diff --git a/qortal-ui-crypto/api/transactions/DeployAtTransaction.js b/qortal-ui-crypto/api/transactions/DeployAtTransaction.js new file mode 100644 index 00000000..a9b3ad5f --- /dev/null +++ b/qortal-ui-crypto/api/transactions/DeployAtTransaction.js @@ -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} +
+
${this._atDeployDialog1}: ${this._rName}
+
+
${this.atDeployDialog2}: ${this._rDescription}
+
+
+ + ${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 + } +} diff --git a/qortal-ui-crypto/api/transactions/arbitrary/signArbitraryWithFee.js b/qortal-ui-crypto/api/transactions/arbitrary/signArbitraryWithFee.js new file mode 100644 index 00000000..1a71cc2e --- /dev/null +++ b/qortal-ui-crypto/api/transactions/arbitrary/signArbitraryWithFee.js @@ -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 diff --git a/qortal-ui-crypto/api/transactions/transactions.js b/qortal-ui-crypto/api/transactions/transactions.js index 9fa87e99..0423d3ae 100644 --- a/qortal-ui-crypto/api/transactions/transactions.js +++ b/qortal-ui-crypto/api/transactions/transactions.js @@ -22,6 +22,7 @@ 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, @@ -30,6 +31,7 @@ export const transactionTypes = { 5: SellNameTransacion, 6: CancelSellNameTransacion, 7: BuyNameTransacion, + 16: DeployAtTransaction, 17: MessageTransaction, 18: ChatTransaction, 181: GroupChatTransaction,