Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
feature(store): added block, ocean and transaction_queue store (#8)
Browse files Browse the repository at this point in the history
* feature(store): added block, ocean and transaction_queue store

* feature(store): added block, ocean and transaction_queue store
  • Loading branch information
thedoublejay authored Dec 14, 2022
1 parent 2113608 commit 790fae6
Show file tree
Hide file tree
Showing 13 changed files with 554 additions and 39 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public-hoist-pattern[]=*vite*
public-hoist-pattern[]=*react*
public-hoist-pattern[]=*defichain*
public-hoist-pattern[]=*@waveshq*
public-hoist-pattern[]=@reduxjs/*

engine-strict=true
auto-install-peers=true
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"@birthdayresearch/eslint-config": "^0.3.2",
"@birthdayresearch/sticky-turbo": "^0.3.2",
"@waveshq/walletkit-core": "workspace:*",
"@waveshq/standard-web": "^0.15.1",
"@waveshq/standard-web-linter": "^0.15.1",
"@waveshq/standard-defichain-jellyfishsdk": "^0.15.1",
"@waveshq/standard-prettier": "^0.15.1"
"@waveshq/standard-web": "^0.17.0",
"@waveshq/standard-web-linter": "^0.17.0",
"@waveshq/standard-defichain-jellyfishsdk": "^0.17.0",
"@waveshq/standard-prettier": "^0.17.0"
},
"eslintConfig": {
"extends": [
Expand Down
3 changes: 2 additions & 1 deletion packages/walletkit-ui/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"project": "./tsconfig.json"
},
"rules": {
"check-file/filename-naming-convention": "off"
"check-file/filename-naming-convention": "off",
"no-param-reassign": "warn"
}
}
11 changes: 7 additions & 4 deletions packages/walletkit-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
],
"dependencies": {
"@birthdayresearch/sticky-jest": "^0.3.2",
"@waveshq/standard-web": "^0.15.1",
"@waveshq/standard-web-linter": "^0.15.1",
"@waveshq/standard-defichain-jellyfishsdk": "^0.15.1",
"@waveshq/standard-web": "^0.17.0",
"@waveshq/standard-web-linter": "^0.17.0",
"@waveshq/standard-defichain-jellyfishsdk": "^0.17.0",
"@waveshq/walletkit-core": "workspace:*",
"bignumber.js": "^9.1.1"
"bignumber.js": "^9.1.1",
"immer": "^9.0.16",
"reselect": "^4.1.7",
"smart-buffer": "^4.2.0"
},
"scripts": {
"build": "tsc -b ./tsconfig.build.json",
Expand Down
1 change: 1 addition & 0 deletions packages/walletkit-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./contexts";
export * from "./store";
57 changes: 57 additions & 0 deletions packages/walletkit-ui/src/store/block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// TODO(@thedoublejay): see https://github.com/microsoft/TypeScript/issues/47663
import type {} from "immer";

export interface BlockState {
count?: number;
masternodeCount?: number;
lastSync?: string;
connected: boolean;
isPolling: boolean;
tvl?: number;
lastSuccessfulSync?: string;
}

const initialState: BlockState = {
count: undefined,
masternodeCount: undefined,
lastSync: undefined,
connected: false,
isPolling: false,
tvl: undefined,
lastSuccessfulSync: undefined,
};

export const block = createSlice({
name: "block",
initialState,
reducers: {
updateBlockDetails: (
state,
action: PayloadAction<{
count: number;
masternodeCount: number;
lastSync?: string;
lastSuccessfulSync?: string;
tvl?: number;
}>
) => {
state.count = action.payload.count;
state.masternodeCount = action.payload.masternodeCount;
const firstSuccessfulSync =
state.lastSuccessfulSync ?? new Date().toString();
state.lastSuccessfulSync =
action.payload.lastSuccessfulSync != null
? action.payload.lastSuccessfulSync
: firstSuccessfulSync;
state.lastSync = action.payload.lastSync; // updated even if its not successful (no connection)
state.tvl = action.payload.tvl;
},
setConnected: (state, action: PayloadAction<boolean>) => {
state.connected = action.payload;
},
setPolling: (state, action: PayloadAction<boolean>) => {
state.isPolling = action.payload;
},
},
});
68 changes: 68 additions & 0 deletions packages/walletkit-ui/src/store/block.unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { block, BlockState } from "./block";

describe("block reducer", () => {
let initialState: BlockState;
const date = new Date().toString();

beforeEach(() => {
initialState = {
count: 77,
masternodeCount: 10,
lastSuccessfulSync: date,
lastSync: date,
isPolling: false,
connected: false,
tvl: 1,
};
});

it("should handle initial state", () => {
expect(block.reducer(undefined, { type: "unknown" })).toEqual({
count: undefined,
masternodeCount: undefined,
lastSuccessfulSync: undefined,
connected: false,
isPolling: false,
tvl: undefined,
lastSync: undefined,
});
});

it("should handle updateBlock", () => {
const payload = {
count: 99,
masternodeCount: 0,
lastSuccessfulSync: date,
lastSync: date,
tvl: 1,
};
const actual = block.reducer(
initialState,
block.actions.updateBlockDetails(payload)
);
expect(actual).toStrictEqual({ ...initialState, ...payload });
});

it("should handle setConnected", () => {
const actual = block.reducer(
initialState,
block.actions.setConnected(true)
);
expect(actual).toStrictEqual({
...initialState,
count: 77,
isPolling: false,
connected: true,
});
});

it("should handle setPolling", () => {
const actual = block.reducer(initialState, block.actions.setPolling(true));
expect(actual).toStrictEqual({
...initialState,
count: 77,
isPolling: true,
connected: false,
});
});
});
3 changes: 3 additions & 0 deletions packages/walletkit-ui/src/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./block";
export * from "./ocean";
export * from "./transaction_queue";
76 changes: 76 additions & 0 deletions packages/walletkit-ui/src/store/ocean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { CTransactionSegWit } from "@defichain/jellyfish-transaction";
import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit";
// TODO(@thedoublejay): see https://github.com/microsoft/TypeScript/issues/47663
import type {} from "reselect";

export enum TransactionStatusCode {
success = 200,
pending = 202,
}

export interface OceanTransaction {
broadcasted: boolean;
tx: CTransactionSegWit;
title?: string;
drawerMessages?: {
preparing?: string;
waiting?: string;
complete?: string;
};
submitButtonLabel?: string;
onBroadcast?: () => any;
onConfirmation?: () => any;
onError?: () => any;
oceanStatusCode?: TransactionStatusCode;
}

export interface OceanState {
transactions: OceanTransaction[];
height: number;
err?: Error;
}

const initialState: OceanState = {
transactions: [],
height: 0,
err: undefined,
};

export const ocean = createSlice({
name: "ocean",
initialState,
reducers: {
setHeight: (state, action: PayloadAction<number>) => {
state.height = action.payload;
},
queueTransaction: (
state,
action: PayloadAction<Omit<OceanTransaction, "broadcasted">>
) => {
state.transactions = [
...state.transactions,
{
...action.payload,
broadcasted: false,
},
];
},
setError: (state, action: PayloadAction<Error>) => {
state.err = action.payload;
},
popTransaction: (state) => {
state.transactions.shift();
state.transactions = [...state.transactions];
},
},
});

export const firstTransactionSelector = createSelector(
(state: OceanState) => state.transactions,
(transactions) => transactions[0]
);

export const hasOceanTXQueued = createSelector(
(state: OceanState) => state.transactions,
(transactions) => transactions.length > 0
);
86 changes: 86 additions & 0 deletions packages/walletkit-ui/src/store/ocean.unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { CTransactionSegWit } from "@defichain/jellyfish-transaction";
import { SmartBuffer } from "smart-buffer";

import { ocean, OceanState, OceanTransaction } from "./ocean";

describe("ocean reducer", () => {
let initialState: OceanState;

beforeEach(() => {
initialState = {
transactions: [],
height: 0,
err: undefined,
};
});

it("should handle initial state", () => {
expect(ocean.reducer(undefined, { type: "unknown" })).toEqual({
transactions: [],
err: undefined,
height: 0,
});
});

it("should handle queueTransaction and popTransaction", () => {
const v2 =
"020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050393700500ffffffff038260498a040000001976a9143db7aeb218455b697e94f6ff00c548e72221231d88ac7e67ce1d0000000017a914dd7730517e0e4969b4e43677ff5bee682e53420a870000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000";
const buffer = SmartBuffer.fromBuffer(Buffer.from(v2, "hex"));
const signed = new CTransactionSegWit(buffer);
const payload: Omit<OceanTransaction, "broadcasted"> = {
title: "Sending",
tx: signed,
};
const addedTransaction = ocean.reducer(
initialState,
ocean.actions.queueTransaction(payload)
);
expect(addedTransaction).toStrictEqual({
transactions: [
{
...payload,
broadcasted: false,
},
],
err: undefined,
height: 0,
});
const actual = ocean.reducer(
addedTransaction,
ocean.actions.queueTransaction(payload)
);

const pop = ocean.reducer(actual, ocean.actions.popTransaction());
expect(pop).toStrictEqual({
transactions: [
{
...payload,
broadcasted: false,
},
],
err: undefined,
height: 0,
});
const removed = ocean.reducer(pop, ocean.actions.popTransaction());
expect(removed).toStrictEqual({
transactions: [],
err: undefined,
height: 0,
});
});

it("should handle setError", () => {
const err = new Error("An error has occurred");
const actual = ocean.reducer(initialState, ocean.actions.setError(err));
expect(actual).toStrictEqual({ transactions: [], err, height: 0 });
});

it("should setHeight", () => {
const actual = ocean.reducer(initialState, ocean.actions.setHeight(77));
expect(actual).toStrictEqual({
transactions: [],
err: undefined,
height: 77,
});
});
});
Loading

0 comments on commit 790fae6

Please sign in to comment.