diff --git a/cashtab/src/wallet/fixtures/vectors.js b/cashtab/src/wallet/fixtures/vectors.js new file mode 100644 --- /dev/null +++ b/cashtab/src/wallet/fixtures/vectors.js @@ -0,0 +1,55 @@ +export default { + getBalanceSatsVectors: { + expectedReturns: [ + { + description: 'Kind of a normal balance calculation', + nonSlpUtxos: [ + { value: '546' }, + { value: '150000000' }, + { value: '62500000' }, + ], + balanceSats: 212500546, + }, + { + description: 'Wallet balance of total XEC supply', + nonSlpUtxos: [ + { value: '700000000000000' }, + { value: '700000000000000' }, + { value: '700000000000000' }, + ], + balanceSats: 2100000000000000, + }, + { + description: 'Empty array returns 0 balance', + nonSlpUtxos: [], + balanceSats: 0, + }, + { + description: + 'Array containing valid and invalid chronik utxos returns NaN', + nonSlpUtxos: [ + { noValueKey: '546' }, + { value: { thisKeyIsNotAString: 500 } }, + { value: '62500000' }, + ], + balanceSats: NaN, + }, + { + description: + 'Array containing invalid chronik utxos returns NaN', + nonSlpUtxos: [ + { noValueKey: '546' }, + { value: { thisKeyIsNotAString: 500 } }, + ], + balanceSats: NaN, + }, + ], + expectedErrors: [ + { + description: 'Call with non-Array', + nonSlpUtxos: { somekey: 'an object instead of an array' }, + errorMsg: 'nonSlpUtxos.reduce is not a function', + }, + ], + }, +}; diff --git a/cashtab/src/wallet/index.js b/cashtab/src/wallet/index.js new file mode 100644 --- /dev/null +++ b/cashtab/src/wallet/index.js @@ -0,0 +1,16 @@ +/** + * Get total value of satoshis associated with an array of chronik utxos + * @param {array} nonSlpUtxos array of chronik utxos + * (each is an object with an integer as a string + * stored at 'value' key representing associated satoshis) + * e.g. {value: '12345'} + * @throws {error} if nonSlpUtxos does not have a .reduce method + * @returns {number | NaN} integer, total balance of input utxos in satoshis + * or NaN if any utxo is invalid + */ +export const getBalanceSats = nonSlpUtxos => { + return nonSlpUtxos.reduce( + (previousBalance, utxo) => previousBalance + parseInt(utxo.value), + 0, + ); +}; diff --git a/cashtab/src/wallet/index.test.js b/cashtab/src/wallet/index.test.js new file mode 100644 --- /dev/null +++ b/cashtab/src/wallet/index.test.js @@ -0,0 +1,18 @@ +import { getBalanceSats } from 'wallet'; +import vectors from './fixtures/vectors'; + +describe('Calculates total balance in satoshis from a valid set of chronik utxos', () => { + const { expectedReturns, expectedErrors } = vectors.getBalanceSatsVectors; + expectedReturns.forEach(expectedReturn => { + const { description, nonSlpUtxos, balanceSats } = expectedReturn; + it(`getBalanceSats: ${description}`, () => { + expect(getBalanceSats(nonSlpUtxos)).toBe(balanceSats); + }); + }); + expectedErrors.forEach(expectedError => { + const { description, nonSlpUtxos, errorMsg } = expectedError; + it(`getBalanceSats throws error for: ${description}`, () => { + expect(() => getBalanceSats(nonSlpUtxos)).toThrow(errorMsg); + }); + }); +});