+3
-1
@@ -11,6 +11,8 @@
|
|||||||
"assert",
|
"assert",
|
||||||
"buffer",
|
"buffer",
|
||||||
"crypto*",
|
"crypto*",
|
||||||
"stream*"
|
"stream*",
|
||||||
|
"env-paths",
|
||||||
|
"open"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,3 +20,11 @@ jobs:
|
|||||||
- run: npm publish --access public
|
- run: npm publish --access public
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
|
- name: Create Sentry release
|
||||||
|
uses: getsentry/action-release@v1
|
||||||
|
env:
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
with:
|
||||||
|
sourcemaps: ./build/static/js
|
||||||
|
|||||||
@@ -96,6 +96,16 @@ The Bee Dashboard runs in development mode on [http://localhost:3031/](http://lo
|
|||||||
|
|
||||||
> Setting the `REACT_APP_DEV_MODE=1` environment variable, or opening Bee Dashboard with the query string `?devMode=1` loosens some checks. This makes it possible to develop Bee Dashboard without having connected peers and chequebook properly set up, effectively supporting the dev mode of Bee itself.
|
> Setting the `REACT_APP_DEV_MODE=1` environment variable, or opening Bee Dashboard with the query string `?devMode=1` loosens some checks. This makes it possible to develop Bee Dashboard without having connected peers and chequebook properly set up, effectively supporting the dev mode of Bee itself.
|
||||||
|
|
||||||
|
#### Bee Desktop development
|
||||||
|
|
||||||
|
If you want to develop Bee Dashboard in the Bee Desktop mode, then spin up `bee-desktop` to the point where you see Bee Dashboard (eq. install Bee etc.) and:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo "REACT_APP_BEE_DESKTOP_URL=http://localhost:3000" > .env.development.local
|
||||||
|
npm start
|
||||||
|
npm run desktop # This will inject the API key to the Dashboard
|
||||||
|
```
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
There are some ways you can make this module better:
|
There are some ways you can make this module better:
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import envPaths from 'env-paths'
|
||||||
|
import open from 'open'
|
||||||
|
|
||||||
|
import { readFile } from 'node:fs/promises'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
|
||||||
|
const paths = envPaths('bee-desktop')
|
||||||
|
const apiKey = await readFile(join(paths.data, 'api-key.txt'), {encoding: 'utf-8'})
|
||||||
|
const url = `http://localhost:3001/?v=${apiKey}#/`
|
||||||
|
|
||||||
|
console.log('Opening: ' + url)
|
||||||
|
await open(url)
|
||||||
Generated
+185
-1
@@ -15,6 +15,8 @@
|
|||||||
"@material-ui/core": "4.12.3",
|
"@material-ui/core": "4.12.3",
|
||||||
"@material-ui/icons": "4.11.2",
|
"@material-ui/icons": "4.11.2",
|
||||||
"@material-ui/lab": "4.0.0-alpha.57",
|
"@material-ui/lab": "4.0.0-alpha.57",
|
||||||
|
"@sentry/react": "^7.1.1",
|
||||||
|
"@sentry/tracing": "^7.1.1",
|
||||||
"assert": "^2.0.0",
|
"assert": "^2.0.0",
|
||||||
"axios": "0.24.0",
|
"axios": "0.24.0",
|
||||||
"bignumber.js": "9.0.1",
|
"bignumber.js": "9.0.1",
|
||||||
@@ -78,6 +80,7 @@
|
|||||||
"babel-plugin-tsconfig-paths": "1.0.2",
|
"babel-plugin-tsconfig-paths": "1.0.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"depcheck": "^1.4.3",
|
"depcheck": "^1.4.3",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
"eslint": "8.17.0 ",
|
"eslint": "8.17.0 ",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-config-react-app": "7.0.1",
|
"eslint-config-react-app": "7.0.1",
|
||||||
@@ -91,6 +94,7 @@
|
|||||||
"eslint-plugin-testing-library": "5.5.1",
|
"eslint-plugin-testing-library": "5.5.1",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
|
"open": "^8.4.0",
|
||||||
"prettier": "2.4.1",
|
"prettier": "2.4.1",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"ts-node": "^10.8.1",
|
"ts-node": "^10.8.1",
|
||||||
@@ -102,7 +106,7 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"bee": ">=0.6.0",
|
"bee": ">=0.6.0",
|
||||||
"node": ">=12.0.0",
|
"node": ">=12.0.0",
|
||||||
"npm": ">=6.0.0"
|
"npm": ">=6.9.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">= 17.0.2",
|
"react": ">= 17.0.2",
|
||||||
@@ -4168,6 +4172,99 @@
|
|||||||
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@sentry/browser": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5AQvStZ+nOP/yxsBmeMZpeGLVtuOgnCNvswKd/c1CJwNw7bDmCE4TQeNKp1C3Gb7lSdBk8ViwUKn0ZpoVQ5MTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/core": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/core": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-SADdAoG5u1LTJhPN5KPtn5HHmH6r0mr6h2LokuZnhj6/okrAuCIIKOb6Fh8jV7j2VuABvew8+FjJHORxi7D/3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/hub": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/hub": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-ASsRVjYDIii6ZTf36JnIYKHWBQBk0P42Tgq324MpyPgaeVDg3saBcyXO5iAtWvY6Vmdi2H4JCVDoir2Zz3Me1w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/react": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-Z7cZvXHIWxg7OhOSy4InhrRgQPRNtHsyOkIAHkgwW32JYOGTg1HdqQ5mFUxQLejhU/YqsxVjTK4CI58FATykLw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/browser": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "15.x || 16.x || 17.x || 18.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/tracing": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-MJ+EPGfvPlgbJOcZRoIl6+Oi0oRE2nIi/HP2BPJSKGxXFi2Y09bcZUwfxOH8fkUa465jOGBFdCm+sXcbyExvuw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/hub": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/types": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5N1UMd2SqvUXprcIUMyDEju3H9lJY2oWfWQBGo0lG6Amn/lGAPAYlchg+4vQCLutDQMyd8K9zPwcbKn4u6gHdw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/utils": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-DPRHDf3InfyVgmxToE4Z+AATAR4OVm+wsXDLFGGyncR91CE1x4wLQKOcAJJwX3F0Hz1VHENfmx1DvyYTHOrC/A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sinclair/typebox": {
|
"node_modules/@sinclair/typebox": {
|
||||||
"version": "0.23.5",
|
"version": "0.23.5",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
|
||||||
@@ -8696,6 +8793,18 @@
|
|||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/env-paths": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/envinfo": {
|
"node_modules/envinfo": {
|
||||||
"version": "7.8.1",
|
"version": "7.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
||||||
@@ -23212,6 +23321,75 @@
|
|||||||
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@sentry/browser": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5AQvStZ+nOP/yxsBmeMZpeGLVtuOgnCNvswKd/c1CJwNw7bDmCE4TQeNKp1C3Gb7lSdBk8ViwUKn0ZpoVQ5MTw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/core": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/core": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-SADdAoG5u1LTJhPN5KPtn5HHmH6r0mr6h2LokuZnhj6/okrAuCIIKOb6Fh8jV7j2VuABvew8+FjJHORxi7D/3Q==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/hub": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/hub": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-ASsRVjYDIii6ZTf36JnIYKHWBQBk0P42Tgq324MpyPgaeVDg3saBcyXO5iAtWvY6Vmdi2H4JCVDoir2Zz3Me1w==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/react": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-Z7cZvXHIWxg7OhOSy4InhrRgQPRNtHsyOkIAHkgwW32JYOGTg1HdqQ5mFUxQLejhU/YqsxVjTK4CI58FATykLw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/browser": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/tracing": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-MJ+EPGfvPlgbJOcZRoIl6+Oi0oRE2nIi/HP2BPJSKGxXFi2Y09bcZUwfxOH8fkUa465jOGBFdCm+sXcbyExvuw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/hub": "7.1.1",
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"@sentry/utils": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/types": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5N1UMd2SqvUXprcIUMyDEju3H9lJY2oWfWQBGo0lG6Amn/lGAPAYlchg+4vQCLutDQMyd8K9zPwcbKn4u6gHdw=="
|
||||||
|
},
|
||||||
|
"@sentry/utils": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-DPRHDf3InfyVgmxToE4Z+AATAR4OVm+wsXDLFGGyncR91CE1x4wLQKOcAJJwX3F0Hz1VHENfmx1DvyYTHOrC/A==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "7.1.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sinclair/typebox": {
|
"@sinclair/typebox": {
|
||||||
"version": "0.23.5",
|
"version": "0.23.5",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz",
|
||||||
@@ -26766,6 +26944,12 @@
|
|||||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
|
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"env-paths": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"envinfo": {
|
"envinfo": {
|
||||||
"version": "7.8.1",
|
"version": "7.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
||||||
|
|||||||
+6
-1
@@ -32,12 +32,14 @@
|
|||||||
"@material-ui/core": "4.12.3",
|
"@material-ui/core": "4.12.3",
|
||||||
"@material-ui/icons": "4.11.2",
|
"@material-ui/icons": "4.11.2",
|
||||||
"@material-ui/lab": "4.0.0-alpha.57",
|
"@material-ui/lab": "4.0.0-alpha.57",
|
||||||
|
"@sentry/react": "^7.1.1",
|
||||||
|
"@sentry/tracing": "^7.1.1",
|
||||||
"assert": "^2.0.0",
|
"assert": "^2.0.0",
|
||||||
"axios": "0.24.0",
|
"axios": "0.24.0",
|
||||||
"bignumber.js": "9.0.1",
|
"bignumber.js": "9.0.1",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"crypto-browserify": "^3.12.0",
|
|
||||||
"crypto": "npm:crypto-browserify",
|
"crypto": "npm:crypto-browserify",
|
||||||
|
"crypto-browserify": "^3.12.0",
|
||||||
"ethereumjs-wallet": "^1.0.2",
|
"ethereumjs-wallet": "^1.0.2",
|
||||||
"ethers": "^5.6.4",
|
"ethers": "^5.6.4",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
@@ -92,6 +94,7 @@
|
|||||||
"babel-plugin-tsconfig-paths": "1.0.2",
|
"babel-plugin-tsconfig-paths": "1.0.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"depcheck": "^1.4.3",
|
"depcheck": "^1.4.3",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
"eslint": "8.17.0 ",
|
"eslint": "8.17.0 ",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-config-react-app": "7.0.1",
|
"eslint-config-react-app": "7.0.1",
|
||||||
@@ -105,6 +108,7 @@
|
|||||||
"eslint-plugin-testing-library": "5.5.1",
|
"eslint-plugin-testing-library": "5.5.1",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
|
"open": "^8.4.0",
|
||||||
"prettier": "2.4.1",
|
"prettier": "2.4.1",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"ts-node": "^10.8.1",
|
"ts-node": "^10.8.1",
|
||||||
@@ -120,6 +124,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
"desktop": "node ./desktop.mjs",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"build:component": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' webpack --mode=production",
|
"build:component": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' webpack --mode=production",
|
||||||
"compile:types": "tsc --project tsconfig.lib.json --emitDeclarationOnly --declaration",
|
"compile:types": "tsc --project tsconfig.lib.json --emitDeclarationOnly --declaration",
|
||||||
|
|||||||
+50
-2
@@ -3,6 +3,8 @@ import { ThemeProvider } from '@material-ui/core/styles'
|
|||||||
import { SnackbarProvider } from 'notistack'
|
import { SnackbarProvider } from 'notistack'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { HashRouter as Router } from 'react-router-dom'
|
import { HashRouter as Router } from 'react-router-dom'
|
||||||
|
import * as Sentry from '@sentry/react'
|
||||||
|
import { BrowserTracing } from '@sentry/tracing'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import Dashboard from './layout/Dashboard'
|
import Dashboard from './layout/Dashboard'
|
||||||
import { Provider as BeeProvider } from './providers/Bee'
|
import { Provider as BeeProvider } from './providers/Bee'
|
||||||
@@ -14,6 +16,10 @@ import { Provider as StampsProvider } from './providers/Stamps'
|
|||||||
import { Provider as TopUpProvider } from './providers/TopUp'
|
import { Provider as TopUpProvider } from './providers/TopUp'
|
||||||
import BaseRouter from './routes'
|
import BaseRouter from './routes'
|
||||||
import { theme } from './theme'
|
import { theme } from './theme'
|
||||||
|
import { config } from './config'
|
||||||
|
import { getBeeDesktopLogs, getBeeLogs } from './utils/desktop'
|
||||||
|
import packageJson from '../package.json'
|
||||||
|
import ItsBroken from './layout/ItsBroken'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
beeApiUrl?: string
|
beeApiUrl?: string
|
||||||
@@ -21,7 +27,34 @@ interface Props {
|
|||||||
lockedApiSettings?: boolean
|
lockedApiSettings?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = ({ beeApiUrl, beeDebugApiUrl, lockedApiSettings }: Props): ReactElement => (
|
if (config.SENTRY_KEY) {
|
||||||
|
Sentry.init({
|
||||||
|
dsn: config.SENTRY_KEY,
|
||||||
|
release: packageJson.version,
|
||||||
|
integrations: [new BrowserTracing({ tracingOrigins: ['localhost'] })],
|
||||||
|
tracesSampleRate: 1.0,
|
||||||
|
beforeSend: async (event, hint) => {
|
||||||
|
hint.attachments = []
|
||||||
|
|
||||||
|
try {
|
||||||
|
// This will fail if we are not running in Bee Desktop, but that is alright
|
||||||
|
hint.attachments.push({ filename: 'bee-desktop.log', data: await getBeeDesktopLogs() })
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// This will fail if we are not running in Bee Desktop, but that is alright
|
||||||
|
hint.attachments.push({ filename: 'bee.log', data: await getBeeLogs() })
|
||||||
|
// eslint-disable-next-line no-empty
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
return event
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const App = ({ beeApiUrl, beeDebugApiUrl, lockedApiSettings }: Props): ReactElement => {
|
||||||
|
const mainApp = (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<SettingsProvider beeApiUrl={beeApiUrl} beeDebugApiUrl={beeDebugApiUrl} lockedApiSettings={lockedApiSettings}>
|
<SettingsProvider beeApiUrl={beeApiUrl} beeDebugApiUrl={beeDebugApiUrl} lockedApiSettings={lockedApiSettings}>
|
||||||
@@ -50,6 +83,21 @@ const App = ({ beeApiUrl, beeDebugApiUrl, lockedApiSettings }: Props): ReactElem
|
|||||||
</SettingsProvider>
|
</SettingsProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Displays Report Dialog when some component crashes
|
||||||
|
if (config.SENTRY_KEY) {
|
||||||
|
return (
|
||||||
|
<Sentry.ErrorBoundary
|
||||||
|
showDialog
|
||||||
|
fallback={({ error, componentStack, resetError }) => <ItsBroken message={error.message} />}
|
||||||
|
>
|
||||||
|
{mainApp}
|
||||||
|
</Sentry.ErrorBoundary>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mainApp
|
||||||
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Component, ErrorInfo, ReactElement } from 'react'
|
import { Component, ErrorInfo, ReactElement } from 'react'
|
||||||
|
import ItsBroken from '../layout/ItsBroken'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: ReactElement
|
children: ReactElement
|
||||||
@@ -26,8 +27,7 @@ export default class ErrorBoundary extends Component<Props, State> {
|
|||||||
|
|
||||||
render(): ReactElement {
|
render(): ReactElement {
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
// You can render any custom fallback UI
|
return <ItsBroken message={this.state.error.message} />
|
||||||
return <h1>Something went wrong. Error: {this.state.error.message}</h1>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.props.children
|
return this.props.children
|
||||||
|
|||||||
+9
-13
@@ -1,7 +1,3 @@
|
|||||||
function getProcessEnv(key: string): string | undefined | false {
|
|
||||||
return typeof process === 'object' && process.env[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public readonly BEE_API_HOST: string
|
public readonly BEE_API_HOST: string
|
||||||
public readonly BEE_DEBUG_API_HOST: string
|
public readonly BEE_DEBUG_API_HOST: string
|
||||||
@@ -10,19 +6,19 @@ class Config {
|
|||||||
public readonly BEE_DISCORD_HOST: string
|
public readonly BEE_DISCORD_HOST: string
|
||||||
public readonly GITHUB_REPO_URL: string
|
public readonly GITHUB_REPO_URL: string
|
||||||
public readonly BEE_DESKTOP_URL: string
|
public readonly BEE_DESKTOP_URL: string
|
||||||
|
public readonly SENTRY_KEY: string | undefined
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.BEE_API_HOST =
|
this.BEE_API_HOST = sessionStorage.getItem('api_host') ?? process.env.REACT_APP_BEE_HOST ?? 'http://localhost:1633'
|
||||||
sessionStorage.getItem('api_host') || getProcessEnv('REACT_APP_BEE_HOST') || 'http://localhost:1633'
|
this.SENTRY_KEY = process.env.REACT_APP_SENTRY_KEY
|
||||||
this.BEE_DEBUG_API_HOST =
|
this.BEE_DEBUG_API_HOST =
|
||||||
sessionStorage.getItem('debug_api_host') || getProcessEnv('REACT_APP_BEE_DEBUG_HOST') || 'http://localhost:1635'
|
sessionStorage.getItem('debug_api_host') ?? process.env.REACT_APP_BEE_DEBUG_HOST ?? 'http://localhost:1635'
|
||||||
this.BLOCKCHAIN_EXPLORER_URL =
|
this.BLOCKCHAIN_EXPLORER_URL =
|
||||||
getProcessEnv('REACT_APP_BLOCKCHAIN_EXPLORER_URL') || 'https://blockscout.com/xdai/mainnet'
|
process.env.REACT_APP_BLOCKCHAIN_EXPLORER_URL ?? 'https://blockscout.com/xdai/mainnet'
|
||||||
this.BEE_DOCS_HOST = getProcessEnv('REACT_APP_BEE_DOCS_HOST') || 'https://docs.ethswarm.org/docs/'
|
this.BEE_DOCS_HOST = process.env.REACT_APP_BEE_DOCS_HOST ?? 'https://docs.ethswarm.org/docs/'
|
||||||
this.BEE_DISCORD_HOST = getProcessEnv('REACT_APP_BEE_DISCORD_HOST') || 'https://discord.gg/eKr9XPv7'
|
this.BEE_DISCORD_HOST = process.env.REACT_APP_BEE_DISCORD_HOST ?? 'https://discord.gg/eKr9XPv7'
|
||||||
this.GITHUB_REPO_URL =
|
this.GITHUB_REPO_URL = process.env.REACT_APP_BEE_GITHUB_REPO_URL ?? 'https://api.github.com/repos/ethersphere/bee'
|
||||||
getProcessEnv('REACT_APP_BEE_GITHUB_REPO_URL') || 'https://api.github.com/repos/ethersphere/bee'
|
this.BEE_DESKTOP_URL = process.env.REACT_APP_BEE_DESKTOP_URL ?? window.location.origin
|
||||||
this.BEE_DESKTOP_URL = getProcessEnv('REACT_APP_BEE_DESKTOP_URL') || window.location.origin
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { CircularProgress, Container } from '@material-ui/core'
|
import { CircularProgress, Container } from '@material-ui/core'
|
||||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
||||||
import { ReactElement, useContext } from 'react'
|
import React, { ReactElement, useContext } from 'react'
|
||||||
import ErrorBoundary from '../components/ErrorBoundary'
|
import ErrorBoundary from '../components/ErrorBoundary'
|
||||||
import SideBar from '../components/SideBar'
|
import SideBar from '../components/SideBar'
|
||||||
import { Context } from '../providers/Bee'
|
import { Context } from '../providers/Bee'
|
||||||
|
import config from '../config'
|
||||||
|
import * as Sentry from '@sentry/react'
|
||||||
|
import ItsBroken from './ItsBroken'
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
@@ -22,12 +25,7 @@ const Dashboard = (props: Props): ReactElement => {
|
|||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
const { isLoading } = useContext(Context)
|
const { isLoading } = useContext(Context)
|
||||||
|
const content = (
|
||||||
return (
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<SideBar />
|
|
||||||
<Container className={classes.content}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<>
|
<>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div style={{ textAlign: 'center', width: '100%' }}>
|
<div style={{ textAlign: 'center', width: '100%' }}>
|
||||||
@@ -37,8 +35,27 @@ const Dashboard = (props: Props): ReactElement => {
|
|||||||
props.children
|
props.children
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
</ErrorBoundary>
|
)
|
||||||
</Container>
|
|
||||||
|
let errorBoundaryWithContent
|
||||||
|
|
||||||
|
if (config.SENTRY_KEY) {
|
||||||
|
errorBoundaryWithContent = (
|
||||||
|
<Sentry.ErrorBoundary
|
||||||
|
showDialog
|
||||||
|
fallback={({ error, componentStack, resetError }) => <ItsBroken message={error.message} />}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</Sentry.ErrorBoundary>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
errorBoundaryWithContent = <ErrorBoundary>{content}</ErrorBoundary>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex' }}>
|
||||||
|
<SideBar />
|
||||||
|
<Container className={classes.content}>{errorBoundaryWithContent}</Container>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Container } from '@material-ui/core'
|
||||||
|
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
||||||
|
import { ReactElement } from 'react'
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
|
createStyles({
|
||||||
|
content: {
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
minHeight: '100vh',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
errorMsg: {
|
||||||
|
marginTop: '30px',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Provide some nicer design
|
||||||
|
const ItsBroken = ({ message }: Props): ReactElement => {
|
||||||
|
const classes = useStyles()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Container className={classes.content}>
|
||||||
|
<h1>Ups, there was a problem 😅</h1>
|
||||||
|
<h3 className={classes.errorMsg}>Error: {message}</h3>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ItsBroken
|
||||||
+23
-7
@@ -1,5 +1,5 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { getJson, postJson } from './net'
|
import { getJson, postJson, sendRequest } from './net'
|
||||||
|
|
||||||
interface DesktopStatus {
|
interface DesktopStatus {
|
||||||
status: 0 | 1 | 2
|
status: 0 | 1 | 2
|
||||||
@@ -9,7 +9,7 @@ interface DesktopStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getDesktopStatus(): Promise<DesktopStatus> {
|
export async function getDesktopStatus(): Promise<DesktopStatus> {
|
||||||
const response = await getJson(`http://${getDesktopHost()}/status`)
|
const response = await getJson(`${getDesktopHost()}/status`)
|
||||||
|
|
||||||
return response as DesktopStatus
|
return response as DesktopStatus
|
||||||
}
|
}
|
||||||
@@ -33,21 +33,37 @@ export async function setJsonRpcInDesktop(value: string): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateDesktopConfiguration(values: Record<string, unknown>): Promise<void> {
|
async function updateDesktopConfiguration(values: Record<string, unknown>): Promise<void> {
|
||||||
await postJson(`http://${getDesktopHost()}/config`, values)
|
await postJson(`${getDesktopHost()}/config`, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function restartBeeNode(): Promise<void> {
|
export async function restartBeeNode(): Promise<void> {
|
||||||
await postJson(`http://${getDesktopHost()}/restart`)
|
await postJson(`${getDesktopHost()}/restart`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createGiftWallet(address: string): Promise<void> {
|
export async function createGiftWallet(address: string): Promise<void> {
|
||||||
await postJson(`http://${getDesktopHost()}/gift-wallet/${address}`)
|
await postJson(`${getDesktopHost()}/gift-wallet/${address}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function performSwap(daiAmount: string): Promise<void> {
|
export async function performSwap(daiAmount: string): Promise<void> {
|
||||||
await postJson(`http://${getDesktopHost()}/swap`, { dai: daiAmount })
|
await postJson(`${getDesktopHost()}/swap`, { dai: daiAmount })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBeeDesktopLogs(): Promise<string> {
|
||||||
|
const response = await sendRequest(`${getDesktopHost()}/logs/bee-desktop`, 'GET')
|
||||||
|
|
||||||
|
return response as unknown as string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBeeLogs(): Promise<string> {
|
||||||
|
const response = await sendRequest(`${getDesktopHost()}/logs/bee`, 'GET')
|
||||||
|
|
||||||
|
return response as unknown as string
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDesktopHost(): string {
|
function getDesktopHost(): string {
|
||||||
return window.location.host
|
if (process.env.REACT_APP_BEE_DESKTOP_URL) {
|
||||||
|
return process.env.REACT_APP_BEE_DESKTOP_URL
|
||||||
|
}
|
||||||
|
|
||||||
|
return `http://${window.location.host}`
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ export function postJson(url: string, data?: Record<string, any>): Promise<Recor
|
|||||||
return sendRequest(url, 'POST', data)
|
return sendRequest(url, 'POST', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendRequest(
|
export async function sendRequest(
|
||||||
url: string,
|
url: string,
|
||||||
method: 'GET' | 'POST',
|
method: 'GET' | 'POST',
|
||||||
data?: Record<string, unknown>,
|
data?: Record<string, unknown>,
|
||||||
|
|||||||
Reference in New Issue
Block a user