All files / app/store/stacks-node stacks-node.reducer.ts

0% Statements 0/24
0% Branches 0/1
0% Functions 0/5
0% Lines 0/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74                                                                                                                                                   
import { RootState } from '..';
import { DEFAULT_STACKS_NODE_URL } from '@constants/index';
import {
  createEntityAdapter,
  EntityState,
  createSlice,
  createSelector,
  PayloadAction,
} from '@reduxjs/toolkit';
import { StacksMainnet, StacksNetwork, StacksTestnet } from '@stacks/network';
import { whenNetwork } from '@utils/network-utils';
 
export interface StacksNode {
  url: string;
  name: string;
  id: string;
}
 
export interface StacksNodeState extends EntityState<StacksNode> {
  selectedApiId: string;
}
 
const stacksNodeAdapter = createEntityAdapter<StacksNode>();
 
const emptyInitialState = stacksNodeAdapter.getInitialState({
  selectedApiId: 'default',
});
 
const stacksNodeSlice = createSlice({
  name: 'stacksNodes',
  initialState: emptyInitialState,
  reducers: {
    upsertStacksNodeApi: stacksNodeAdapter.upsertOne,
    removeStacksNodeApi: (state, action) => ({
      ...stacksNodeAdapter.removeOne({ ...state, selectedApiId: 'default' }, action),
    }),
    setActiveStacksNode: (state, action: PayloadAction<string>) => ({
      ...state,
      selectedApiId: action.payload,
    }),
  },
});
 
export const stacksNodeReducer = stacksNodeSlice.reducer;
 
export const upsertStacksNodeApi = stacksNodeSlice.actions.upsertStacksNodeApi;
export const removeStacksNodeApi = stacksNodeSlice.actions.removeStacksNodeApi;
export const setActiveStacksNode = stacksNodeSlice.actions.setActiveStacksNode;
 
export const defaultNode: StacksNode = Object.freeze({
  url: DEFAULT_STACKS_NODE_URL,
  name: 'Hiro Systems node',
  id: 'default',
});
 
const selectStacksNodeState = (state: RootState) => state.stacksNode;
const selectors = stacksNodeAdapter.getSelectors(selectStacksNodeState);
export const selectStacksNodeApis = selectors.selectAll;
export const selectActiveNodeApi = createSelector(
  selectStacksNodeState,
  // coercing type as default node is always selected
  state => {
    Iif (state.selectedApiId === 'default') return defaultNode;
    return state.entities[state.selectedApiId] as StacksNode;
  }
);
 
export const selectActiveStacksNetwork = createSelector(selectActiveNodeApi, activeNode =>
  whenNetwork<StacksNetwork>({
    mainnet: new StacksMainnet({ url: activeNode.url }),
    testnet: new StacksTestnet({ url: activeNode.url }),
  })
);