UNPKG

aion-gql-webcomponents

Version:
100 lines (99 loc) 4.71 kB
import rlp from "aion-rlp"; import { AionLong } from "aion-rlp"; import BN from "bn.js"; import nacl from 'tweetnacl'; import { Buffer } from 'buffer'; import { CryptoUtil } from "./CryptoUtil"; import { SignedTransaction } from "../../common/SignedTransaction"; export class TransactionUtil { static signTransaction(transaction, privateKey) { if (privateKey) { if (privateKey.startsWith("0x")) privateKey = privateKey.substring(2); } const rlpOutput = this.rlpEncode(transaction); const hash = CryptoUtil.blake2b256(rlpOutput); const privateKeyBuff = CryptoUtil.hex2ua(privateKey); const keyPair = nacl.sign.keyPair.fromSecretKey(privateKeyBuff); const signature = nacl.sign.detached(hash, keyPair.secretKey); if (nacl.sign.detached.verify(hash, signature, keyPair.publicKey) === false) { throw new Error('Could not verify signature.'); } let aionPubSigLen = nacl.sign.publicKeyLength + nacl.sign.signatureLength; const aionPubSig = CryptoUtil.concatBuffer(keyPair.publicKey, signature, aionPubSigLen); const rawTx = rlp.decode(rlpOutput).concat(Buffer.from(aionPubSig)); const rawTransaction = rlp.encode(rawTx); const rawTransactionHash = CryptoUtil.uia2hex(rawTransaction); console.log(rawTransactionHash); let signedTransaction = new SignedTransaction(); signedTransaction.messageHash = CryptoUtil.uia2hex(hash); signedTransaction.signature = CryptoUtil.uia2hex(aionPubSig); signedTransaction.rawTransaction = CryptoUtil.uia2hex(rawTransaction); signedTransaction.input = transaction; return signedTransaction; } static verifyAndEncodedSignTransaction(transaction, rlpEncoded, signature, publicKey) { const hash = CryptoUtil.blake2b256(rlpEncoded); if (nacl.sign.detached.verify(hash, signature, publicKey) === false) { console.log("Could not verify the signature from ledger"); } let aionPubSigLen = nacl.sign.publicKeyLength + nacl.sign.signatureLength; const aionPubSig = CryptoUtil.concatBuffer(publicKey, signature, aionPubSigLen); const rawTx = rlp.decode(rlpEncoded).concat(Buffer.from(aionPubSig)); const rawTransaction = rlp.encode(rawTx); const rawTransactionHash = CryptoUtil.uia2hex(rawTransaction); console.log(rawTransactionHash); let signedTransaction = new SignedTransaction(); signedTransaction.messageHash = CryptoUtil.uia2hex(hash); signedTransaction.signature = CryptoUtil.uia2hex(aionPubSig); signedTransaction.rawTransaction = CryptoUtil.uia2hex(rawTransaction); signedTransaction.input = transaction; return signedTransaction; } static rlpEncode(transaction) { const txArray = new Array(); if (transaction.to) { transaction.to = transaction.to.toLowerCase(); if (!transaction.to.startsWith("0x")) transaction.to = "0x" + transaction.to; } txArray.push(new BN(transaction.nonce)); txArray.push(transaction.to); txArray.push(transaction.value); txArray.push(transaction.data); if (transaction.timestamp !== 0) txArray.push(transaction.timestamp); else { transaction.timestamp = Date.now() * 1000; txArray.push(transaction.timestamp); } if (transaction.gas) txArray.push(new AionLong(new BN(transaction.gas))); else { transaction.gas = "22000"; txArray.push(new AionLong(new BN(transaction.gas))); } if (transaction.gasPrice) { txArray.push(new AionLong(new BN(transaction.gasPrice))); } else { transaction.gasPrice = this.defaultNrgPrice.toString(); txArray.push(new AionLong(new BN(transaction.gasPrice))); } if (transaction.type !== 0) txArray.push(transaction.type); else { transaction.type = 1; txArray.push(transaction.type); } const rlpOutput = rlp.encode(txArray); return rlpOutput; } static getAddress(privateKey) { const privateKeyBuff = CryptoUtil.hex2ua(privateKey); const keyPair = nacl.sign.keyPair.fromSecretKey(privateKeyBuff); return [CryptoUtil.createA0Address(keyPair.publicKey), CryptoUtil.uia2hex(keyPair.publicKey)]; } } TransactionUtil.defaultNrgPrice = 10000000000; TransactionUtil.defaultNrgLimit = 22000;