Skip to content

Commit

Permalink
Merge pull request #784 from hubiinetwork/feature/1.2.5
Browse files Browse the repository at this point in the history
1.2.5
  • Loading branch information
katat committed Sep 19, 2019
2 parents 56c8b74 + 63779da commit 7634814
Show file tree
Hide file tree
Showing 16 changed files with 2,827 additions and 176 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hubii-core",
"version": "1.2.4",
"version": "1.2.5",
"author": {
"name": "hubii",
"email": "info@hubii.com",
Expand Down Expand Up @@ -318,7 +318,7 @@
"minimist": "1.2.0",
"moment": "2.22.2",
"nahmii-ethereum-address": "^2.0.1",
"nahmii-sdk": "3.0.6",
"nahmii-sdk": "3.1.2",
"prop-types": "15.6.1",
"qrcode.react": "0.8.0",
"react": "16.6.3",
Expand Down
10 changes: 4 additions & 6 deletions src/containers/HubiiApiHoc/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,10 @@ const makeSelectTransactionsWithInfo = () => createSelector(
(transactions, supportedAssets) => {
// set all address's transactions to loading if don't have all required information
let transactionsWithInfo = transactions;
if
(
supportedAssets.get('loading') ||
supportedAssets.get('error')
) {
transactionsWithInfo = transactionsWithInfo.map((address) => address.set('loading', true));
if (!supportedAssets.get('assets')) {
transactionsWithInfo = transactionsWithInfo.map(
(address) => address.set('loading', true).set('transactions', fromJS([]))
);
return transactionsWithInfo;
}

Expand Down
6 changes: 6 additions & 0 deletions src/containers/HubiiApiHoc/tests/mocks/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ export const supportedAssetsErrorMock = fromJS({
assets: [],
});

export const supportedAssetsNullMock = fromJS({
loading: false,
error: true,
assets: null,
});


// selectHubiiApiHocDomain
export const hubiiApiHocMock = fromJS({
Expand Down
16 changes: 4 additions & 12 deletions src/containers/HubiiApiHoc/tests/selectors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
transactionsWithInfoMock,
balancesMock,
supportedAssetsLoadedMock,
supportedAssetsLoadingMock,
supportedAssetsErrorMock,
supportedAssetsNullMock,
pricesLoadedMock,
} from './mocks/selectors';

Expand Down Expand Up @@ -106,17 +105,10 @@ describe('makeSelectTransactionsWithInfo', () => {
expect(transactionsWithInfoSelector(storeMock)).toEqual(expected);
});

it('should mark add tx as loading when supportedAssets loading', () => {
it('should mark add tx as loading when supportedAssets has null assets property', () => {
const mockedState = storeMock
.setIn(['hubiiApiHoc', 'supportedAssets'], supportedAssetsLoadingMock);
const expected = transactionsMock.map((a) => a.set('loading', true));
expect(transactionsWithInfoSelector(mockedState)).toEqual(expected);
});

it('should mark add tx as loading when supportedAssets errored', () => {
const mockedState = storeMock
.setIn(['hubiiApiHoc', 'supportedAssets'], supportedAssetsErrorMock);
const expected = transactionsMock.map((a) => a.set('loading', true));
.setIn(['hubiiApiHoc', 'supportedAssets'], supportedAssetsNullMock);
const expected = transactionsMock.map((a) => a.set('loading', true).set('transactions', fromJS([])));
expect(transactionsWithInfoSelector(mockedState)).toEqual(expected);
});
});
13 changes: 13 additions & 0 deletions src/containers/NahmiiHoc/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
LOAD_NAHMII_RECEIPTS_ERROR,
SETTLE_ALL_CHALLENGES_SUCCESS,
RELOAD_SETTLEMENT_STATES,
NEW_RECEIPT_RECEIVED,
} from './constants';

export function setSelectedWalletCurrency(currencyAddress) {
Expand Down Expand Up @@ -435,6 +436,18 @@ export function loadReceiptsError(address, error) {
};
}

export function newReceiptReceived(address, receipt) {
return {
type: NEW_RECEIPT_RECEIVED,
address,
receipt: {
...receipt,
created: new Date().toISOString(),
updated: new Date().toISOString(),
},
};
}

export function reloadSettlementStates(address, currency) {
return {
type: RELOAD_SETTLEMENT_STATES,
Expand Down
2 changes: 2 additions & 0 deletions src/containers/NahmiiHoc/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ export const LOAD_RECEIPTS_ERROR = 'src/WalletHOC/NAHMII/LOAD_RECEIPTS_ERROR';
export const LOAD_NAHMII_RECEIPTS = 'src/WalletHOC/NAHMII/LOAD_NAHMII_RECEIPTS';
export const LOAD_NAHMII_RECEIPTS_SUCCESS = 'src/WalletHOC/NAHMII/LOAD_NAHMII_RECEIPTS_SUCCESS';
export const LOAD_NAHMII_RECEIPTS_ERROR = 'src/WalletHOC/NAHMII/LOAD_NAHMII_RECEIPTS_ERROR';

export const NEW_RECEIPT_RECEIVED = 'src/WalletHOC/NAHMII/NEW_RECEIPT_RECEIVED';
9 changes: 8 additions & 1 deletion src/containers/NahmiiHoc/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
LOAD_SETTLEABLE_CHALLENGES_SUCCESS,
LOAD_SETTLEABLE_CHALLENGES_ERROR,
RELOAD_SETTLEMENT_STATES,
NEW_RECEIPT_RECEIVED,
} from './constants';

export const initialState = fromJS({
Expand Down Expand Up @@ -210,7 +211,13 @@ function nahmiiHocReducer(state = initialState, action) {
return state
.setIn(['receipts', action.address, 'loading'], false)
.setIn(['receipts', action.address, 'error'], action.error)
.setIn(['receipts', action.address, 'receipts'], fromJS([]));
.setIn(['receipts', action.address, 'receipts'], state.getIn(['receipts', action.address, 'receipts']) || fromJS([]));
case NEW_RECEIPT_RECEIVED:
return state
.setIn(['receipts', action.address, 'receipts'],
state.getIn(['receipts', action.address, 'receipts']) ?
state.getIn(['receipts', action.address, 'receipts']).unshift(fromJS(action.receipt)) :
fromJS([action.receipt]));
case CHANGE_NETWORK:
return state
.set('balances', initialState.get('balances'))
Expand Down
67 changes: 55 additions & 12 deletions src/containers/NahmiiHoc/saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import BalanceTrackerContract from 'nahmii-sdk/lib/wallet/balance-tracker-contra
import DriipSettlementChallengeContract from 'nahmii-sdk/lib/settlement/driip-settlement-challenge-contract';
import { utils } from 'ethers';
import { all, fork, takeEvery, takeLatest, select, put, call, take, cancel, race } from 'redux-saga/effects';
import { delay } from 'redux-saga';
import { delay, eventChannel } from 'redux-saga';
import BigNumber from 'bignumber.js';
import { requestHardwareWalletAPI } from 'utils/request';
import rpcRequest from 'utils/rpcRequest';
Expand Down Expand Up @@ -707,20 +707,59 @@ export function* loadSettleableChallenges({ address, currency }, network, noPoll
}
}

export function* loadWalletReceipts({ address }, network) {
while (true) { // eslint-disable-line no-constant-condition
try {
const receipts = yield call(network.nahmiiProvider.getWalletReceipts.bind(network.nahmiiProvider), address, null, 1000);
yield put(actions.loadReceiptsSuccess(address, receipts));
} catch (e) {
yield put(actions.loadReceiptsError(address, e));
} finally {
const FIVE_SEC_IN_MS = 1000 * 5;
yield delay(FIVE_SEC_IN_MS);
export const receiptEventChannel = (nahmiiEventProvider) => eventChannel((emit) => {
nahmiiEventProvider.onNewReceipt((receipt) => {
emit(receipt);
});
return () => {
nahmiiEventProvider.dispose();
};
});

export function* listenReceiptEvent() {
const network = yield select(makeSelectCurrentNetwork());
const nahmiiEventProvider = yield nahmii.NahmiiEventProvider.from(network.nahmiiProvider);
const channel = yield call(receiptEventChannel, nahmiiEventProvider);
while (true) {
const [receipt, changedNetwork] = yield race([
take(channel),
take(CHANGE_NETWORK),
]);

if (changedNetwork) {
channel.close();
return;
}

const wallets = yield select(makeSelectWallets());
for (const wallet of wallets) {
if (
isAddressMatch(receipt.sender, wallet.get('address')) ||
isAddressMatch(receipt.recipient, wallet.get('address'))
) {
yield put(actions.newReceiptReceived(wallet.get('address'), receipt.toJSON()));
}
}
}
}

export function* loadWalletReceipts({ address }, network) {
try {
const receipts = yield call(network.nahmiiProvider.getWalletReceipts.bind(network.nahmiiProvider), address, null, 1000);
yield put(actions.loadReceiptsSuccess(address, receipts));
} catch (e) {
yield put(actions.loadReceiptsError(address, e));
}
}

export function* loadAllWalletReceipts() {
const network = yield select(makeSelectCurrentNetwork());
const wallets = yield select(makeSelectWallets());
for (const wallet of wallets) {
yield fork(loadWalletReceipts, { address: wallet.get('address') }, network);
}
}

// manages calling of complex ethOperations
export function* challengeStatusOrcestrator() {
try {
Expand All @@ -731,7 +770,7 @@ export function* challengeStatusOrcestrator() {
const allTasks = yield all([
...wallets.map((wallet) => fork(loadBalances, { address: wallet.get('address') }, network)),
...wallets.map((wallet) => fork(loadStagedBalances, { address: wallet.get('address') }, network)),
...wallets.map((wallet) => fork(loadWalletReceipts, { address: wallet.get('address') }, network)),
// ...wallets.map((wallet) => fork(loadWalletReceipts, { address: wallet.get('address') }, network)),
]);

const currentWalletAddress = (yield select(makeSelectCurrentWallet())).get('address');
Expand Down Expand Up @@ -813,6 +852,10 @@ export function* processPendingSettlementTransactions() {
export default function* listen() {
yield takeLatest(INIT_NETWORK_ACTIVITY, challengeStatusOrcestrator);
yield takeLatest(INIT_NETWORK_ACTIVITY, processPendingSettlementTransactions);
yield takeLatest(INIT_NETWORK_ACTIVITY, listenReceiptEvent);
yield takeLatest(INIT_NETWORK_ACTIVITY, loadAllWalletReceipts);
yield takeLatest(CHANGE_NETWORK, listenReceiptEvent);
yield takeLatest(CHANGE_NETWORK, loadAllWalletReceipts);
yield takeLatest(CHANGE_NETWORK, processPendingSettlementTransactions);
yield takeEvery(NAHMII_DEPOSIT, deposit);
yield takeEvery(NAHMII_DEPOSIT_ETH, depositEth);
Expand Down
5 changes: 5 additions & 0 deletions src/containers/NahmiiHoc/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ const makeSelectReceiptsWithInfo = () => createSelector(
receiptWithInfo.get('updated')
);

receiptWithInfo = receiptWithInfo.set(
'hash',
receiptWithInfo.getIn(['seals', 'operator', 'hash'])
);

return result.push(receiptWithInfo);
}, new List());

Expand Down
8 changes: 8 additions & 0 deletions src/containers/NahmiiHoc/tests/mocks/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ export const receiptsWithInfo = receiptsLoaded
['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 1, 'confirmed'],
true
)
.setIn(
['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 1, 'hash'],
receiptsLoaded.getIn(['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 1, 'seals', 'operator', 'hash'])
)
.setIn(
['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 0, 'type'],
'received'
Expand Down Expand Up @@ -249,6 +253,10 @@ export const receiptsWithInfo = receiptsLoaded
.setIn(
['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 0, 'confirmed'],
true
)
.setIn(
['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 0, 'hash'],
receiptsLoaded.getIn(['0x1c7429f62595097315289ceBaC1fDbdA587Ad512', 'receipts', 0, 'seals', 'operator', 'hash'])
);

// makeSelectNahmiiBalances
Expand Down
81 changes: 80 additions & 1 deletion src/containers/NahmiiHoc/tests/saga.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { expectSaga } from 'redux-saga-test-plan';
import { eventChannel } from 'redux-saga';
import { fromJS } from 'immutable';
import nahmii from 'nahmii-sdk';
import { storeMock } from 'mocks/store';
import { currentNetworkMock } from 'containers/App/tests/mocks/selectors';
import { getIntl } from 'utils/localisation';
import BigNumber from 'bignumber.js';
import { showDecryptWalletModal } from 'containers/WalletHoc/actions';
import { notify } from 'containers/App/actions';
import { notify, changeNetwork } from 'containers/App/actions';
import * as actions from '../actions';
import {
loadBalances,
Expand All @@ -25,6 +26,7 @@ import {
reloadSettlementStatesHook,
processTx,
processPendingSettlementTransactions,
listenReceiptEvent,
} from '../saga';
import nahmiiHocReducer from '../reducer';

Expand Down Expand Up @@ -62,6 +64,83 @@ describe('nahmiiHocSaga', () => {
.put(actions.loadBalancesError(address))
.run({ silenceTimeout: true }));
});
describe.only('#listenReceiptEvent()', () => {
const currency = '0x0000000000000000000000000000000000000000';
const receipt = new nahmii.Receipt(nahmii.Payment.from({
amount: '1',
currency: {
ct: currency,
id: 0,
},
sender: {
wallet: storeMock.getIn(['walletHoc', 'wallets', 0, 'address']),
},
recipient: {
wallet: storeMock.getIn(['walletHoc', 'wallets', 1, 'address']),
},
}));

it('should trigger receivedNewReceipt action when an receipt comes from the event API', () => {
const disposeListener = jest.fn();
return expectSaga(listenReceiptEvent)
.withReducer(withReducer, storeMock)
.provide({
call(effect) {
if (effect.fn.name === 'receiptEventChannel') {
return eventChannel((emitter) => {
setTimeout(() => {
emitter(receipt);
}, 100);
return () => {
disposeListener();
};
});
}
return true;
},
})
.put(actions.newReceiptReceived(receipt.sender, receipt.toJSON()))
.put(actions.newReceiptReceived(receipt.recipient, receipt.toJSON()))
.run({ silenceTimeout: true })
.then((result) => {
const state = result.storeState;
const receiptsByWallet1 = state.getIn(['nahmiiHoc', 'receipts', storeMock.getIn(['walletHoc', 'wallets', 0, 'address']), 'receipts']);
expect(receiptsByWallet1).toEqual(
storeMock
.getIn(['nahmiiHoc', 'receipts', storeMock.getIn(['walletHoc', 'wallets', 0, 'address']), 'receipts'])
.unshift(fromJS({ ...receipt.toJSON(), created: new Date().toISOString(), updated: new Date().toISOString() }))
);
const receiptsByWallet2 = state.getIn(['nahmiiHoc', 'receipts', storeMock.getIn(['walletHoc', 'wallets', 1, 'address']), 'receipts']);
expect(receiptsByWallet2).toEqual(fromJS([{ ...receipt.toJSON(), created: new Date().toISOString(), updated: new Date().toISOString() }]));
expect(disposeListener.mock.calls.length).toEqual(0);
});
});
it('should trigger close the event channel when CHANGE_NETWORK is triggered', () => {
const disposeListener = jest.fn();
return expectSaga(listenReceiptEvent)
.withReducer(withReducer, storeMock)
.provide({
call(effect) {
if (effect.fn.name === 'receiptEventChannel') {
return eventChannel((emitter) => {
setTimeout(() => {
emitter(receipt);
}, 100);
return () => {
disposeListener();
};
});
}
return true;
},
})
.dispatch(changeNetwork())
.run({ silenceTimeout: true })
.then(() => {
expect(disposeListener).toBeCalled();
});
});
});
describe('makePayment', () => {
let monetaryAmount;
let recipient;
Expand Down
4 changes: 2 additions & 2 deletions src/containers/NahmiiWithdraw/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ export class NahmiiWithdraw extends React.Component { // eslint-disable-line rea
amountToWithdrawInputRegex,
gasPriceGweiInput: '10',
gasPriceGwei: new BigNumber('10'),
gasLimit: 2000000,
gasLimitInput: '2000000',
gasLimit: 3000000,
gasLimitInput: '3000000',
addContactModalVisibility: false,
showGasPriceConfirmModal: false,
};
Expand Down
Loading

0 comments on commit 7634814

Please sign in to comment.