Skip to content

Commit

Permalink
fix(LSK): estimate fee accordingly to the docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bludnic committed Dec 26, 2023
1 parent 0f0488d commit 028fa4a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 43 deletions.
21 changes: 4 additions & 17 deletions src/lib/__tests__/lisk/lisk-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @vitest-environment node
// Some crypto libs throw errors when using `jsdom` environment

import { LSK_MIN_REQUIRED_FEE } from '@/lib/lisk'
import { LSK_MIN_FEE_PER_BYTE } from '@/lib/lisk'
import { convertBeddowsToLSK } from '@liskhq/lisk-transactions'
import { describe, it, expect } from 'vitest'
import { Cryptos } from '@/lib/constants'
Expand All @@ -17,24 +17,11 @@ describe('lisk-utils', () => {
})

describe('estimateFee', () => {
const MIN_FEE = convertBeddowsToLSK(LSK_MIN_REQUIRED_FEE.toString())

it('should return default fee', () => {
expect(estimateFee()).toBe(MIN_FEE)
})

it('should meet minimum required fee', () => {
expect(
estimateFee({
amount: '0.01'
})
).toBe(MIN_FEE)
})

it('should calculate fee including `data`', () => {
const data = 'hello'
const messageFee = BigInt(data.length) * BigInt(1000)
const expectedFee = LSK_MIN_REQUIRED_FEE + messageFee
const minimalFee = BigInt(165000)
const messageFee = BigInt(data.length) * BigInt(LSK_MIN_FEE_PER_BYTE)
const expectedFee = minimalFee + messageFee

expect(estimateFee({ data })).toBe(convertBeddowsToLSK(expectedFee.toString()))
})
Expand Down
3 changes: 2 additions & 1 deletion src/lib/lisk/lisk-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const LiskHashSettings = {
export const LSK_CHAIN_ID = '00000000'
export const LSK_TOKEN_ID = '0000000000000000'
export const LSK_DECIMALS = CryptosInfo.LSK.decimals
export const LSK_MIN_REQUIRED_FEE = BigInt(CryptosInfo.LSK.defaultFee * 10 ** LSK_DECIMALS) // in beddows
export const LSK_DEFAULT_FEE = BigInt(CryptosInfo.LSK.defaultFee * 10 ** LSK_DECIMALS) // in beddows
export const LSK_MIN_FEE_PER_BYTE = BigInt(1000) // in beddows
export const LSK_TRANSFER_TO_NEW_ACCOUNT_FEE = BigInt(5000000) // additional fee when sending to new accounts (@see https://lisk.com/documentation/understand-blockchain/blocks-txs.html#command-fee)
export const LSK_TXS_PER_PAGE = 25 // transactions per page

Expand Down
41 changes: 16 additions & 25 deletions src/lib/lisk/lisk-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DecodedTransaction, Transaction } from './types/lisk'
import { codec } from '@liskhq/lisk-codec'
import * as cryptography from '@liskhq/lisk-cryptography'
import networks from '@/lib/lisk/networks'
import { computeMinFee, convertBeddowsToLSK, convertLSKToBeddows } from '@liskhq/lisk-transactions'
import { convertBeddowsToLSK } from '@liskhq/lisk-transactions'
import * as transactions from '@liskhq/lisk-transactions'
import { Buffer } from 'buffer'
import pbkdf2 from 'pbkdf2'
Expand All @@ -19,10 +19,10 @@ import {
LSK_TRANSFER_TO_NEW_ACCOUNT_FEE,
LSK_DECIMALS,
LSK_DEMO_ACCOUNT,
LSK_MIN_REQUIRED_FEE,
LSK_TOKEN_ID
LSK_TOKEN_ID,
LSK_MIN_FEE_PER_BYTE
} from './lisk-constants'
import { bytesToHex } from '@/lib/hex'
import { bytesToHex, hexToBytes } from '@/lib/hex'
import * as validator from '@liskhq/lisk-validator'

/**
Expand Down Expand Up @@ -227,6 +227,7 @@ type EstimateFeeParams = {

/**
* Estimate transaction fee by LSK amount.
* https://lisk.com/documentation/understand-blockchain/blocks-txs.html#transaction-fees
*
* @param params Transaction params
*/
Expand All @@ -240,30 +241,20 @@ export function estimateFee(params?: EstimateFeeParams) {
isNewAccount
} = params || {}

const unsignedTransaction = {
module: 'token',
command: 'transfer',
fee: BigInt(0),
nonce: BigInt(nonce),
senderPublicKey: Buffer.from(keyPair.publicKey, 'hex'),
params: {
tokenID: Buffer.from(LSK_TOKEN_ID, 'hex'),
amount: BigInt(convertLSKToBeddows(amount.toString())),
recipientAddress: cryptography.address.getAddressFromLisk32Address(recipientAddress),
data
const transaction = createTransaction(
{
publicKey: Buffer.from(keyPair.publicKey, 'hex'),
secretKey: Buffer.from(keyPair.secretKey, 'hex')
},
signatures: []
}

const signedTransaction = transactions.signTransaction(
unsignedTransaction,
Buffer.from(LSK_CHAIN_ID, 'hex'),
Buffer.from(keyPair.secretKey, 'hex'),
TRANSACTION_PARAMS_SCHEMA
recipientAddress,
amount,
1,
nonce,
data
)
const transactionBytes = hexToBytes(transaction.hex)

const minFee = computeMinFee(signedTransaction, TRANSACTION_PARAMS_SCHEMA)
const fee = minFee < LSK_MIN_REQUIRED_FEE ? LSK_MIN_REQUIRED_FEE : minFee
const fee = BigInt(transactionBytes.length) * LSK_MIN_FEE_PER_BYTE
const transferToNewAccountFee = isNewAccount ? LSK_TRANSFER_TO_NEW_ACCOUNT_FEE : BigInt(0)

const totalFee = fee + transferToNewAccountFee
Expand Down

0 comments on commit 028fa4a

Please sign in to comment.