diff --git a/src/__integrationtests__/utils.ts b/src/__integrationtests__/utils.ts
index 70146e565..ca898778b 100644
--- a/src/__integrationtests__/utils.ts
+++ b/src/__integrationtests__/utils.ts
@@ -9,9 +9,6 @@ import CType from '../ctype/CType'
import { getOwner } from '../ctype/CType.chain'
import Identity from '../identity/Identity'
-// FIXME: check with weights
-// export const GAS = new BN(1_000_000)
-export const GAS = new BN(125_000_000)
export const MIN_TRANSACTION = new BN(100_000_000)
export const ENDOWMENT = MIN_TRANSACTION.mul(new BN(100))
diff --git a/src/balance/Balance.chain.ts b/src/balance/Balance.chain.ts
index ba5ca72e5..d426d4e5f 100644
--- a/src/balance/Balance.chain.ts
+++ b/src/balance/Balance.chain.ts
@@ -15,6 +15,7 @@ import BN from 'bn.js'
import { getCached } from '../blockchainApiConnection'
import Identity from '../identity/Identity'
import IPublicIdentity from '../types/PublicIdentity'
+import BalanceUtils from './Balance.utils'
/**
* Fetches the current balance of the account with [accountAddress].
@@ -89,11 +90,12 @@ export async function listenToBalanceChanges(
/**
* Transfer Kilt [amount] tokens to [toAccountAddress] using the given [[Identity]].
- * Note that balance amount is in Femto-Kilt (1e-15) and must be translated to Kilt-Coin.
+ * Note that the value of the transferred currency and the balance amount reported by the chain is in Femto-Kilt (1e-15), and must be translated to Kilt-Coin.
*
* @param identity Identity to use for token transfer.
* @param accountAddressTo Address of the receiver account.
- * @param amount Amount of Femto-Kilt (1e-15) to transfer.
+ * @param amount Amount of Units to transfer.
+ * @param exponent Magnitude of the amount. Default magnitude of Femto-Kilt.
* @returns Promise containing the transaction status.
*
* @example
@@ -117,9 +119,17 @@ export async function listenToBalanceChanges(
export async function makeTransfer(
identity: Identity,
accountAddressTo: IPublicIdentity['address'],
- amount: BN
+ amount: BN,
+ exponent = -15
): Promise {
const blockchain = await getCached()
- const transfer = blockchain.api.tx.balances.transfer(accountAddressTo, amount)
+ const cleanExponent =
+ (exponent >= 0 ? 1 : -1) * Math.floor(Math.abs(exponent))
+ const transfer = blockchain.api.tx.balances.transfer(
+ accountAddressTo,
+ cleanExponent === -15
+ ? amount
+ : BalanceUtils.convertToTxUnit(amount, cleanExponent)
+ )
return blockchain.submitTx(identity, transfer)
}
diff --git a/src/balance/Balance.spec.ts b/src/balance/Balance.spec.ts
index 299724069..4ed7137b7 100644
--- a/src/balance/Balance.spec.ts
+++ b/src/balance/Balance.spec.ts
@@ -9,6 +9,7 @@ import {
makeTransfer,
} from './Balance.chain'
import TYPE_REGISTRY from '../blockchainApiConnection/__mocks__/BlockchainQuery'
+import BalanceUtils from './Balance.utils'
jest.mock('../blockchainApiConnection/BlockchainApiConnection')
@@ -16,6 +17,8 @@ const BALANCE = 42
const FEE = 30
describe('Balance', () => {
+ let alice: Identity
+ let bob: Identity
const blockchainApi = require('../blockchainApiConnection/BlockchainApiConnection')
.__mocked_api
@@ -41,9 +44,11 @@ describe('Balance', () => {
return accountInfo(BALANCE - FEE)
}
)
-
+ beforeAll(async () => {
+ alice = await Identity.buildFromURI('//Alice')
+ bob = await Identity.buildFromURI('//Bob')
+ })
it('should listen to balance changes', async (done) => {
- const bob = await Identity.buildFromURI('//Bob')
const listener = (account: string, balance: BN, change: BN): void => {
expect(account).toBe(bob.address)
expect(balance.toNumber()).toBe(BALANCE)
@@ -58,11 +63,23 @@ describe('Balance', () => {
})
it('should make transfer', async () => {
- const alice = await Identity.buildFromURI('//Alice')
- const bob = await Identity.buildFromURI('//Bob')
-
const status = await makeTransfer(alice, bob.address, new BN(100))
expect(status).toBeInstanceOf(SubmittableResult)
expect(status.isFinalized).toBeTruthy()
})
+ it('should make transfer of amount with arbitrary exponent', async () => {
+ const amount = new BN(10)
+ const exponent = -6
+ const expectedAmount = BalanceUtils.convertToTxUnit(
+ amount,
+ (exponent >= 0 ? 1 : -1) * Math.floor(Math.abs(exponent))
+ )
+ const status = await makeTransfer(alice, bob.address, amount, exponent)
+ expect(blockchainApi.tx.balances.transfer).toHaveBeenCalledWith(
+ bob.address,
+ expectedAmount
+ )
+ expect(status).toBeInstanceOf(SubmittableResult)
+ expect(status.isFinalized).toBeTruthy()
+ })
})
diff --git a/src/balance/Balance.utils.spec.ts b/src/balance/Balance.utils.spec.ts
new file mode 100644
index 000000000..ccaf803b4
--- /dev/null
+++ b/src/balance/Balance.utils.spec.ts
@@ -0,0 +1,95 @@
+import BN from 'bn.js'
+import {
+ formatKiltBalance,
+ convertToTxUnit,
+ asFemtoKilt,
+ TRANSACTION_FEE,
+} from './Balance.utils'
+
+describe('formatKiltBalance', () => {
+ const TESTVALUE = new BN('123456789000')
+ const baseValue = new BN('1')
+ it('formats the given balance', async () => {
+ expect(formatKiltBalance(TESTVALUE)).toEqual('123.456 micro KILT')
+ expect(formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(3))))).toEqual(
+ '1.000 pico KILT'
+ )
+ expect(formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(6))))).toEqual(
+ '1.000 nano KILT'
+ )
+ expect(formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(9))))).toEqual(
+ '1.000 micro KILT'
+ )
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(12))))
+ ).toEqual('1.000 milli KILT')
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(15))))
+ ).toEqual('1.000 KILT')
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(18))))
+ ).toEqual('1.000 Kilo KILT')
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(21))))
+ ).toEqual('1.000 Mega KILT')
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(24))))
+ ).toEqual('1.000 Giga KILT')
+ expect(
+ formatKiltBalance(baseValue.mul(new BN(10).pow(new BN(27))))
+ ).toEqual('1.000 Tera KILT')
+ })
+})
+describe('convertToTxUnit', () => {
+ it('converts given value with given power to femto KILT', () => {
+ expect(new BN(convertToTxUnit(new BN(1), -15).toString())).toEqual(
+ new BN(1)
+ )
+ expect(new BN(convertToTxUnit(new BN(1), -12).toString())).toEqual(
+ new BN('1000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), -9).toString())).toEqual(
+ new BN('1000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), -6).toString())).toEqual(
+ new BN('1000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), -3).toString())).toEqual(
+ new BN('1000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 0).toString())).toEqual(
+ new BN('1000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 3).toString())).toEqual(
+ new BN('1000000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 6).toString())).toEqual(
+ new BN('1000000000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 9).toString())).toEqual(
+ new BN('1000000000000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 12).toString())).toEqual(
+ new BN('1000000000000000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 15).toString())).toEqual(
+ new BN('1000000000000000000000000000000')
+ )
+ expect(new BN(convertToTxUnit(new BN(1), 18).toString())).toEqual(
+ new BN('1000000000000000000000000000000000')
+ )
+ })
+})
+describe('asFemtoKilt', () => {
+ it('converts whole KILT to femtoKilt using convertToTxUnit', () => {
+ expect(new BN(asFemtoKilt(new BN(1000)).toString())).toEqual(
+ new BN('1000000000000000000')
+ )
+ })
+})
+
+describe('TRANSACTION_FEE', () => {
+ it('equals 125 nano KILT', () => {
+ expect(formatKiltBalance(TRANSACTION_FEE)).toEqual('125.000 nano KILT')
+ })
+})
diff --git a/src/balance/Balance.utils.ts b/src/balance/Balance.utils.ts
new file mode 100644
index 000000000..5a0c1a750
--- /dev/null
+++ b/src/balance/Balance.utils.ts
@@ -0,0 +1,36 @@
+/**
+ * @packageDocumentation
+ * @module BalanceUtils
+ * @preferred
+ */
+
+import BN from 'bn.js'
+import { formatBalance } from '@polkadot/util'
+
+export const KILT_COIN = new BN(1)
+
+export function formatKiltBalance(amount: BN): string {
+ return formatBalance(amount, {
+ decimals: 15,
+ withSiFull: true,
+ withUnit: 'KILT',
+ })
+}
+
+export function convertToTxUnit(balance: BN, power: number): BN {
+ return new BN(balance).mul(new BN(10).pow(new BN(15 + power)))
+}
+
+export function asFemtoKilt(balance: BN): BN {
+ return convertToTxUnit(balance, 0)
+}
+
+export const TRANSACTION_FEE = convertToTxUnit(new BN(125), -9)
+
+export default {
+ KILT_COIN,
+ TRANSACTION_FEE,
+ formatKiltBalance,
+ asFemtoKilt,
+ convertToTxUnit,
+}
diff --git a/src/balance/index.ts b/src/balance/index.ts
index 518794606..19e00bd4d 100644
--- a/src/balance/index.ts
+++ b/src/balance/index.ts
@@ -3,4 +3,8 @@
* @ignore
*/
-export * from './Balance.chain'
+import BalanceUtils from './Balance.utils'
+import * as Balance from './Balance.chain'
+
+export { Balance, BalanceUtils }
+export default Balance
diff --git a/src/index.ts b/src/index.ts
index c147d30e8..936b6d336 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,7 +6,7 @@ import { Accumulator, CombinedPresentation } from '@kiltprotocol/portablegabi'
import { Attester, Claimer, Verifier } from './actor'
import Attestation, { AttestationUtils } from './attestation'
import AttestedClaim, { AttestedClaimUtils } from './attestedclaim'
-import * as Balance from './balance'
+import { Balance, BalanceUtils } from './balance'
import Blockchain, { IBlockchainApi } from './blockchain'
import * as BlockchainApiConnection from './blockchainApiConnection'
import Claim, { ClaimUtils } from './claim'
@@ -66,6 +66,7 @@ export {
IBlockchainApi,
BlockchainApiConnection,
Balance,
+ BalanceUtils,
Crypto,
Identity,
AttesterIdentity,