Skip to content

Commit

Permalink
feat(nc): implement unregister nano contract saga effect
Browse files Browse the repository at this point in the history
fix: docstring

fix: registerNanoContract test

fix: historyNanoContract test

feat: remove registered nano contracts on cleanTokens

feat: add unregisterNanoContract to HybridStore
  • Loading branch information
alexruzenhack committed May 28, 2024
1 parent c744c93 commit a56f2fc
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 7 deletions.
1 change: 1 addition & 0 deletions __tests__/sagas/nanoContracts/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const fixtures = {
ncState: {
success: true,
nc_id: '3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595',
blueprint_id: '000001342d3c5b858a4d4835baea93fcc683fa615ff5892bd044459621a0340a',
blueprint_name: 'Bet',
fields: {
token_uid: { value: '00' },
Expand Down
8 changes: 3 additions & 5 deletions __tests__/sagas/nanoContracts/historyNanoContract.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ describe('sagas/nanoContract/fetchHistory', () => {
// arrange wallet mock
const mockedWallet = {
getNetworkObject: jest.fn(),
storage: {
isAddressMine: jest.fn(),
},
isAddressMine: jest.fn(),
};
// arrange ncApi mock
const mockedNcApi = jest.mocked(ncApi);
Expand Down Expand Up @@ -115,10 +113,10 @@ describe('sagas/nanoContract/requestHistoryNanoContract', () => {

// call effect to request history
const gen = requestHistoryNanoContract(nanoContractHistoryRequest({ ncId }));
// select wallet
// select historyMeta
gen.next();
// feed back historyMeta
gen.next({});
gen.next({ [ncId]: { isLoading: false, after: null } });
// feed back wallet
gen.next(fixtures.wallet.readyAndMine);
// feed back isNanoContractRegistered
Expand Down
1 change: 1 addition & 0 deletions __tests__/sagas/nanoContracts/registerNanoContract.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ describe('sagas/nanoContract/registerNanoContract', () => {
expect(actionResult.payload.action.payload.entryValue).toEqual(expect.objectContaining({
address,
ncId,
blueprintId: expect.any(String),
blueprintName: expect.any(String),
}));
// assert termination
Expand Down
40 changes: 40 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ export const types = {
NANOCONTRACT_HISTORY_SUCCESS: 'NANOCONTRACT_HISTORY_SUCCESS',
/* It indicates a Nano Contract history failed to load. */
NANOCONTRACT_HISTORY_FAILURE: 'NANOCONTRACT_HISTORY_FAILURE',
/* It initiates an unregistration process of a Nano Contract. */
NANOCONTRACT_UNREGISTER_REQUEST: 'NANOCONTRACT_UNREGISTER_REQUEST',
/* It signals a successful completion of unregistration process. */
NANOCONTRACT_UNREGISTER_SUCCESS: 'NANOCONTRACT_UNREGISTER_SUCCESS',
/* It initiates a process to change the address on registered Nano Contract. */
NANOCONTRACT_ADDRESS_CHANGE_REQUEST: 'NANOCONTRACT_ADDRESS_CHANGE_REQUEST',
};

export const featureToggleInitialized = () => ({
Expand Down Expand Up @@ -1055,3 +1061,37 @@ export const nanoContractHistoryFailure = (payload) => ({
type: types.NANOCONTRACT_HISTORY_FAILURE,
payload,
});

/**
* Request unregistration of a Nano Contract by its key.
* @param {{
* ncId: string,
* }} Nano Contract ID to unregister.
*/
export const nanoContractUnregisterRequest = (unregisterRequest) => ({
type: types.NANOCONTRACT_UNREGISTER_REQUEST,
payload: unregisterRequest,
});

/**
* Unregistration of a Nano Contract has finished with success.
* @param {{
* ncId: string,
* }} Nano Contract ID unregistered.
*/
export const nanoContractUnregisterSuccess = (unregistered) => ({
type: types.NANOCONTRACT_UNREGISTER_SUCCESS,
payload: unregistered,
});

/**
* Request a change on the Nano Contract registered.
* @param {{
* newAddress: string;
* oldNc: Object;
* }} changeAddressRequest
*/
export const nanoContractAddressChangeRequest = (changeAddressRequest) => ({
type: types.NANOCONTRACT_ADDRESS_CHANGE_REQUEST,
payload: changeAddressRequest,
});
33 changes: 33 additions & 0 deletions src/reducers/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ export const reducer = (state = initialState, action) => {
return onNanoContractHistoryFailure(state, action);
case types.NANOCONTRACT_HISTORY_SUCCESS:
return onNanoContractHistorySuccess(state, action);
case types.NANOCONTRACT_UNREGISTER_SUCCESS:
return onNanoContractUnregisterSuccess(state, action);
default:
return state;
}
Expand Down Expand Up @@ -1329,6 +1331,37 @@ export const onNanoContractRegisterSuccess = (state, { payload }) => ({
},
});

/**
* @param {Object} state
* @param {{
* payload: {
* ncId: string,
* }
* }} action
*/
export const onNanoContractUnregisterSuccess = (state, { payload }) => {
const { ncId } = payload;

const newRegisteredContracts = { ...state.nanoContract.registered, };
delete newRegisteredContracts[ncId];

const newContractsHistory = { ...state.nanoContract.history };
delete newContractsHistory[ncId];

const newContractsHistoryMeta = { ...state.nanoContract.historyMeta };
delete newContractsHistoryMeta[ncId];

return ({
...state,
nanoContract: {
...state.nanoContract,
registered: newRegisteredContracts,
history: newContractsHistory,
historyMeta: newContractsHistoryMeta,
},
});
};

/**
* @param {Object} state
* @param {{
Expand Down
33 changes: 31 additions & 2 deletions src/sagas/nanoContract.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
nanoContractHistorySuccess,
nanoContractRegisterFailure,
nanoContractRegisterSuccess,
nanoContractUnregisterSuccess,
onExceptionCaptured,
types,
} from '../actions';
Expand Down Expand Up @@ -80,7 +81,8 @@ export function* registerNanoContract({ payload }) {

let ncState = null;
try {
ncState = yield call(ncApi.getNanoContractState.bind(ncApi), ncId);
const response = yield call(ncApi.getNanoContractState.bind(ncApi), ncId);
ncState = response.ncState;
} catch (error) {
if (error instanceof NanoRequest404Error) {
yield put(nanoContractRegisterFailure(failureMessage.nanoContractStateNotFound));
Expand All @@ -95,7 +97,7 @@ export function* registerNanoContract({ payload }) {
address,
ncId,
blueprintId: ncState.blueprint_id,
blueprintName: ncState.blueprint_name
blueprintName: ncState.blueprint_name,
};
yield call(wallet.storage.registerNanoContract.bind(wallet.storage), ncId, nc);

Expand Down Expand Up @@ -254,9 +256,36 @@ export function* requestHistoryNanoContract({ payload }) {
}
}

/**
* Process Nano Contract unregister request.
* @param {{
* payload: {
* ncId: string;
* }
* }} action with request payload.
*/
export function* unregisterNanoContract({ payload }) {
const { ncId } = payload;

const wallet = yield select((state) => state.wallet);
if (!wallet.isReady()) {
log.debug('Fail unregistering Nano Contract because wallet is not ready yet.');
// This will show user an error modal with the option to send the error to sentry.
yield put(onExceptionCaptured(new Error(failureMessage.walletNotReadyError), true));
return;
}

yield call(wallet.storage.unregisterNanoContract.bind(wallet.storage), ncId);

log.debug(`Success unregistering Nano Contract. ncId = ${ncId}`);
// emit action NANOCONTRACT_REGISTER_SUCCESS
yield put(nanoContractUnregisterSuccess({ ncId }));
}

export function* saga() {
yield all([
takeEvery(types.NANOCONTRACT_REGISTER_REQUEST, registerNanoContract),
takeEvery(types.NANOCONTRACT_HISTORY_REQUEST, requestHistoryNanoContract),
takeEvery(types.NANOCONTRACT_UNREGISTER_REQUEST, unregisterNanoContract),
]);
}
14 changes: 14 additions & 0 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ class HybridStore extends MemoryStore {
STORE.setItem(REGISTERED_NANO_CONTRACTS_KEY, contracts)
}

/**
* Unregister a nano contract.
*
* @param {string} ncId Nano Contract ID.
* @returns {Promise<void>}
* @async
*/
async unregisterNanoContract(ncId) {
await super.unregisterNanoContract(ncId);
const contracts = STORE.getItem(REGISTERED_NANO_CONTRACTS_KEY) || {};
delete contracts[ncId];
}

/**
* Clean the storage.
* @param {boolean} cleanHistory if we should clean the transaction history.
Expand All @@ -157,6 +170,7 @@ class HybridStore extends MemoryStore {
if (cleanTokens) {
// Remove from the cache
STORE.removeItem(REGISTERED_TOKENS_KEY);
STORE.removeItem(REGISTERED_NANO_CONTRACTS_KEY);
}
}
}
Expand Down

0 comments on commit a56f2fc

Please sign in to comment.