/
mustreets
/
CreateTransactions
Обзор
Документация
Войти
/
mustreets
/
CreateTransactions
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
libJS/wallet/class.CreateTransaction.ts
152 строки
5 KB
Slava
Initialize project with essential configurations and structures
14 май 2026, 22:23
14 май 2026, 22:23
a89cd26
Код
Авторство
О чём код?
import BigNumber from "bignumber.js"; import i18n from "i18next"; import stringify from "json-stable-stringify"; import * as crypto from "react-native-crypto-js"; import { v4 as uuidv4 } from "uuid"; import { type Reporter, reporter as defaultReporter } from "../services/Reporting"; import { TransactionCoordinator } from "./class.TransactionCoordinator"; import { ICipherTransaction, IKeyProvider, ITransactionSnapshot, IValueTransfer, Wallet, } from "./types"; const ERROR_MESSAGE = { ErrorEmptyChainId: "wallet:errors.errorEmptyChainId", ErrorNotEnoughBalance: "wallet:errors.errorNotEnoughBalance", ErrorSameAddress: "wallet:errors.errorSameAddress", ErrorTransactionExpired: "wallet:errors.errorTransactionExpired", ErrorValue: "wallet:errors.errorValue", ErrorZeroValue: "wallet:errors.errorZeroValue", }; export class CreateTransaction { protected readonly wallet: Wallet; protected readonly value: IValueTransfer; protected readonly sendTransaction: (value: ICipherTransaction) => void; protected readonly provider: IKeyProvider; private readonly coordinator: TransactionCoordinator; private readonly reporter: Reporter; constructor({ wallet, value, sendTransaction, provider, reporter: reporterInstance = defaultReporter, }: { wallet: Wallet; sendTransaction: (value: ICipherTransaction) => void; value: IValueTransfer; provider: IKeyProvider; reporter?: Reporter; }) { this.wallet = wallet; this.value = value; this.sendTransaction = sendTransaction; this.provider = provider; this.reporter = reporterInstance; this.coordinator = new TransactionCoordinator(provider); } public getNonce(): number { return Date.now(); } public hash(value: string): string { const sha256 = crypto.HmacSHA256(value, "secret"); return sha256.toString(); } private async prepareValidatedSnapshot(): Promise<ITransactionSnapshot> { this.reporter.log("Preparation started"); await this.coordinator.validateFull(this.value); const snapshot = this.createSnapshot(); if (Date.now() > snapshot.expiresAt) { throw new Error(i18n.t(ERROR_MESSAGE.ErrorTransactionExpired)); } return snapshot; } public createSnapshot(): ITransactionSnapshot { const id = uuidv4(); const timestamp = Date.now(); const payloadHash = this.hash( (stringify(this.value) ?? "") + String(timestamp) + this.value.addressFrom ); const expiresAt = timestamp + 1000 * 60 * 5; if (new BigNumber(this.value.value).lt(0)) { throw new Error(i18n.t(ERROR_MESSAGE.ErrorValue)); } if (new BigNumber(this.value.value).eq(0)) { throw new Error(i18n.t(ERROR_MESSAGE.ErrorZeroValue)); } if (this.value.addressFrom === this.value.addressTo) { throw new Error(i18n.t(ERROR_MESSAGE.ErrorSameAddress)); } if (this.value.chainId === "") { throw new Error(i18n.t(ERROR_MESSAGE.ErrorEmptyChainId)); } return Object.freeze({ expiresAt: expiresAt, payloadHash: payloadHash, timestamp, transaction_id: id, value: this.value, wallet: this.wallet, }); } public async verifyTransaction() { const snapshot = await this.prepareValidatedSnapshot(); const sk = await this.provider.getPrivateKey(); const pk = await this.provider.getPublicKey(); const cipherTransaction = await this.cipherTransaction(snapshot, snapshot.timestamp, sk); this.reporter.track("transaction_verify_complete", { wallet: this.wallet, }); return { cipherTransaction, expiresAt: snapshot.expiresAt, payloadHash: snapshot.payloadHash, pk, timestamp: snapshot.timestamp, transaction_id: snapshot.transaction_id, value: snapshot.value, wallet: this.wallet, }; } public async signTransaction(): Promise<void> { const snapshot = await this.prepareValidatedSnapshot(); const privateKey = await this.provider.getPrivateKey(); const cipherTransaction = await this.cipherTransaction(snapshot, snapshot.timestamp, privateKey); this.sendTransaction(cipherTransaction); this.reporter.track("transaction_signed", { wallet: this.wallet }); } protected async cipherTransaction( snapshot: ITransactionSnapshot, nonce: number, sk: string ): Promise<ICipherTransaction> { const pk = await this.provider.getPublicKey(); return { body: { value: snapshot.value }, expiresAt: snapshot.expiresAt, header: { nonce, timestamp: snapshot.timestamp }, id: snapshot.transaction_id, payloadHash: snapshot.payloadHash, publicKey: pk, signature: `signed_with_${sk.substring(0, 5)}`, }; } }