Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solution: new create tx logic and components #1341

Merged
merged 2 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .vscode/emerald-wallet.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"extensions": {
"recommendations": [
"christian-kohler.npm-intellisense",
"dbaeumer.vscode-eslint",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"orta.vscode-jest",
"rust-lang.rust-analyzer",
"serayuzgur.crates",
"tamasfe.even-better-toml",
"visualstudioexptteam.vscodeintellicode"
]
},
"folders": [
{
"name": "emerald-wallet",
"path": ".."
},
{
"name": "@emeraldwallet/core",
"path": "../packages/core"
},
{
"name": "@emeraldwallet/desktop",
"path": "../packages/desktop"
},
{
"name": "@emeraldwallet/electron-app",
"path": "../packages/electron-app"
},
{
"name": "@emeraldwallet/persistent-state",
"path": "../packages/persistent-state"
},
{
"name": "@emeraldwallet/persistent-state/native",
"path": "../packages/persistent-state/native"
},
{
"name": "@emeraldwallet/react-app",
"path": "../packages/react-app"
},
{
"name": "@emeraldwallet/services",
"path": "../packages/services"
},
{
"name": "@emeraldwallet/store",
"path": "../packages/store"
},
{
"name": "@emeraldwallet/ui",
"path": "../packages/ui"
}
],
"settings": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"jest.disabledWorkspaceFolders": [
"emerald-wallet",
"@emeraldwallet/electron-app",
"@emeraldwallet/persistent-state/native"
],
"npm.packageManager": "yarn",
"search.exclude": {
"**/.emerald-dev": true,
"**/.tests": true,
"**/app": true,
"**/lib": true,
"**/node_modules": true,
"**/target": true,
"*.tsbuildinfo": true,
"yarn.lock": true
},
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}
}
12 changes: 0 additions & 12 deletions .vscode/extensions.json

This file was deleted.

11 changes: 0 additions & 11 deletions .vscode/settings.json

This file was deleted.

