mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
Compare commits
4 commits
23433a05ed
...
fba30046eb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fba30046eb | ||
|
|
a04ecb750d | ||
|
|
5ed07dbf71 | ||
|
|
b6646d7868 |
11 changed files with 2206 additions and 2492 deletions
22
.github/workflows/main.yml
vendored
22
.github/workflows/main.yml
vendored
|
|
@ -26,6 +26,11 @@ env:
|
|||
# /dev.Dockerfile
|
||||
GO_VERSION: 1.25.11
|
||||
|
||||
# Only applies to the CI jobs below. The note above covers GO_VERSION alone:
|
||||
# /Dockerfile and /dev.Dockerfile pin their own Node version for release
|
||||
# builds, and it does not have to match this one.
|
||||
NODE_VERSION: 24.x
|
||||
|
||||
jobs:
|
||||
########################
|
||||
# frontend build checks
|
||||
|
|
@ -36,7 +41,6 @@ jobs:
|
|||
|
||||
strategy:
|
||||
matrix:
|
||||
node_version: [ 16.x ]
|
||||
os: [ ubuntu-latest, windows-latest, macOS-latest ]
|
||||
|
||||
steps:
|
||||
|
|
@ -45,10 +49,10 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: setup nodejs ${{ matrix.node_version }}
|
||||
- name: setup nodejs ${{ env.NODE_VERSION }}
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: '${{ matrix.node_version }}'
|
||||
node-version: '${{ env.NODE_VERSION }}'
|
||||
|
||||
- name: install dependencies
|
||||
working-directory: ./app
|
||||
|
|
@ -84,10 +88,10 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: setup nodejs ${{ matrix.node_version }}
|
||||
- name: setup nodejs ${{ env.NODE_VERSION }}
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: '${{ matrix.node_version }}'
|
||||
node-version: '${{ env.NODE_VERSION }}'
|
||||
|
||||
- name: setup go ${{ env.GO_VERSION }}
|
||||
uses: ./.github/actions/setup-go
|
||||
|
|
@ -144,10 +148,10 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: setup nodejs ${{ matrix.node_version }}
|
||||
- name: setup nodejs ${{ env.NODE_VERSION }}
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: '${{ matrix.node_version }}'
|
||||
node-version: '${{ env.NODE_VERSION }}'
|
||||
|
||||
- name: setup go ${{ env.GO_VERSION }}
|
||||
uses: ./.github/actions/setup-go
|
||||
|
|
@ -324,10 +328,10 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: setup nodejs ${{ matrix.node_version }}
|
||||
- name: setup nodejs ${{ env.NODE_VERSION }}
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: '${{ matrix.node_version }}'
|
||||
node-version: '${{ env.NODE_VERSION }}'
|
||||
|
||||
- name: setup go ${{ env.GO_VERSION }}
|
||||
uses: ./.github/actions/setup-go
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
"@emotion/react": "11.4.0",
|
||||
"@emotion/styled": "11.3.0",
|
||||
"@improbable-eng/grpc-web": "0.14.0",
|
||||
"@remix-run/router": "1.23.3",
|
||||
"@types/react-collapse": "^5.0.1",
|
||||
"big.js": "6.1.1",
|
||||
"bootstrap": "4.6.1",
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
"date-fns": "2.14.0",
|
||||
"debug": "4.3.1",
|
||||
"file-saver": "2.0.2",
|
||||
"http-proxy-middleware": "2.0.9",
|
||||
"http-proxy-middleware": "2.0.10",
|
||||
"i18next": "19.5.1",
|
||||
"i18next-browser-languagedetector": "5.0.0",
|
||||
"lodash": "4.18.1",
|
||||
|
|
@ -48,7 +49,7 @@
|
|||
"react-collapse": "^5.1.1",
|
||||
"react-dom": "17.0.2",
|
||||
"react-i18next": "13.5.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-router-dom": "6.30.4",
|
||||
"react-toastify": "6.0.6",
|
||||
"react-virtualized": "9.21.2",
|
||||
"reactour": "1.18.0",
|
||||
|
|
@ -56,13 +57,13 @@
|
|||
"styled-components": "5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-actions": "7.5.3",
|
||||
"@storybook/addon-docs": "7.5.3",
|
||||
"@storybook/addon-links": "7.5.3",
|
||||
"@storybook/addons": "7.5.3",
|
||||
"@storybook/preset-create-react-app": "7.5.3",
|
||||
"@storybook/react": "7.5.3",
|
||||
"@storybook/react-webpack5": "7.5.3",
|
||||
"@storybook/addon-actions": "7.6.24",
|
||||
"@storybook/addon-docs": "7.6.24",
|
||||
"@storybook/addon-links": "7.6.24",
|
||||
"@storybook/addons": "7.6.24",
|
||||
"@storybook/preset-create-react-app": "7.6.24",
|
||||
"@storybook/react": "7.6.24",
|
||||
"@storybook/react-webpack5": "7.6.24",
|
||||
"@testing-library/jest-dom": "5.11.5",
|
||||
"@testing-library/react": "11.1.1",
|
||||
"@testing-library/user-event": "12.2.0",
|
||||
|
|
@ -71,13 +72,11 @@
|
|||
"@types/debug": "4.1.5",
|
||||
"@types/file-saver": "2.0.1",
|
||||
"@types/google-protobuf": "3.15.10",
|
||||
"@types/history": "4.7.6",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/lodash": "4.14.157",
|
||||
"@types/node": "14.0.14",
|
||||
"@types/react": "17.0.13",
|
||||
"@types/react-dom": "17.0.8",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-virtualized": "9.21.10",
|
||||
"@types/reactour": "1.17.1",
|
||||
"@types/semver": "^7.3.9",
|
||||
|
|
@ -94,14 +93,23 @@
|
|||
"protoc-gen-js": "3.21.2",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "1.43.4",
|
||||
"storybook": "7.5.3",
|
||||
"storybook": "7.6.24",
|
||||
"ts-protoc-gen": "0.15.0",
|
||||
"typescript": "4.1.6",
|
||||
"webpack": "5.89.0"
|
||||
"typescript": "4.9.5",
|
||||
"webpack": "5.109.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"strip-ansi": "6.0.1",
|
||||
"@tootallnate/once": "2.0.1",
|
||||
"esbuild": "0.25.12",
|
||||
"http-proxy-middleware": "2.0.10",
|
||||
"jackspeak": "2.1.1",
|
||||
"nth-check": "2.1.1",
|
||||
"resolve-url-loader": "5.0.0",
|
||||
"serialize-javascript": "7.1.0",
|
||||
"strip-ansi": "6.0.1",
|
||||
"svgo": "2.8.3",
|
||||
"tar": "7.5.22",
|
||||
"uuid": "11.1.1",
|
||||
"wrap-ansi": "7.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@ describe('AppView', () => {
|
|||
expect(store.alerts.size).toBe(1);
|
||||
});
|
||||
|
||||
it('should handle values thrown that are not Errors', () => {
|
||||
// Nothing in the language guarantees a thrown value is an Error, and
|
||||
// showing the user an empty alert is worse than showing the raw value.
|
||||
store.handleError('something went wrong', 'title');
|
||||
expect(store.alerts.size).toBe(1);
|
||||
const alert = values(store.alerts)[0];
|
||||
expect(alert.message).toBe('something went wrong');
|
||||
expect(alert.title).toBe('title');
|
||||
});
|
||||
|
||||
it('should handle authentication errors', () => {
|
||||
rootStore.authStore.authenticated = true;
|
||||
expect(store.alerts.size).toBe(0);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ const AuthPage: React.FC = () => {
|
|||
try {
|
||||
await store.authStore.login(pass);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
setError(err instanceof Error ? err.message : String(err));
|
||||
const errors = store.authStore.errors;
|
||||
setErrorDetailLit(errors.litDetail);
|
||||
setErrorDetailLnd(errors.lndDetail);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { autorun, makeAutoObservable, runInAction } from 'mobx';
|
||||
import { IS_DEV, IS_TEST, USE_SAMPLE_DATA } from 'config';
|
||||
import { createBrowserHistory, History } from 'history';
|
||||
import { createBrowserHistory, History } from '@remix-run/router';
|
||||
import AppStorage from 'util/appStorage';
|
||||
import CsvExporter from 'util/csv';
|
||||
import { actionLog, Logger } from 'util/log';
|
||||
|
|
@ -217,7 +217,9 @@ export const createStore = (grpcClient?: GrpcClient, appStorage?: AppStorage) =>
|
|||
const poolApi = new PoolApi(grpc);
|
||||
const litApi = new LitApi(grpc);
|
||||
const csv = new CsvExporter();
|
||||
const history = createBrowserHistory();
|
||||
// v5Compat is required for listeners to be notified of push() and replace()
|
||||
// calls, not just browser back/forward navigation.
|
||||
const history = createBrowserHistory({ v5Compat: true });
|
||||
|
||||
const store = new Store(
|
||||
lndApi,
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ export default class AuthStore {
|
|||
this.setCredentials('');
|
||||
this._store.log.error('connection failure');
|
||||
this.errors = { mainErr: '', litDetail: '', lndDetail: '' };
|
||||
throw new Error(await this.getErrMsg(error.message));
|
||||
throw new Error(
|
||||
await this.getErrMsg(error instanceof Error ? error.message : String(error)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ export default class BatchStore {
|
|||
this.loading = false;
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.message !== 'batch snapshot not found') {
|
||||
if (!(error instanceof Error) || error.message !== 'batch snapshot not found') {
|
||||
this._store.appView.handleError(error, `Unable to fetch batch with id ${prevId}`);
|
||||
}
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ export default class BatchStore {
|
|||
this._store.log.info('updated batchStore.markets', toJS(this.markets));
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.message === 'batch snapshot not found') return;
|
||||
if (error instanceof Error && error.message === 'batch snapshot not found') return;
|
||||
this._store.appView.handleError(error, 'Unable to fetch the latest batch');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { makeAutoObservable, runInAction } from 'mobx';
|
||||
import { History, Location } from 'history';
|
||||
import { History, Location } from '@remix-run/router';
|
||||
|
||||
/** the listener callback accepted by the history object */
|
||||
type Listener = Parameters<History['listen']>[0];
|
||||
|
||||
export default class RouterStore {
|
||||
/** the history object */
|
||||
|
|
@ -11,13 +14,31 @@ export default class RouterStore {
|
|||
constructor(history: History) {
|
||||
makeAutoObservable(this, { history: false }, { deep: false, autoBind: true });
|
||||
|
||||
this.history = history;
|
||||
this.location = history.location;
|
||||
|
||||
history.listen(({ location }) => {
|
||||
// The router's history implementation only accepts a single active
|
||||
// listener, but both this store and the <HistoryRouter> component need to
|
||||
// observe navigation. Subscribe once here and fan the updates out to any
|
||||
// additional listeners.
|
||||
const listeners = new Set<Listener>();
|
||||
history.listen(update => {
|
||||
runInAction(() => {
|
||||
this.location = location;
|
||||
this.location = update.location;
|
||||
});
|
||||
listeners.forEach(listener => listener(update));
|
||||
});
|
||||
|
||||
// Expose a history that hands out fan-out subscriptions instead of the
|
||||
// single underlying one. A proxy is used so that the `location` and
|
||||
// `action` getters continue to read through to the real history object.
|
||||
this.history = new Proxy(history, {
|
||||
get: (target, prop, receiver) => {
|
||||
if (prop !== 'listen') return Reflect.get(target, prop, receiver);
|
||||
return (listener: Listener) => {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,13 +210,13 @@ export default class AppView {
|
|||
}
|
||||
|
||||
/** handle errors by showing a notification and/or the auth screen */
|
||||
handleError(error: Error, title?: string) {
|
||||
handleError(error: unknown, title?: string) {
|
||||
if (error instanceof AuthenticationError) {
|
||||
// this will automatically redirect to the auth page
|
||||
this._store.authStore.authenticated = false;
|
||||
this.notify(l('authErrorMsg'), l('authErrorTitle'));
|
||||
} else {
|
||||
this.notify(error.message, title);
|
||||
this.notify(error instanceof Error ? error.message : String(error), title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,10 @@ export default class AppStorage {
|
|||
this.set(cacheKey, { expires, data });
|
||||
log.info(`updated cache with ${keys.length} new ${cacheKey}`);
|
||||
} catch (error) {
|
||||
log.error(`failed to fetch ${cacheKey} from the API`, error.message);
|
||||
log.error(
|
||||
`failed to fetch ${cacheKey} from the API`,
|
||||
error instanceof Error ? error.message : String(error),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
4574
app/yarn.lock
4574
app/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue