├── .gitignore
├── Dockerfile
├── README.md
├── config-overrides.js
├── mime.types
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.test.tsx
├── App.tsx
├── ergo-related
│ ├── explorer.js
│ ├── rest.js
│ └── serializer.js
├── index.css
├── index.tsx
├── logo.svg
├── my-ergo-page.js
├── react-app-env.d.ts
├── reportWebVitals.ts
└── setupTests.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | .eslintcache
25 | .idea
26 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM tiangolo/node-frontend:10 as build-stage
2 | WORKDIR /app
3 | COPY package*.json /app/
4 | RUN npm install
5 | COPY ./ /app/
6 | RUN npm run build
7 | FROM nginx:1.15
8 | COPY --from=build-stage /app/build/ /usr/share/nginx/html
9 | COPY --from=build-stage /nginx.conf /etc/nginx/conf.d/default.conf
10 | COPY /mime.types /etc/nginx/mime.types
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Ergo](https://ergoplatform.org/) JS Template - Entry Point to Ergo dApp Development
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). It contains [ergo-ts](https://github.com/coinbarn/ergo-ts) and [ergo-lib](https://github.com/ergoplatform/sigma-rust) libraries as dependencies
4 | and some examples to present how to use these libraries.
5 |
6 | ## Goal
7 | The goal of this template is to bootstrap JS dApp development for Ergo Blockchain.
8 | Ergo libraries, WASM support and several examples are already available in this template.
9 | These simple examples should help devs to get on board faster and start developing their ideas right away.
10 |
11 | Since the template is structurally identical to an empty React project created by CRA,
12 | devs can simply and without any ergo-related barriers clone the project and build on top of it.
13 |
14 | ## Examples
15 | Available examples include:
16 | * Interacting with the explorer
17 | * Encoding different data types
18 | * Decoding fields (registers) of tokens
19 |
20 | These examples are simple intentionally to be newcomer-friendly. These should help you
21 | to understand how to use ergo libraries and start developing your dApp.
22 |
23 | ## Deploy Your dApp
24 | To facilitate deploying your React app, docker file is already available for this template.
25 |
26 | Just build your docker image locally using:
27 | ```bash
28 | docker build -t mydapp
29 | ```
30 | Or configure [Dockerhub](https://hub.docker.com/) to build the image automatically for you when you push to a specific branch.
31 |
32 | Then you can run/deploy your dApp easily using:
33 | ```bash
34 | docker run -p 80:80 mydapp
35 | ```
36 |
37 | ## Available Scripts
38 |
39 | In the project directory, you can run:
40 |
41 | ### `npm start`
42 |
43 | Runs the app in the development mode.\
44 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
45 |
46 | The page will reload if you make edits.\
47 | You will also see any lint errors in the console.
48 |
49 | ### `npm test`
50 |
51 | Launches the test runner in the interactive watch mode.\
52 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
53 |
54 | ### `npm run build`
55 |
56 | Builds the app for production to the `build` folder.\
57 | It correctly bundles React in production mode and optimizes the build for the best performance.
58 |
59 | The build is minified and the filenames include the hashes.\
60 | Your app is ready to be deployed!
61 |
62 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
63 |
64 | ## Learn React
65 |
66 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
67 |
68 | To learn React, check out the [React documentation](https://reactjs.org/).
69 |
--------------------------------------------------------------------------------
/config-overrides.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = function override(config, env) {
4 | const wasmExtensionRegExp = /\.wasm$/;
5 |
6 | config.resolve.extensions.push('.wasm');
7 |
8 | config.module.rules.forEach(rule => {
9 | (rule.oneOf || []).forEach(oneOf => {
10 | if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
11 | // make file-loader ignore WASM files
12 | oneOf.exclude.push(wasmExtensionRegExp);
13 | }
14 | });
15 | });
16 |
17 | // add a dedicated loader for WASM
18 | config.module.rules.push({
19 | test: wasmExtensionRegExp,
20 | include: path.resolve(__dirname, 'src'),
21 | use: [{ loader: require.resolve('wasm-loader'), options: {} }]
22 | });
23 |
24 | return config;
25 | };
26 |
--------------------------------------------------------------------------------
/mime.types:
--------------------------------------------------------------------------------
1 |
2 | types {
3 | text/html html htm shtml;
4 | text/css css;
5 | text/xml xml;
6 | image/gif gif;
7 | image/jpeg jpeg jpg;
8 | application/javascript js;
9 | application/atom+xml atom;
10 | application/rss+xml rss;
11 |
12 | text/mathml mml;
13 | text/plain txt;
14 | text/vnd.sun.j2me.app-descriptor jad;
15 | text/vnd.wap.wml wml;
16 | text/x-component htc;
17 |
18 | image/png png;
19 | image/svg+xml svg svgz;
20 | image/tiff tif tiff;
21 | image/vnd.wap.wbmp wbmp;
22 | image/webp webp;
23 | image/x-icon ico;
24 | image/x-jng jng;
25 | image/x-ms-bmp bmp;
26 |
27 | font/woff woff;
28 | font/woff2 woff2;
29 |
30 | application/wasm wasm;
31 | application/java-archive jar war ear;
32 | application/json json;
33 | application/mac-binhex40 hqx;
34 | application/msword doc;
35 | application/pdf pdf;
36 | application/postscript ps eps ai;
37 | application/rtf rtf;
38 | application/vnd.apple.mpegurl m3u8;
39 | application/vnd.google-earth.kml+xml kml;
40 | application/vnd.google-earth.kmz kmz;
41 | application/vnd.ms-excel xls;
42 | application/vnd.ms-fontobject eot;
43 | application/vnd.ms-powerpoint ppt;
44 | application/vnd.oasis.opendocument.graphics odg;
45 | application/vnd.oasis.opendocument.presentation odp;
46 | application/vnd.oasis.opendocument.spreadsheet ods;
47 | application/vnd.oasis.opendocument.text odt;
48 | application/vnd.openxmlformats-officedocument.presentationml.presentation
49 | pptx;
50 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
51 | xlsx;
52 | application/vnd.openxmlformats-officedocument.wordprocessingml.document
53 | docx;
54 | application/vnd.wap.wmlc wmlc;
55 | application/x-7z-compressed 7z;
56 | application/x-cocoa cco;
57 | application/x-java-archive-diff jardiff;
58 | application/x-java-jnlp-file jnlp;
59 | application/x-makeself run;
60 | application/x-perl pl pm;
61 | application/x-pilot prc pdb;
62 | application/x-rar-compressed rar;
63 | application/x-redhat-package-manager rpm;
64 | application/x-sea sea;
65 | application/x-shockwave-flash swf;
66 | application/x-stuffit sit;
67 | application/x-tcl tcl tk;
68 | application/x-x509-ca-cert der pem crt;
69 | application/x-xpinstall xpi;
70 | application/xhtml+xml xhtml;
71 | application/xspf+xml xspf;
72 | application/zip zip;
73 |
74 | application/octet-stream bin exe dll;
75 | application/octet-stream deb;
76 | application/octet-stream dmg;
77 | application/octet-stream iso img;
78 | application/octet-stream msi msp msm;
79 |
80 | audio/midi mid midi kar;
81 | audio/mpeg mp3;
82 | audio/ogg ogg;
83 | audio/x-m4a m4a;
84 | audio/x-realaudio ra;
85 |
86 | video/3gpp 3gpp 3gp;
87 | video/mp2t ts;
88 | video/mp4 mp4;
89 | video/mpeg mpeg mpg;
90 | video/quicktime mov;
91 | video/webm webm;
92 | video/x-flv flv;
93 | video/x-m4v m4v;
94 | video/x-mng mng;
95 | video/x-ms-asf asx asf;
96 | video/x-ms-wmv wmv;
97 | video/x-msvideo avi;
98 | }
99 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ergo-template",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "ergo-lib-wasm-browser": "^0.4.4",
7 | "@coinbarn/ergo-ts": "^0.3.0",
8 | "@testing-library/jest-dom": "^5.11.9",
9 | "@testing-library/react": "^11.2.3",
10 | "@testing-library/user-event": "^12.6.0",
11 | "@types/jest": "^26.0.20",
12 | "@types/node": "^12.19.14",
13 | "@types/react": "^16.14.2",
14 | "@types/react-dom": "^16.9.10",
15 | "react": "^17.0.1",
16 | "react-dom": "^17.0.1",
17 | "react-scripts": "4.0.1",
18 | "typescript": "^4.1.3",
19 | "web-vitals": "^0.2.4"
20 | },
21 | "scripts": {
22 | "start": "react-app-rewired start",
23 | "build": "react-app-rewired build",
24 | "test": "react-app-rewired test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": [
29 | "react-app",
30 | "react-app/jest"
31 | ]
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | },
45 | "devDependencies": {
46 | "react-app-rewired": "^2.1.8",
47 | "wasm-loader": "^1.3.0"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anon-real/ergo-js-template/2f0711027bb227152dee6bb1bc0b4f401ff13c75/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anon-real/ergo-js-template/2f0711027bb227152dee6bb1bc0b4f401ff13c75/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anon-real/ergo-js-template/2f0711027bb227152dee6bb1bc0b4f401ff13c75/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 | import {currentHeight} from "./ergo-related/explorer";
5 | import MyErgoPage from "./my-ergo-page";
6 |
7 | function App() {
8 | return (
9 |
22 | );
23 | }
24 |
25 | export default App;
26 |
--------------------------------------------------------------------------------
/src/ergo-related/explorer.js:
--------------------------------------------------------------------------------
1 | import { get } from './rest';
2 |
3 | export const trueAddress = '4MQyML64GnzMxZgm'; // dummy address to get unsigned tx from node, we only care about the boxes though in this case
4 | export const explorerApi = 'https://api.ergoplatform.com/api/v0';
5 |
6 | async function getRequest(url) {
7 | return get(explorerApi + url).then(res => {
8 | return { data: res };
9 | });
10 | }
11 |
12 | export async function currentHeight() {
13 | return getRequest('/blocks?limit=1')
14 | .then(res => res.data)
15 | .then(res => res.items[0].height);
16 | }
17 |
18 | export function unspentBoxesFor(address) {
19 | return getRequest(`/transactions/boxes/byAddress/unspent/${address}`).then(
20 | (res) => res.data
21 | );
22 | }
23 |
24 | export function boxById(id) {
25 | return getRequest(`/transactions/boxes/${id}`).then((res) => res.data);
26 | }
27 |
28 | export function txById(id) {
29 | return getRequest(`/transactions/${id}`).then((res) => res.data);
30 | }
31 |
32 | export async function getSpendingTx(boxId) {
33 | const data = getRequest(`/transactions/boxes/${boxId}`);
34 | return data
35 | .then((res) => res.data)
36 | .then((res) => res.spentTransactionId)
37 | .catch((_) => null);
38 | }
39 |
40 | export function getUnconfirmedTxsFor(addr) {
41 | return getRequest(
42 | `/transactions/unconfirmed/byAddress/${addr}`
43 | )
44 | .then((res) => res.data)
45 | .then((res) => res.items);
46 | }
47 |
48 | export function getTokenBox(addr) {
49 | return getRequest(
50 | `/assets/${addr}/issuingBox`
51 | )
52 | .then((res) => res.data[0])
53 | }
54 |
55 | export function getBalanceFor(addr, token = null) {
56 | return getRequest(
57 | `/addresses/${addr}`
58 | )
59 | .then((res) => res.data)
60 | .then((res) => res.transactions)
61 | .then(res => {
62 | if (!token) return res.confirmedBalance;
63 | let tok = res.confirmedTokensBalance.filter(tok => tok.tokenId === token);
64 | if (tok.length === 0) return 0;
65 | else return tok[0].amount;
66 | });
67 | }
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/ergo-related/rest.js:
--------------------------------------------------------------------------------
1 | export async function post(url, body = {}, apiKey = '') {
2 | return await fetch(url, {
3 | method: 'POST',
4 | headers: {
5 | Accept: 'application/json',
6 | 'Content-Type': 'application/json',
7 | api_key: apiKey,
8 | },
9 | body: JSON.stringify(body),
10 | });
11 | }
12 | export async function get(url, apiKey = '') {
13 | return await fetch(url, {
14 | headers: {
15 | Accept: 'application/json',
16 | 'Content-Type': 'application/json',
17 | api_key: apiKey,
18 | },
19 | }).then(res => res.json());
20 | }
21 |
--------------------------------------------------------------------------------
/src/ergo-related/serializer.js:
--------------------------------------------------------------------------------
1 | import {Serializer} from "@coinbarn/ergo-ts";
2 |
3 | let ergolib = import('ergo-lib-wasm-browser')
4 |
5 | export async function encodeNum(n, isInt = false) {
6 | if (isInt) return (await ergolib).Constant.from_i32(n).encode_to_base16()
7 | else return (await ergolib).Constant.from_i64((await ergolib).I64.from_str(n)).encode_to_base16()
8 | }
9 |
10 | export async function decodeNum(n, isInt = false) {
11 | if (isInt) return (await ergolib).Constant.decode_from_base16(n).to_i32()
12 | else return (await ergolib).Constant.decode_from_base16(n).to_i64().to_str()
13 |
14 | }
15 |
16 | export async function encodeHex(reg) {
17 | return (await ergolib).Constant.from_byte_array(Buffer.from(reg, 'hex')).encode_to_base16()
18 | }
19 |
20 | export async function encodeStr(str) {
21 | return encodeHex(Serializer.stringToHex(str))
22 | }
23 |
24 | function toHexString(byteArray) {
25 | return Array.from(byteArray, function(byte) {
26 | return ('0' + (byte & 0xFF).toString(16)).slice(-2);
27 | }).join('')
28 | }
29 |
30 | export async function decodeString(encoded) {
31 | return Serializer.stringFromHex(toHexString((await ergolib).Constant.decode_from_base16(encoded).to_byte_array()))
32 | }
33 |
34 | export function ergToNano(erg) {
35 | if (erg === undefined) return 0
36 | if (erg.startsWith('.')) return parseInt(erg.slice(1) + '0'.repeat(9 - erg.length + 1))
37 | let parts = erg.split('.')
38 | if (parts.length === 1) parts.push('')
39 | if (parts[1].length > 9) return 0
40 | return parseInt(parts[0] + parts[1] + '0'.repeat(9 - parts[1].length))
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/my-ergo-page.js:
--------------------------------------------------------------------------------
1 | import React, {Fragment} from 'react';
2 | import {currentHeight, getTokenBox} from "./ergo-related/explorer";
3 | import {decodeNum, decodeString, encodeNum, encodeStr} from "./ergo-related/serializer";
4 |
5 |
6 | export default class MyErgoPage extends React.Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | height: NaN,
11 | tokenId: '01004ddddd67da4b34ab2a5a99f2fed6f1f280e3289508ed5b44ae2d948279ee'
12 | };
13 | this.decodeToken = this.decodeToken.bind(this)
14 | }
15 |
16 | componentDidMount() {
17 | currentHeight().then(res => {
18 | this.setState({height: res})
19 | })
20 | this.decodeToken(this.state.tokenId)
21 | }
22 |
23 | async decodeToken(tokenId) {
24 | let box = await getTokenBox(tokenId)
25 | if (!box) return
26 | let name = await decodeString(box.additionalRegisters.R4)
27 | let description = await decodeString(box.additionalRegisters.R5)
28 | let decimals = await decodeString(box.additionalRegisters.R6)
29 | this.setState({name: name, description: description, decimals: decimals})
30 | }
31 |
32 | render() {
33 | return (
34 |
35 | Current Blockchain Height: {this.state.height}
36 |
37 | Encode Number: encodeNum(e.target.value).then(res => this.setState({encodedNum: res}))}
39 | type='number' step="1" placeholder='Enter a number'/> {this.state.encodedNum}
40 |
41 |
42 | Encode String: encodeStr(e.target.value).then(res => this.setState({encodedStr: res}))}
44 | type='text' step="1" placeholder='Enter text'/> {this.state.encodedStr}
45 |
46 |
47 | Decode Token Fields: {
51 | this.setState({tokenId: e.target.value})
52 | this.decodeToken(e.target.value)
53 | }}
54 | type='text' placeholder='Enter token ID'/>
55 |
token's name: {this.state.name}
56 | token's description: {this.state.description}
57 | token's decimals: {this.state.decimals}
58 |
59 |
60 |
61 | );
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------