4 changes: 4 additions & 0 deletions packages/core/src/blockchains/blockchains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ export function isBitcoin(code: BlockchainCode): boolean {

export const WEIS_GOERLI = new Units([
new Unit(0, 'Goerli Wei', 'WeiG'),
new Unit(3, 'Goerli Kwei', 'KWeiG'),
new Unit(6, 'Goerli Mwei', 'MWeiG'),
new Unit(9, 'Goerli Gwei', 'GWeiG'),
new Unit(12, 'Goerli Microether', 'μETG'),
new Unit(15, 'Goerli Milliether', 'mETG'),
new Unit(18, 'Goerli Ether', 'ETG'),
]);

Expand Down
22 changes: 4 additions & 18 deletions packages/core/src/convert.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import BigNumber from 'bignumber.js';
import * as convert from './convert';

const {
toNumber, toHex, toBigNumber, quantitiesToHex,
} = convert;
const { toNumber, toHex, toBigNumber } = convert;

test('toNumber should convert hex string to number', () => {
expect(toNumber('0x01')).toBe(1);
Expand All @@ -20,37 +18,25 @@ test('toNumber should convert number to number', () => {
});

test('toNumber should accept empty', () => {
// @ts-ignore
expect(toNumber(null)).toBe(0);
// @ts-ignore
expect(toNumber(undefined)).toBe(0);

// @ts-ignore
expect(toNumber(null, -1)).toBe(-1);
// @ts-ignore
expect(toNumber(undefined, 10)).toBe(10);
});

describe('quantitiesToHex', () => {
it('converts without leading zeros', () => {
expect(quantitiesToHex(1024)).toEqual('0x400');
expect(quantitiesToHex(0)).toEqual('0x0');
});
});

describe('toHex', () => {
it('convert decimal number to hex', () => {
expect(toHex(10000000000)).toEqual('0x02540be400');
expect(toHex(10000000000)).toEqual('0x2540be400');
expect(toHex('21000')).toEqual('0x5208');
expect(toHex('100000000000000000000')).toEqual('0x056bc75e2d63100000');
expect(toHex('100000000000000000000')).toEqual('0x56bc75e2d63100000');
});

it('convert BigNumber to hex', () => {
expect(toHex(new BigNumber(21000))).toEqual('0x5208');
});

it('convert hex to hex', () => {
expect(toHex('0x01')).toEqual('0x01');
expect(toHex('0x1')).toEqual('0x1');
});
});

Expand Down
51 changes: 30 additions & 21 deletions packages/core/src/convert.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import BigNumber from 'bignumber.js';

type Numeric = number | string | null | undefined;

/**
* Convert hex string to number
*
* @param value
* @param defaultValue
* @returns {number}
* Convert hex to number
*/
export function toNumber(value: string | number, defaultValue = 0): number {
if (!value) {
export function toNumber(hex: Numeric, defaultValue = 0): number {
if (hex == null) {
return defaultValue;
}

if (typeof value === 'number') {
return value;
if (typeof hex === 'number') {
return hex;
}

if (value === '0x') {
if (hex === '0x') {
return 0;
}

return parseInt(value.substring(2), 16);
return parseInt(hex, 16);
}

/**
* Converts number, string or hex string into BigNumber
*/
export function toBigNumber(value: BigNumber | number | string): BigNumber {
export function toBigNumber(value: BigNumber | Numeric, defaultValue = new BigNumber(0)): BigNumber {
if (value == null) {
return defaultValue;
}

if (value instanceof BigNumber) {
return value;
}
Expand All @@ -36,20 +38,27 @@ export function toBigNumber(value: BigNumber | number | string): BigNumber {
return new BigNumber(0);
}

if (value.substring(0, 2) === '0x') {
return new BigNumber(value.substring(2), 16);
}
return new BigNumber(value, 16);
}

return new BigNumber(value, 10);
}

export function toHex(val: number | string | BigNumber): string {
const hex = new BigNumber(val).toString(16);
/**
* Converts number, string or BigNumber into hex string
*/
export function toHex(value: BigNumber | Numeric, defaultValue = '0x'): string {
if (value == null) {
return defaultValue;
}

return `0x${hex.length % 2 !== 0 ? `0${hex}` : hex}`;
}
let hex: string;

if (BigNumber.isBigNumber(value)) {
hex = value.toString(16);
} else {
hex = new BigNumber(value).toString(16);
}

export function quantitiesToHex(val: number | string): string {
return `0x${new BigNumber(val).toString(16)}`;
return `0x${hex}`;
}
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ export {
formatFiatAmountPartial,
} from './format';
export { getStandardUnits } from './asset';
export { quantitiesToHex, toBigNumber, toHex, toNumber } from './convert';
export { toBigNumber, toHex, toNumber } from './convert';
14 changes: 7 additions & 7 deletions packages/core/src/transaction/ethereum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import BigNumber from 'bignumber.js';
import { BigAmount } from '@emeraldpay/bigamount';
import { BlockchainCode } from '../blockchains';

export const DEFAULT_GAS_LIMIT = 21000 as const;
Expand Down Expand Up @@ -46,16 +46,16 @@ export interface EthereumTransaction {
blockchain: BlockchainCode;
blockNumber?: number;
from: string;
gas: number | string;
gasPrice?: string | BigNumber;
maxGasPrice?: string | BigNumber;
priorityGasPrice?: string | BigNumber;
gas: number;
gasPrice?: BigAmount;
maxGasPrice?: BigAmount;
priorityGasPrice?: BigAmount;
hash?: string;
data?: string;
nonce?: number | string;
nonce?: number;
to?: string;
type: EthereumTransactionType;
value: string | BigNumber;
value: BigAmount;
}

export interface EthereumRawReceipt {
Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/workflow/create-tx/CreateBitcoinTx.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigAmount, CreateAmount, Units } from '@emeraldpay/bigamount';
import { BigAmount, CreateAmount } from '@emeraldpay/bigamount';
import { BitcoinEntry, EntryId, UnsignedBitcoinTx } from '@emeraldpay/emerald-vault-core';
import { BlockchainCode, InputUtxo, amountDecoder, amountFactory, blockchainIdToCode } from '../../blockchains';
import { TxTarget, ValidationResult } from './types';
Expand Down Expand Up @@ -92,7 +92,6 @@ export class CreateBitcoinTx implements BitcoinTx {

private readonly amountDecoder: (value: string) => BigAmount;
private readonly amountFactory: CreateAmount<BigAmount>;
private readonly amountUnits: Units;
private readonly blockchain: BlockchainCode;
private readonly utxo: InputUtxo[];
private readonly zero: BigAmount;
Expand All @@ -110,7 +109,6 @@ export class CreateBitcoinTx implements BitcoinTx {
this.amountFactory = amountFactory(this.blockchain);

this.zero = this.amountFactory(0);
this.amountUnits = this.zero.units;

this.vkbPrice = this.amountFactory(DEFAULT_VKB_FEE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,6 @@ describe('CreateErc20ApproveTx', () => {
type: EthereumTransactionType.EIP1559,
});

expect(tx.build().data.length).toBeGreaterThan(2);
expect(tx.build().data?.length).toBeGreaterThan(2);
});
});
38 changes: 13 additions & 25 deletions packages/core/src/workflow/create-tx/CreateErc20ApproveTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,9 @@ export class CreateErc20ApproveTx implements Erc20ApproveTxDetails {

this.zeroAmount = amountFactory(details.blockchain)(0);

if (this.type === EthereumTransactionType.EIP1559) {
this.maxGasPrice = details.maxGasPrice ?? this.zeroAmount;
this.priorityGasPrice = details.priorityGasPrice ?? this.zeroAmount;
} else {
this.gasPrice = details.gasPrice ?? this.zeroAmount;
}
this.gasPrice = details.gasPrice ?? this.zeroAmount;
this.maxGasPrice = details.maxGasPrice ?? this.zeroAmount;
this.priorityGasPrice = details.priorityGasPrice ?? this.zeroAmount;
}

static fromPlain(details: Erc20ApproveTxDetails): CreateErc20ApproveTx {
Expand Down Expand Up @@ -126,34 +123,24 @@ export class CreateErc20ApproveTx implements Erc20ApproveTxDetails {
}

build(): EthereumTransaction {
const {
amount,
blockchain,
gas,
gasPrice,
maxGasPrice,
priorityGasPrice,
type,
allowFor = '',
approveBy = '',
} = this;
const { blockchain, gas, gasPrice, maxGasPrice, priorityGasPrice, type, allowFor = '', approveBy = '' } = this;

const data = this.tokenContract.functionToData('approve', {
_spender: allowFor,
_amount: amount.number.toFixed(),
_amount: this.amount.number.toFixed(),
});

return {
blockchain,
gas,
data,
gas,
gasPrice,
maxGasPrice,
priorityGasPrice,
type,
from: approveBy,
gasPrice: gasPrice?.number,
maxGasPrice: maxGasPrice?.number,
priorityGasPrice: priorityGasPrice?.number,
to: this._token.address,
value: this.zeroAmount.number,
to: this.token.address,
value: this.zeroAmount,
};
}

Expand All @@ -176,7 +163,8 @@ export class CreateErc20ApproveTx implements Erc20ApproveTxDetails {
}

getFees(): BigAmount {
const gasPrice = this.maxGasPrice ?? this.gasPrice ?? this.zeroAmount;
const gasPrice =
(this.type === EthereumTransactionType.EIP1559 ? this.maxGasPrice : this.gasPrice) ?? this.zeroAmount;

return gasPrice.multiply(this.gas);
}
Expand Down
Loading