├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── main.yml
│ ├── publish.yml
│ ├── pull_request.yml
│ └── pull_request_dependabot.yml
├── .gitignore
├── .husky
└── pre-commit
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.js
├── dist
├── index.min.js
└── index.min.js.map
├── example
├── node
│ ├── index.ts
│ ├── package-lock.json
│ └── package.json
├── vanilla-minimal
│ └── index.html
└── vanilla-vite
│ ├── .gitignore
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ └── vite.svg
│ ├── src
│ ├── counter.ts
│ ├── main.ts
│ ├── style.css
│ ├── typescript.svg
│ └── vite-env.d.ts
│ └── tsconfig.json
├── lib
├── contract-verifier-ui.d.ts
├── contract-verifier-ui.js
├── contract-verifier-ui.js.map
├── contract-verifier.d.ts
├── contract-verifier.js
├── contract-verifier.js.map
├── dom.d.ts
├── dom.js
├── dom.js.map
├── file-structure.d.ts
├── file-structure.js
├── file-structure.js.map
├── index.d.ts
├── index.js
├── index.js.map
├── web.d.ts
├── web.js
└── web.js.map
├── package-lock.json
├── package.json
├── src
└── lib
│ ├── contract-verifier-ui.ts
│ ├── contract-verifier.ts
│ ├── declaration.d.ts
│ ├── dom.ts
│ ├── file-structure.ts
│ ├── index.ts
│ ├── res
│ ├── file-black.svg
│ ├── file-white.svg
│ ├── folder-closed-black.svg
│ ├── folder-closed-white.svg
│ ├── folder-open-black.svg
│ └── folder-open-white.svg
│ ├── style.css
│ └── web.ts
├── tsconfig.json
└── tslint.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: https://hge.to/thanks
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "04:00"
8 | timezone: America/Montreal
9 | open-pull-requests-limit: 10
10 | versioning-strategy: increase
11 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | paths-ignore:
6 | - README.md
7 | - .gitignore
8 | - .github/**
9 |
10 | jobs:
11 | build:
12 | runs-on: ${{ matrix.os }}
13 | strategy:
14 | matrix:
15 | node-version: [12.x]
16 | os: [ubuntu-latest]
17 | steps:
18 | - uses: actions/checkout@v1
19 | - name: Use Node.js ${{ matrix.node_version }}
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: ${{ matrix.node_version }}
23 | - name: npm install, build, and test
24 | run: |
25 | npm install
26 | npm run test
27 | env:
28 | CI: true
29 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | paths-ignore:
8 | - README.md
9 | - .gitignore
10 | - .github/**
11 |
12 | jobs:
13 | publish:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v1
17 | - uses: actions/setup-node@v1
18 | with:
19 | node-version: 12
20 | - run: npm install
21 | - run: npm run test -- --coverage --watchAll=false
22 |
23 | - name: Setup GIT
24 | run: |
25 | git reset --hard
26 | git config --local --list
27 | git checkout master
28 | git config user.email "$GH_EMAIL"
29 | git config user.name "Francisco Hodge"
30 | env:
31 | GH_EMAIL: ${{secrets.GH_EMAIL}}
32 |
33 | - name: Bump version
34 | run: |
35 | git reset --hard
36 | npm version patch
37 | npm run build
38 | git add . || true
39 | git commit -m "Build update" || true
40 | git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY"
41 | env:
42 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
43 |
44 | - name: npm publish
45 | run: |
46 | npm config set //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN
47 | npm run trypublish
48 | env:
49 | NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
50 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yml:
--------------------------------------------------------------------------------
1 | name: Build PR (Standard)
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | build:
7 | runs-on: ${{ matrix.os }}
8 | if: ${{ github.actor != 'dependabot[bot]' }}
9 | strategy:
10 | matrix:
11 | node-version: [12.x]
12 | os: [ubuntu-latest]
13 | steps:
14 | - uses: actions/checkout@v1
15 | - name: Use Node.js ${{ matrix.node_version }}
16 | uses: actions/setup-node@v1
17 | with:
18 | node-version: ${{ matrix.node_version }}
19 | - name: npm install, build, and test
20 | run: |
21 | npm install
22 | npm run test
23 | env:
24 | CI: true
25 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request_dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Build PR (Dependabot)
2 |
3 | on: pull_request_target
4 |
5 | jobs:
6 | build:
7 | runs-on: ${{ matrix.os }}
8 | if: ${{ github.actor == 'dependabot[bot]' }}
9 | strategy:
10 | matrix:
11 | node-version: [12.x]
12 | os: [ubuntu-latest]
13 | steps:
14 | - uses: actions/checkout@v2
15 | with:
16 | ref: ${{ github.event.pull_request.head.sha }}
17 | - name: Use Node.js ${{ matrix.node_version }}
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: ${{ matrix.node_version }}
21 | - name: npm install, build, and test
22 | run: |
23 | npm install
24 | npm run test
25 | env:
26 | CI: true
27 | - name: Merge PR
28 | if: success()
29 | uses: "actions/github-script@v2"
30 | with:
31 | github-token: "${{ secrets.GH_KEY }}"
32 | script: |
33 | const pullRequest = context.payload.pull_request
34 | const repository = context.repo
35 |
36 | await github.pulls.merge({
37 | merge_method: "merge",
38 | owner: repository.owner,
39 | pull_number: pullRequest.number,
40 | repo: repository.repo,
41 | })
42 | - name: Reject PR
43 | if: failure()
44 | uses: peter-evans/close-pull@v1
45 | with:
46 | pull-request-number: ${{github.event.number}}
47 | comment: "Closing PR due to failing tests."
48 | delete-branch: true
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | temp
3 | .DS_Store
4 | *.tgz
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npm run format
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /tests
6 | /coverage
7 |
8 | # docs
9 | /docs
10 |
11 | # misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 | /.github
18 | /demo
19 | .esdoc.json
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # Development folders and files
26 | public
27 | src
28 | scripts
29 | config
30 | .travis.yml
31 | CHANGELOG.md
32 | README.md
33 | webpack.config.js
34 | babel.config.js
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [1.1.1] - 2023-04-18
11 |
12 | ### Changed
13 | - Modified `FuncCompilerVersion` type to be a string to ease future version support
14 |
15 | ## [1.1.0] - 2023-03-12
16 |
17 | ### Added
18 |
19 | - Added testnet support:
20 | - getSourcesJsonUrl - `options` now accept a `testnet` parameter
21 | - getSourcesData - (Breaking) `options` now accepts an `option` parameter, which takes a custom `ipfsConverter` function and `testnet` parameters
22 |
23 | ### Fixed
24 |
25 | - None
26 |
27 | ### Changed
28 |
29 | - None
30 |
31 | ### Removed
32 |
33 | - None
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Orbs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TON Contract Verifier SDK
2 |
3 | ## TL;DR
4 | TON verifier data fetcher and code viewer with FunC code highlighting
5 |
6 | ## Related repositories
7 |
8 | This repo is a part of the following:
9 |
10 | 1. [contract-verifier-contracts](https://github.com/ton-community/contract-verifier-contracts) - Sources registry contracts which stores an on-chain proof per code cell hash.
11 | 2. [contract-verifier-backend](https://github.com/ton-community/contract-verifier-backend) - Backend for compiling FunC and returning a signature over a message containing the resulting code cell hash.
12 | 3. [contract-verifier-sdk](https://github.com/ton-community/contract-verifier-sdk) (this repo) - A UI component to fetch and display sources from TON blockchain and IPFS, including FunC code highlighting.
13 | 4. [contract-verifier](https://github.com/ton-community/contract-verifier) - A UI app to interact with the backend, contracts and publish an on-chain proof.
14 |
15 | ## ⭐️ Features
16 | - Queries the Sources Registry for the existence of a Source Item contract
17 | - Fetches contract source code from IPFS via a sources.json url
18 | - Displays a code navigator with code highlighting for FunC, FIFT, based on [highlight.js plugin](https://github.com/highlightjs/highlightjs-func)
19 | - Customizable data fetching (IPFS GW, TON API endpoint, verifier id)
20 |
21 | ## 📦 Getting Started
22 |
23 | ### Step 1: Prepare DOM ###
24 | Add this to your HTML structure
25 | ```html
26 |
32 | ```
33 |
34 | ### Installation
35 |
36 | #### NPM
37 | ```
38 | npm install @ton-community/contract-verifier-sdk
39 | ```
40 |
41 | #### Web CDN
42 | ```
43 |
44 | ```
45 |
46 | ### Usage
47 |
48 | #### Node
49 | ```typescript
50 | import { ContractVerifier } from "@ton-community/contract-verifier-sdk";
51 |
52 | const ipfsLink = await ContractVerifier.getSourcesJsonUrl(
53 | "45cE5NYJuT5l2bJ+HfRI0hUhR3LsBI6wER6yralqPyY=",
54 | {
55 | testnet: false
56 | }
57 | );
58 |
59 | const src = await ContractVerifier.getSourcesData(ipfsLink!, {testnet: false});
60 |
61 | // use contract data
62 | ```
63 |
64 | #### Browser
65 | ```html
66 |
87 | ```
88 |
89 | ## ℹ️ Interface
90 |
91 | ### ContractVerifier
92 | ```typescript
93 | interface GetSourcesOptions {
94 | verifier?: string, // Defaults to "orbs.com"
95 | httpApiEndpointV4?: string, // Defaults to an Orbs L3 TON Gateway
96 | testnet?: boolean
97 | }
98 |
99 | // Returns an `ipfs://` prefixed URL if the given code cell hash has a corresponding source verifier contract
100 | async ContractVerifier.getSourcesJsonUrl(codeCellHash: string, options?: GetSourcesOptions): Promise;
101 |
102 |
103 | interface SourcesData {
104 | files: { name: string; content: string }[];
105 | commandLine: string;
106 | compiler: string;
107 | version: string;
108 | verificationDate: Date;
109 | }
110 | type IpfsUrlConverterFunc (ipfsUrl: string) => string;
111 |
112 | // Returns file names and their source code content
113 | async ContractVerifier.getSourcesData(sourcesJsonUrl: string, options?: {
114 | ipfsConverter?: IpfsUrlConverterFunc;
115 | testnet?: boolean;
116 | }): Promise;
117 | ```
118 |
119 | ### ContractVerifierUI
120 |
121 | ```typescript
122 | ContractVerifierUI.loadSourcesData(sourcesData: SourcesData, opts: {
123 | containerSelector: string; // main container
124 | fileListSelector?: string; // if omitted, the file list will not be populated and the setCode function can be used instead to switch between files
125 | contentSelector: string; // code container
126 | theme: Theme; // "light" or "dark"
127 | });
128 |
129 | // To be used usually only if the file list is manually built
130 | ContractVerifierUI.setCode(contentSelector: string, content: string);
131 | ```
132 |
133 | ## 👀 Demo
134 | 1. Clone this repo
135 | 2. Run `npm install`
136 | 3. Run `npm run build`
137 |
138 | ### Web - Minimal
139 | 1. Navigate to `example/vanilla-minimal`
140 | 4. Open `index.html`
141 |
142 | ### Web - Vanilla
143 | 1. Navigate to `example/vanilla-vite`
144 | 2. Run `npm install`
145 | 3. Run `npm link ../../`
146 | 4. Run `npm run dev`
147 |
148 | ### Node.js
149 | 1. Navigate to `example/node`
150 | 2. Run `npm install`
151 | 3. Run `npm link ../../`
152 | 4. Run `ts-node index.ts`
153 |
154 | ## 💎 Customization
155 |
156 | ### CSS
157 | The widget will attach the following classnames to its components:
158 | ```
159 | contract-verifier-container
160 | contract-verifier-files
161 | contract-verifier-file
162 | contract-verifier-code
163 | ```
164 |
165 | Which can be customized according to your needs.
166 |
167 | ## 📔 License
168 | MIT
169 |
--------------------------------------------------------------------------------
/build.js:
--------------------------------------------------------------------------------
1 | let StyleLoader = {
2 | name: "inline-style",
3 | setup({ onLoad }) {
4 | let fs = require("fs");
5 | onLoad({ filter: /\.css$/ }, async (args) => {
6 | let css = await fs.promises.readFile(args.path, "utf8");
7 | return { contents: css, loader: "text" };
8 | });
9 | },
10 | };
11 |
12 | let SVGLoader = {
13 | name: "svg",
14 | setup({ onLoad }) {
15 | let fs = require("fs");
16 | onLoad({ filter: /\.svg$/ }, async (args) => {
17 | let svg = await fs.promises.readFile(args.path, "utf8");
18 | return { contents: svg, loader: "text" };
19 | });
20 | },
21 | };
22 |
23 | const { polyfillNode } = require("esbuild-plugin-polyfill-node");
24 |
25 | (async () => {
26 | await require("esbuild")
27 | .build({
28 | plugins: [polyfillNode(), StyleLoader, SVGLoader],
29 | entryPoints: ["./src/lib/web.ts"],
30 | bundle: true,
31 | target: "ES2020",
32 | outfile: "./dist/index.min.js",
33 | sourcemap: true,
34 | minify: true,
35 | })
36 | .catch(() => process.exit(1));
37 | })();
38 |
--------------------------------------------------------------------------------
/example/node/index.ts:
--------------------------------------------------------------------------------
1 | import { ContractVerifier } from "@ton-community/contract-verifier-sdk";
2 |
3 | (async () => {
4 | console.log("Fetching IPFS Link")
5 | const ipfsLink = await ContractVerifier.getSourcesJsonUrl(
6 | "45cE5NYJuT5l2bJ+HfRI0hUhR3LsBI6wER6yralqPyY="
7 | );
8 |
9 | console.log(`Got: ${ipfsLink}. Fetching JSON and sources.\n`)
10 |
11 | const src = await ContractVerifier.getSourcesData(ipfsLink!);
12 |
13 | console.log({
14 | ...src,
15 | files: src.files.map(({ name, content }) => ({
16 | name,
17 | content: content.slice(0, 50) + "...",
18 | })),
19 | });
20 | })();
21 |
--------------------------------------------------------------------------------
/example/node/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "node",
9 | "version": "1.0.0",
10 | "license": "ISC"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/vanilla-minimal/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
33 |
34 |
35 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/vanilla-vite/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/example/vanilla-vite/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/vanilla-vite/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "0.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "example",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "@ton-community/contract-verifier-sdk": "file:../.."
12 | },
13 | "devDependencies": {
14 | "typescript": "^4.6.4",
15 | "vite": "^3.1.0"
16 | }
17 | },
18 | "..": {
19 | "name": "@orbs-network/tsv-widget",
20 | "version": "0.0.2",
21 | "extraneous": true,
22 | "license": "MIT",
23 | "dependencies": {
24 | "@types/codemirror": "^5.43.0",
25 | "codemirror": "^5.43.0",
26 | "codemirror-textmate": "git://github.com/orbs-network/codemirror-textmate",
27 | "onigasm": "^2.2.5"
28 | },
29 | "devDependencies": {
30 | "@babel/cli": "^7.18.10",
31 | "@babel/core": "^7.19.1",
32 | "@babel/plugin-proposal-class-properties": "^7.18.6",
33 | "@babel/polyfill": "^7.12.1",
34 | "@babel/preset-env": "^7.19.1",
35 | "babel-eslint": "^10.1.0",
36 | "babel-loader": "^8.2.5",
37 | "babel-preset-minify": "^0.5.2",
38 | "css-loader": "^6.7.1",
39 | "css-minimizer-webpack-plugin": "^4.1.0",
40 | "eslint": "^8.23.0",
41 | "file-loader": "^6.2.0",
42 | "html-webpack-plugin": "^5.5.0",
43 | "mini-css-extract-plugin": "^2.6.1",
44 | "node-polyfill-webpack-plugin": "^2.0.1",
45 | "style-loader": "^3.3.1",
46 | "terser-webpack-plugin": "^5.3.6",
47 | "to-string-loader": "^1.2.0",
48 | "ts-loader": "^9.4.1",
49 | "url-loader": "^4.1.1",
50 | "webpack": "^5.74.0",
51 | "webpack-cli": "^4.10.0",
52 | "webpack-dev-server": "^4.11.1"
53 | }
54 | },
55 | "../..": {
56 | "name": "@ton-community/contract-verifier-sdk",
57 | "version": "0.2.1",
58 | "license": "MIT",
59 | "dependencies": {
60 | "@aws-crypto/sha256-js": "^2.0.2",
61 | "@orbs-network/ton-access": "^2.2.2",
62 | "highlight.js": "^11.6.0",
63 | "highlightjs-func": "github:orbs-network/highlightjs-func",
64 | "ton": "^13.3.0"
65 | },
66 | "devDependencies": {
67 | "@types/node": "^18.11.18",
68 | "esbuild": "^0.16.16",
69 | "esbuild-plugin-polyfill-node": "^0.1.3",
70 | "eslint": "^8.31.0",
71 | "source-map-explorer": "^2.5.3",
72 | "tslint": "^6.1.3",
73 | "tslint-config-prettier": "^1.18.0"
74 | },
75 | "engines": {
76 | "node": ">=14.16"
77 | }
78 | },
79 | "node_modules/@esbuild/android-arm": {
80 | "version": "0.15.10",
81 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz",
82 | "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==",
83 | "cpu": [
84 | "arm"
85 | ],
86 | "dev": true,
87 | "optional": true,
88 | "os": [
89 | "android"
90 | ],
91 | "engines": {
92 | "node": ">=12"
93 | }
94 | },
95 | "node_modules/@esbuild/linux-loong64": {
96 | "version": "0.15.10",
97 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz",
98 | "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==",
99 | "cpu": [
100 | "loong64"
101 | ],
102 | "dev": true,
103 | "optional": true,
104 | "os": [
105 | "linux"
106 | ],
107 | "engines": {
108 | "node": ">=12"
109 | }
110 | },
111 | "node_modules/@ton-community/contract-verifier-sdk": {
112 | "resolved": "../..",
113 | "link": true
114 | },
115 | "node_modules/esbuild": {
116 | "version": "0.15.10",
117 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz",
118 | "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==",
119 | "dev": true,
120 | "hasInstallScript": true,
121 | "bin": {
122 | "esbuild": "bin/esbuild"
123 | },
124 | "engines": {
125 | "node": ">=12"
126 | },
127 | "optionalDependencies": {
128 | "@esbuild/android-arm": "0.15.10",
129 | "@esbuild/linux-loong64": "0.15.10",
130 | "esbuild-android-64": "0.15.10",
131 | "esbuild-android-arm64": "0.15.10",
132 | "esbuild-darwin-64": "0.15.10",
133 | "esbuild-darwin-arm64": "0.15.10",
134 | "esbuild-freebsd-64": "0.15.10",
135 | "esbuild-freebsd-arm64": "0.15.10",
136 | "esbuild-linux-32": "0.15.10",
137 | "esbuild-linux-64": "0.15.10",
138 | "esbuild-linux-arm": "0.15.10",
139 | "esbuild-linux-arm64": "0.15.10",
140 | "esbuild-linux-mips64le": "0.15.10",
141 | "esbuild-linux-ppc64le": "0.15.10",
142 | "esbuild-linux-riscv64": "0.15.10",
143 | "esbuild-linux-s390x": "0.15.10",
144 | "esbuild-netbsd-64": "0.15.10",
145 | "esbuild-openbsd-64": "0.15.10",
146 | "esbuild-sunos-64": "0.15.10",
147 | "esbuild-windows-32": "0.15.10",
148 | "esbuild-windows-64": "0.15.10",
149 | "esbuild-windows-arm64": "0.15.10"
150 | }
151 | },
152 | "node_modules/esbuild-android-64": {
153 | "version": "0.15.10",
154 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz",
155 | "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==",
156 | "cpu": [
157 | "x64"
158 | ],
159 | "dev": true,
160 | "optional": true,
161 | "os": [
162 | "android"
163 | ],
164 | "engines": {
165 | "node": ">=12"
166 | }
167 | },
168 | "node_modules/esbuild-android-arm64": {
169 | "version": "0.15.10",
170 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz",
171 | "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==",
172 | "cpu": [
173 | "arm64"
174 | ],
175 | "dev": true,
176 | "optional": true,
177 | "os": [
178 | "android"
179 | ],
180 | "engines": {
181 | "node": ">=12"
182 | }
183 | },
184 | "node_modules/esbuild-darwin-64": {
185 | "version": "0.15.10",
186 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz",
187 | "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==",
188 | "cpu": [
189 | "x64"
190 | ],
191 | "dev": true,
192 | "optional": true,
193 | "os": [
194 | "darwin"
195 | ],
196 | "engines": {
197 | "node": ">=12"
198 | }
199 | },
200 | "node_modules/esbuild-darwin-arm64": {
201 | "version": "0.15.10",
202 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz",
203 | "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==",
204 | "cpu": [
205 | "arm64"
206 | ],
207 | "dev": true,
208 | "optional": true,
209 | "os": [
210 | "darwin"
211 | ],
212 | "engines": {
213 | "node": ">=12"
214 | }
215 | },
216 | "node_modules/esbuild-freebsd-64": {
217 | "version": "0.15.10",
218 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz",
219 | "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==",
220 | "cpu": [
221 | "x64"
222 | ],
223 | "dev": true,
224 | "optional": true,
225 | "os": [
226 | "freebsd"
227 | ],
228 | "engines": {
229 | "node": ">=12"
230 | }
231 | },
232 | "node_modules/esbuild-freebsd-arm64": {
233 | "version": "0.15.10",
234 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz",
235 | "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==",
236 | "cpu": [
237 | "arm64"
238 | ],
239 | "dev": true,
240 | "optional": true,
241 | "os": [
242 | "freebsd"
243 | ],
244 | "engines": {
245 | "node": ">=12"
246 | }
247 | },
248 | "node_modules/esbuild-linux-32": {
249 | "version": "0.15.10",
250 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz",
251 | "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==",
252 | "cpu": [
253 | "ia32"
254 | ],
255 | "dev": true,
256 | "optional": true,
257 | "os": [
258 | "linux"
259 | ],
260 | "engines": {
261 | "node": ">=12"
262 | }
263 | },
264 | "node_modules/esbuild-linux-64": {
265 | "version": "0.15.10",
266 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz",
267 | "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==",
268 | "cpu": [
269 | "x64"
270 | ],
271 | "dev": true,
272 | "optional": true,
273 | "os": [
274 | "linux"
275 | ],
276 | "engines": {
277 | "node": ">=12"
278 | }
279 | },
280 | "node_modules/esbuild-linux-arm": {
281 | "version": "0.15.10",
282 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz",
283 | "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==",
284 | "cpu": [
285 | "arm"
286 | ],
287 | "dev": true,
288 | "optional": true,
289 | "os": [
290 | "linux"
291 | ],
292 | "engines": {
293 | "node": ">=12"
294 | }
295 | },
296 | "node_modules/esbuild-linux-arm64": {
297 | "version": "0.15.10",
298 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz",
299 | "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==",
300 | "cpu": [
301 | "arm64"
302 | ],
303 | "dev": true,
304 | "optional": true,
305 | "os": [
306 | "linux"
307 | ],
308 | "engines": {
309 | "node": ">=12"
310 | }
311 | },
312 | "node_modules/esbuild-linux-mips64le": {
313 | "version": "0.15.10",
314 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz",
315 | "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==",
316 | "cpu": [
317 | "mips64el"
318 | ],
319 | "dev": true,
320 | "optional": true,
321 | "os": [
322 | "linux"
323 | ],
324 | "engines": {
325 | "node": ">=12"
326 | }
327 | },
328 | "node_modules/esbuild-linux-ppc64le": {
329 | "version": "0.15.10",
330 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz",
331 | "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==",
332 | "cpu": [
333 | "ppc64"
334 | ],
335 | "dev": true,
336 | "optional": true,
337 | "os": [
338 | "linux"
339 | ],
340 | "engines": {
341 | "node": ">=12"
342 | }
343 | },
344 | "node_modules/esbuild-linux-riscv64": {
345 | "version": "0.15.10",
346 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz",
347 | "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==",
348 | "cpu": [
349 | "riscv64"
350 | ],
351 | "dev": true,
352 | "optional": true,
353 | "os": [
354 | "linux"
355 | ],
356 | "engines": {
357 | "node": ">=12"
358 | }
359 | },
360 | "node_modules/esbuild-linux-s390x": {
361 | "version": "0.15.10",
362 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz",
363 | "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==",
364 | "cpu": [
365 | "s390x"
366 | ],
367 | "dev": true,
368 | "optional": true,
369 | "os": [
370 | "linux"
371 | ],
372 | "engines": {
373 | "node": ">=12"
374 | }
375 | },
376 | "node_modules/esbuild-netbsd-64": {
377 | "version": "0.15.10",
378 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz",
379 | "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==",
380 | "cpu": [
381 | "x64"
382 | ],
383 | "dev": true,
384 | "optional": true,
385 | "os": [
386 | "netbsd"
387 | ],
388 | "engines": {
389 | "node": ">=12"
390 | }
391 | },
392 | "node_modules/esbuild-openbsd-64": {
393 | "version": "0.15.10",
394 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz",
395 | "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==",
396 | "cpu": [
397 | "x64"
398 | ],
399 | "dev": true,
400 | "optional": true,
401 | "os": [
402 | "openbsd"
403 | ],
404 | "engines": {
405 | "node": ">=12"
406 | }
407 | },
408 | "node_modules/esbuild-sunos-64": {
409 | "version": "0.15.10",
410 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz",
411 | "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==",
412 | "cpu": [
413 | "x64"
414 | ],
415 | "dev": true,
416 | "optional": true,
417 | "os": [
418 | "sunos"
419 | ],
420 | "engines": {
421 | "node": ">=12"
422 | }
423 | },
424 | "node_modules/esbuild-windows-32": {
425 | "version": "0.15.10",
426 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz",
427 | "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==",
428 | "cpu": [
429 | "ia32"
430 | ],
431 | "dev": true,
432 | "optional": true,
433 | "os": [
434 | "win32"
435 | ],
436 | "engines": {
437 | "node": ">=12"
438 | }
439 | },
440 | "node_modules/esbuild-windows-64": {
441 | "version": "0.15.10",
442 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz",
443 | "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==",
444 | "cpu": [
445 | "x64"
446 | ],
447 | "dev": true,
448 | "optional": true,
449 | "os": [
450 | "win32"
451 | ],
452 | "engines": {
453 | "node": ">=12"
454 | }
455 | },
456 | "node_modules/esbuild-windows-arm64": {
457 | "version": "0.15.10",
458 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz",
459 | "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==",
460 | "cpu": [
461 | "arm64"
462 | ],
463 | "dev": true,
464 | "optional": true,
465 | "os": [
466 | "win32"
467 | ],
468 | "engines": {
469 | "node": ">=12"
470 | }
471 | },
472 | "node_modules/fsevents": {
473 | "version": "2.3.2",
474 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
475 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
476 | "dev": true,
477 | "hasInstallScript": true,
478 | "optional": true,
479 | "os": [
480 | "darwin"
481 | ],
482 | "engines": {
483 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
484 | }
485 | },
486 | "node_modules/function-bind": {
487 | "version": "1.1.1",
488 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
489 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
490 | "dev": true
491 | },
492 | "node_modules/has": {
493 | "version": "1.0.3",
494 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
495 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
496 | "dev": true,
497 | "dependencies": {
498 | "function-bind": "^1.1.1"
499 | },
500 | "engines": {
501 | "node": ">= 0.4.0"
502 | }
503 | },
504 | "node_modules/is-core-module": {
505 | "version": "2.10.0",
506 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
507 | "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
508 | "dev": true,
509 | "dependencies": {
510 | "has": "^1.0.3"
511 | },
512 | "funding": {
513 | "url": "https://github.com/sponsors/ljharb"
514 | }
515 | },
516 | "node_modules/nanoid": {
517 | "version": "3.3.4",
518 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
519 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
520 | "dev": true,
521 | "bin": {
522 | "nanoid": "bin/nanoid.cjs"
523 | },
524 | "engines": {
525 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
526 | }
527 | },
528 | "node_modules/path-parse": {
529 | "version": "1.0.7",
530 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
531 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
532 | "dev": true
533 | },
534 | "node_modules/picocolors": {
535 | "version": "1.0.0",
536 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
537 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
538 | "dev": true
539 | },
540 | "node_modules/postcss": {
541 | "version": "8.4.17",
542 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
543 | "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
544 | "dev": true,
545 | "funding": [
546 | {
547 | "type": "opencollective",
548 | "url": "https://opencollective.com/postcss/"
549 | },
550 | {
551 | "type": "tidelift",
552 | "url": "https://tidelift.com/funding/github/npm/postcss"
553 | }
554 | ],
555 | "dependencies": {
556 | "nanoid": "^3.3.4",
557 | "picocolors": "^1.0.0",
558 | "source-map-js": "^1.0.2"
559 | },
560 | "engines": {
561 | "node": "^10 || ^12 || >=14"
562 | }
563 | },
564 | "node_modules/resolve": {
565 | "version": "1.22.1",
566 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
567 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
568 | "dev": true,
569 | "dependencies": {
570 | "is-core-module": "^2.9.0",
571 | "path-parse": "^1.0.7",
572 | "supports-preserve-symlinks-flag": "^1.0.0"
573 | },
574 | "bin": {
575 | "resolve": "bin/resolve"
576 | },
577 | "funding": {
578 | "url": "https://github.com/sponsors/ljharb"
579 | }
580 | },
581 | "node_modules/rollup": {
582 | "version": "2.78.1",
583 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
584 | "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
585 | "dev": true,
586 | "bin": {
587 | "rollup": "dist/bin/rollup"
588 | },
589 | "engines": {
590 | "node": ">=10.0.0"
591 | },
592 | "optionalDependencies": {
593 | "fsevents": "~2.3.2"
594 | }
595 | },
596 | "node_modules/source-map-js": {
597 | "version": "1.0.2",
598 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
599 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
600 | "dev": true,
601 | "engines": {
602 | "node": ">=0.10.0"
603 | }
604 | },
605 | "node_modules/supports-preserve-symlinks-flag": {
606 | "version": "1.0.0",
607 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
608 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
609 | "dev": true,
610 | "engines": {
611 | "node": ">= 0.4"
612 | },
613 | "funding": {
614 | "url": "https://github.com/sponsors/ljharb"
615 | }
616 | },
617 | "node_modules/typescript": {
618 | "version": "4.8.4",
619 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
620 | "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
621 | "dev": true,
622 | "bin": {
623 | "tsc": "bin/tsc",
624 | "tsserver": "bin/tsserver"
625 | },
626 | "engines": {
627 | "node": ">=4.2.0"
628 | }
629 | },
630 | "node_modules/vite": {
631 | "version": "3.1.7",
632 | "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.7.tgz",
633 | "integrity": "sha512-5vCAmU4S8lyVdFCInu9M54f/g8qbOMakVw5xJ4pjoaDy5wgy9sLLZkGdSLN52dlsBqh0tBqxjaqqa8LgPqwRAA==",
634 | "dev": true,
635 | "dependencies": {
636 | "esbuild": "^0.15.9",
637 | "postcss": "^8.4.16",
638 | "resolve": "^1.22.1",
639 | "rollup": "~2.78.0"
640 | },
641 | "bin": {
642 | "vite": "bin/vite.js"
643 | },
644 | "engines": {
645 | "node": "^14.18.0 || >=16.0.0"
646 | },
647 | "optionalDependencies": {
648 | "fsevents": "~2.3.2"
649 | },
650 | "peerDependencies": {
651 | "less": "*",
652 | "sass": "*",
653 | "stylus": "*",
654 | "terser": "^5.4.0"
655 | },
656 | "peerDependenciesMeta": {
657 | "less": {
658 | "optional": true
659 | },
660 | "sass": {
661 | "optional": true
662 | },
663 | "stylus": {
664 | "optional": true
665 | },
666 | "terser": {
667 | "optional": true
668 | }
669 | }
670 | }
671 | },
672 | "dependencies": {
673 | "@esbuild/android-arm": {
674 | "version": "0.15.10",
675 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.10.tgz",
676 | "integrity": "sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg==",
677 | "dev": true,
678 | "optional": true
679 | },
680 | "@esbuild/linux-loong64": {
681 | "version": "0.15.10",
682 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz",
683 | "integrity": "sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg==",
684 | "dev": true,
685 | "optional": true
686 | },
687 | "@ton-community/contract-verifier-sdk": {
688 | "version": "file:../..",
689 | "requires": {
690 | "@aws-crypto/sha256-js": "^2.0.2",
691 | "@orbs-network/ton-access": "^2.2.2",
692 | "@types/node": "^18.11.18",
693 | "esbuild": "^0.16.16",
694 | "esbuild-plugin-polyfill-node": "^0.1.3",
695 | "eslint": "^8.31.0",
696 | "highlight.js": "^11.6.0",
697 | "highlightjs-func": "github:orbs-network/highlightjs-func",
698 | "source-map-explorer": "^2.5.3",
699 | "ton": "^13.3.0",
700 | "tslint": "^6.1.3",
701 | "tslint-config-prettier": "^1.18.0"
702 | }
703 | },
704 | "esbuild": {
705 | "version": "0.15.10",
706 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.10.tgz",
707 | "integrity": "sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng==",
708 | "dev": true,
709 | "requires": {
710 | "@esbuild/android-arm": "0.15.10",
711 | "@esbuild/linux-loong64": "0.15.10",
712 | "esbuild-android-64": "0.15.10",
713 | "esbuild-android-arm64": "0.15.10",
714 | "esbuild-darwin-64": "0.15.10",
715 | "esbuild-darwin-arm64": "0.15.10",
716 | "esbuild-freebsd-64": "0.15.10",
717 | "esbuild-freebsd-arm64": "0.15.10",
718 | "esbuild-linux-32": "0.15.10",
719 | "esbuild-linux-64": "0.15.10",
720 | "esbuild-linux-arm": "0.15.10",
721 | "esbuild-linux-arm64": "0.15.10",
722 | "esbuild-linux-mips64le": "0.15.10",
723 | "esbuild-linux-ppc64le": "0.15.10",
724 | "esbuild-linux-riscv64": "0.15.10",
725 | "esbuild-linux-s390x": "0.15.10",
726 | "esbuild-netbsd-64": "0.15.10",
727 | "esbuild-openbsd-64": "0.15.10",
728 | "esbuild-sunos-64": "0.15.10",
729 | "esbuild-windows-32": "0.15.10",
730 | "esbuild-windows-64": "0.15.10",
731 | "esbuild-windows-arm64": "0.15.10"
732 | }
733 | },
734 | "esbuild-android-64": {
735 | "version": "0.15.10",
736 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz",
737 | "integrity": "sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA==",
738 | "dev": true,
739 | "optional": true
740 | },
741 | "esbuild-android-arm64": {
742 | "version": "0.15.10",
743 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz",
744 | "integrity": "sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg==",
745 | "dev": true,
746 | "optional": true
747 | },
748 | "esbuild-darwin-64": {
749 | "version": "0.15.10",
750 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz",
751 | "integrity": "sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA==",
752 | "dev": true,
753 | "optional": true
754 | },
755 | "esbuild-darwin-arm64": {
756 | "version": "0.15.10",
757 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz",
758 | "integrity": "sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ==",
759 | "dev": true,
760 | "optional": true
761 | },
762 | "esbuild-freebsd-64": {
763 | "version": "0.15.10",
764 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz",
765 | "integrity": "sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w==",
766 | "dev": true,
767 | "optional": true
768 | },
769 | "esbuild-freebsd-arm64": {
770 | "version": "0.15.10",
771 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz",
772 | "integrity": "sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg==",
773 | "dev": true,
774 | "optional": true
775 | },
776 | "esbuild-linux-32": {
777 | "version": "0.15.10",
778 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz",
779 | "integrity": "sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w==",
780 | "dev": true,
781 | "optional": true
782 | },
783 | "esbuild-linux-64": {
784 | "version": "0.15.10",
785 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz",
786 | "integrity": "sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA==",
787 | "dev": true,
788 | "optional": true
789 | },
790 | "esbuild-linux-arm": {
791 | "version": "0.15.10",
792 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz",
793 | "integrity": "sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A==",
794 | "dev": true,
795 | "optional": true
796 | },
797 | "esbuild-linux-arm64": {
798 | "version": "0.15.10",
799 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz",
800 | "integrity": "sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A==",
801 | "dev": true,
802 | "optional": true
803 | },
804 | "esbuild-linux-mips64le": {
805 | "version": "0.15.10",
806 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz",
807 | "integrity": "sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q==",
808 | "dev": true,
809 | "optional": true
810 | },
811 | "esbuild-linux-ppc64le": {
812 | "version": "0.15.10",
813 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz",
814 | "integrity": "sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ==",
815 | "dev": true,
816 | "optional": true
817 | },
818 | "esbuild-linux-riscv64": {
819 | "version": "0.15.10",
820 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz",
821 | "integrity": "sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q==",
822 | "dev": true,
823 | "optional": true
824 | },
825 | "esbuild-linux-s390x": {
826 | "version": "0.15.10",
827 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz",
828 | "integrity": "sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA==",
829 | "dev": true,
830 | "optional": true
831 | },
832 | "esbuild-netbsd-64": {
833 | "version": "0.15.10",
834 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz",
835 | "integrity": "sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw==",
836 | "dev": true,
837 | "optional": true
838 | },
839 | "esbuild-openbsd-64": {
840 | "version": "0.15.10",
841 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz",
842 | "integrity": "sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ==",
843 | "dev": true,
844 | "optional": true
845 | },
846 | "esbuild-sunos-64": {
847 | "version": "0.15.10",
848 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz",
849 | "integrity": "sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg==",
850 | "dev": true,
851 | "optional": true
852 | },
853 | "esbuild-windows-32": {
854 | "version": "0.15.10",
855 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz",
856 | "integrity": "sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg==",
857 | "dev": true,
858 | "optional": true
859 | },
860 | "esbuild-windows-64": {
861 | "version": "0.15.10",
862 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz",
863 | "integrity": "sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA==",
864 | "dev": true,
865 | "optional": true
866 | },
867 | "esbuild-windows-arm64": {
868 | "version": "0.15.10",
869 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz",
870 | "integrity": "sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw==",
871 | "dev": true,
872 | "optional": true
873 | },
874 | "fsevents": {
875 | "version": "2.3.2",
876 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
877 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
878 | "dev": true,
879 | "optional": true
880 | },
881 | "function-bind": {
882 | "version": "1.1.1",
883 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
884 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
885 | "dev": true
886 | },
887 | "has": {
888 | "version": "1.0.3",
889 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
890 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
891 | "dev": true,
892 | "requires": {
893 | "function-bind": "^1.1.1"
894 | }
895 | },
896 | "is-core-module": {
897 | "version": "2.10.0",
898 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
899 | "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
900 | "dev": true,
901 | "requires": {
902 | "has": "^1.0.3"
903 | }
904 | },
905 | "nanoid": {
906 | "version": "3.3.4",
907 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
908 | "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
909 | "dev": true
910 | },
911 | "path-parse": {
912 | "version": "1.0.7",
913 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
914 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
915 | "dev": true
916 | },
917 | "picocolors": {
918 | "version": "1.0.0",
919 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
920 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
921 | "dev": true
922 | },
923 | "postcss": {
924 | "version": "8.4.17",
925 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
926 | "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
927 | "dev": true,
928 | "requires": {
929 | "nanoid": "^3.3.4",
930 | "picocolors": "^1.0.0",
931 | "source-map-js": "^1.0.2"
932 | }
933 | },
934 | "resolve": {
935 | "version": "1.22.1",
936 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
937 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
938 | "dev": true,
939 | "requires": {
940 | "is-core-module": "^2.9.0",
941 | "path-parse": "^1.0.7",
942 | "supports-preserve-symlinks-flag": "^1.0.0"
943 | }
944 | },
945 | "rollup": {
946 | "version": "2.78.1",
947 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz",
948 | "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==",
949 | "dev": true,
950 | "requires": {
951 | "fsevents": "~2.3.2"
952 | }
953 | },
954 | "source-map-js": {
955 | "version": "1.0.2",
956 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
957 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
958 | "dev": true
959 | },
960 | "supports-preserve-symlinks-flag": {
961 | "version": "1.0.0",
962 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
963 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
964 | "dev": true
965 | },
966 | "typescript": {
967 | "version": "4.8.4",
968 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
969 | "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
970 | "dev": true
971 | },
972 | "vite": {
973 | "version": "3.1.7",
974 | "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.7.tgz",
975 | "integrity": "sha512-5vCAmU4S8lyVdFCInu9M54f/g8qbOMakVw5xJ4pjoaDy5wgy9sLLZkGdSLN52dlsBqh0tBqxjaqqa8LgPqwRAA==",
976 | "dev": true,
977 | "requires": {
978 | "esbuild": "^0.15.9",
979 | "fsevents": "~2.3.2",
980 | "postcss": "^8.4.16",
981 | "resolve": "^1.22.1",
982 | "rollup": "~2.78.0"
983 | }
984 | }
985 | }
986 | }
987 |
--------------------------------------------------------------------------------
/example/vanilla-vite/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "typescript": "^4.6.4",
13 | "vite": "^3.1.0"
14 | },
15 | "dependencies": {
16 | "@ton-community/contract-verifier-sdk": "file:../.."
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/vanilla-vite/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/vanilla-vite/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(++counter))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/example/vanilla-vite/src/main.ts:
--------------------------------------------------------------------------------
1 | import "./style.css";
2 |
3 | import "@ton-community/contract-verifier-sdk";
4 |
5 | document.querySelector("#app")!.innerHTML = `
6 |
7 |
Code Verifier UI Demo
8 |
9 |
Full
10 |
16 |
17 |
No line numbers
18 |
24 |
25 |
No Files
26 |
30 |
Switch file
31 |
32 |
With Explanation
33 |
34 |
35 |
36 |
37 |
38 |
39 |
How is this source code verified?
40 |
41 | This source code compiles to the same exact bytecode that is found on-chain.
42 |
43 |
44 | Compilation verification is performed by a decentralized group of validators.
45 |
46 |
47 | Variable names and comments cannot be verified and may not be honest.
48 |
49 |
50 | See proof
51 |
52 |
53 |
54 |
Vertical
55 |
61 |
62 |
63 | `;
64 |
65 | window.onload = async () => {
66 | const ipfslink = await ContractVerifier.getSourcesJsonUrl(
67 | "E/XXoxbG124QU+iKxZtd5loHKjiEUTcdxcW+y7oT9Q4="
68 | // "/rX/aCDi/w2Ug+fg1iyBfYRniftK5YDIeIZtlZ2r1cA="
69 | // "p6Jhak1jmgdsL2fnzOBCP9Khwu5VCtZRwe2hbuE7yso="
70 | // { httpApiEndpoint: "https://scalable-api.tonwhales.com/jsonRPC" }
71 | );
72 |
73 | if (ipfslink) {
74 | const sourcesData = await ContractVerifier.getSourcesData(ipfslink);
75 |
76 | const theme =
77 | window.matchMedia &&
78 | window.matchMedia("(prefers-color-scheme: dark)").matches
79 | ? "dark"
80 | : "light";
81 |
82 | // Full
83 | ContractVerifierUI.loadSourcesData(sourcesData, {
84 | containerSelector: "#myContainerFull",
85 | fileListSelector: "#myFilesFull",
86 | contentSelector: "#myContentFull",
87 | theme,
88 | });
89 |
90 | // No line num
91 | ContractVerifierUI.loadSourcesData(sourcesData, {
92 | containerSelector: "#myContainerNoLineNum",
93 | fileListSelector: "#myFilesNoLineNum",
94 | contentSelector: "#myContentNoLineNum",
95 | theme,
96 | hideLineNumbers: true,
97 | });
98 |
99 | // No files
100 | ContractVerifierUI.loadSourcesData(sourcesData, {
101 | containerSelector: "#myContainerNoFiles",
102 | contentSelector: "#myContentNoFiles",
103 | theme,
104 | });
105 |
106 | (document.querySelector("#container-nofiles-btn")! as HTMLElement).onclick =
107 | () => {
108 | ContractVerifierUI.setCode(
109 | "#myContentNoFiles",
110 | sourcesData.files[1].content
111 | );
112 | };
113 |
114 | // Explanation
115 | ContractVerifierUI.loadSourcesData(sourcesData, {
116 | containerSelector: "#myContainerExplanation",
117 | fileListSelector: "#myFilesExplanation",
118 | contentSelector: "#myContentExplanation",
119 | theme,
120 | });
121 |
122 | // Vertical
123 | ContractVerifierUI.loadSourcesData(sourcesData, {
124 | containerSelector: "#myContainerVertical",
125 | fileListSelector: "#myFilesVertical",
126 | contentSelector: "#myContentVertical",
127 | theme,
128 | });
129 |
130 | (document.querySelector("#explanation") as HTMLElement).style.visibility =
131 | "";
132 | }
133 | };
134 |
--------------------------------------------------------------------------------
/example/vanilla-vite/src/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3 | font-size: 16px;
4 | line-height: 24px;
5 | font-weight: 400;
6 |
7 | color-scheme: light dark;
8 | color: rgba(255, 255, 255, 0.87);
9 | background-color: #242424;
10 |
11 | font-synthesis: none;
12 | text-rendering: optimizeLegibility;
13 | -webkit-font-smoothing: antialiased;
14 | -moz-osx-font-smoothing: grayscale;
15 | -webkit-text-size-adjust: 100%;
16 | }
17 |
18 | a {
19 | font-weight: 500;
20 | color: #646cff;
21 | text-decoration: inherit;
22 | }
23 | a:hover {
24 | color: #535bf2;
25 | }
26 |
27 | body {
28 | margin: 0;
29 | display: flex;
30 | place-items: center;
31 | min-width: 320px;
32 | min-height: 100vh;
33 | }
34 |
35 | h1 {
36 | font-size: 3.2em;
37 | line-height: 1.1;
38 | }
39 |
40 | #app {
41 | max-width: 1280px;
42 | margin: 0 auto;
43 | padding: 2rem;
44 | text-align: center;
45 | width: 100%;
46 | }
47 |
48 | .logo {
49 | height: 6em;
50 | padding: 1.5em;
51 | will-change: filter;
52 | }
53 | .logo:hover {
54 | filter: drop-shadow(0 0 2em #646cffaa);
55 | }
56 | .logo.vanilla:hover {
57 | filter: drop-shadow(0 0 2em #3178c6aa);
58 | }
59 |
60 | .card {
61 | padding: 2em;
62 | }
63 |
64 | .read-the-docs {
65 | color: #888;
66 | }
67 |
68 | button {
69 | border-radius: 8px;
70 | border: 1px solid transparent;
71 | padding: 0.6em 1.2em;
72 | font-size: 1em;
73 | font-weight: 500;
74 | font-family: inherit;
75 | background-color: #1a1a1a;
76 | cursor: pointer;
77 | transition: border-color 0.25s;
78 | }
79 | button:hover {
80 | border-color: #646cff;
81 | }
82 | button:focus,
83 | button:focus-visible {
84 | outline: 4px auto -webkit-focus-ring-color;
85 | }
86 |
87 | @media (prefers-color-scheme: light) {
88 | :root {
89 | color: #213547;
90 | background-color: #c6c6c6;
91 | }
92 | a:hover {
93 | color: #747bff;
94 | }
95 | button {
96 | background-color: #f9f9f9;
97 | }
98 | }
99 |
100 | #explanation {
101 | padding-top: 30px;
102 | background-color: black;
103 | }
104 |
105 | .contract-verifier-container {
106 | height: 500px;
107 | }
--------------------------------------------------------------------------------
/example/vanilla-vite/src/typescript.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/vanilla-vite/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/example/vanilla-vite/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "module": "ESNext",
6 | "lib": ["ESNext", "DOM"],
7 | "moduleResolution": "Node",
8 | "strict": true,
9 | "sourceMap": true,
10 | "resolveJsonModule": true,
11 | "isolatedModules": true,
12 | "esModuleInterop": true,
13 | "noEmit": true,
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "noImplicitReturns": true,
17 | "skipLibCheck": true
18 | },
19 | "include": ["src"],
20 | }
21 |
--------------------------------------------------------------------------------
/lib/contract-verifier-ui.d.ts:
--------------------------------------------------------------------------------
1 | import { SourcesData } from "./contract-verifier";
2 | type Theme = "light" | "dark";
3 | export declare const classNames: {
4 | CONTAINER: string;
5 | FILES: string;
6 | FILE: string;
7 | FOLDER: string;
8 | TREE_ITEM: string;
9 | FOLDER_CONTAINER: string;
10 | CODE_CONTAINER: string;
11 | CODE_LINES: string;
12 | CODE_CONTENT: string;
13 | };
14 | export declare const ContractVerifierUI: {
15 | _stylesPopulated: {
16 | internal: boolean;
17 | };
18 | _populateStyle(theme: "dark" | "light"): void;
19 | _populateCode(contentSelector: string, theme: "dark" | "light"): void;
20 | _setCode({ name, content }: {
21 | name: string;
22 | content: string;
23 | }, codeWrapperEl: HTMLElement, filesListEl?: HTMLElement, fileEl?: HTMLElement): void;
24 | setCode(contentSelector: string, content: string): void;
25 | _populateFiles(fileListSelector: string, contentSelector: string, files: {
26 | name: string;
27 | content: string;
28 | }[], theme: "dark" | "light"): void;
29 | _populateContainer(selector: string, hideLineNumbers: boolean): void;
30 | loadSourcesData(sourcesData: SourcesData, opts: {
31 | containerSelector: string;
32 | fileListSelector?: string;
33 | contentSelector: string;
34 | theme: Theme;
35 | hideLineNumbers?: boolean;
36 | }): void;
37 | };
38 | export {};
39 |
--------------------------------------------------------------------------------
/lib/contract-verifier-ui.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
4 | };
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | exports.ContractVerifierUI = exports.classNames = void 0;
7 | const core_1 = __importDefault(require("highlight.js/lib/core"));
8 | const highlightjs_func_1 = __importDefault(require("highlightjs-func"));
9 | const dom_1 = require("./dom");
10 | const file_structure_1 = require("./file-structure");
11 | const style_css_1 = __importDefault(require("./style.css"));
12 | (0, highlightjs_func_1.default)(core_1.default);
13 | exports.classNames = {
14 | CONTAINER: "contract-verifier-container",
15 | FILES: "contract-verifier-files",
16 | FILE: "contract-verifier-file",
17 | FOLDER: "contract-verifier-folder",
18 | TREE_ITEM: "contract-verifier-tree-item",
19 | FOLDER_CONTAINER: "contract-verifier-folder-container",
20 | CODE_CONTAINER: "contract-verifier-code",
21 | CODE_LINES: "contract-verifier-code-lines",
22 | CODE_CONTENT: "contract-verifier-code-content",
23 | };
24 | exports.ContractVerifierUI = {
25 | _stylesPopulated: {
26 | internal: false,
27 | },
28 | _populateStyle(theme) {
29 | if (!this._stylesPopulated[theme]) {
30 | this._stylesPopulated[theme] = true;
31 | const styleEl = document.createElement("style");
32 | styleEl.innerHTML = `${theme === "light"
33 | ? require("highlight.js/styles/atom-one-light.css").toString()
34 | : require("highlight.js/styles/atom-one-dark.css").toString()}`;
35 | document.head.appendChild(styleEl);
36 | }
37 | if (!this._stylesPopulated.internal) {
38 | this._stylesPopulated.internal = true;
39 | const styleEl = document.createElement("style");
40 | styleEl.innerHTML = style_css_1.default;
41 | document.head.appendChild(styleEl);
42 | }
43 | },
44 | _populateCode(contentSelector, theme) {
45 | const codeContainer = document.querySelector(contentSelector);
46 | codeContainer.classList.add(exports.classNames.CODE_CONTAINER);
47 | codeContainer.classList.add(theme);
48 | codeContainer.innerHTML = `
`;
49 | },
50 | _setCode({ name, content }, codeWrapperEl, filesListEl, fileEl) {
51 | if (fileEl?.classList.contains("active"))
52 | return;
53 | codeWrapperEl.scrollTo(0, 0);
54 | content = content.trim();
55 | const codeEl = codeWrapperEl.querySelector("code");
56 | codeEl.innerHTML = "";
57 | codeEl.appendChild((0, dom_1.div)({ className: exports.classNames.CODE_LINES }, content
58 | .split("\n")
59 | .map((_, i) => i + 1)
60 | .join("\n")));
61 | const contentEl = (0, dom_1.div)({ className: exports.classNames.CODE_CONTENT }, content);
62 | codeEl.appendChild(contentEl);
63 | if (name.match(/\.fif(t)?$/)) {
64 | contentEl.classList.add("language-fift");
65 | }
66 | else {
67 | contentEl.classList.add("language-func");
68 | }
69 | core_1.default.highlightElement(contentEl);
70 | filesListEl
71 | ?.querySelector(`.${exports.classNames.FILE}.active`)
72 | ?.classList.remove("active");
73 | fileEl?.classList.add("active");
74 | },
75 | setCode(contentSelector, content) {
76 | this._setCode({ name: "", content }, document.querySelector(contentSelector));
77 | },
78 | _populateFiles(fileListSelector, contentSelector, files, theme) {
79 | const filePart = document.querySelector(fileListSelector);
80 | filePart.innerHTML = "";
81 | filePart.classList.add(theme);
82 | filePart.classList.add(exports.classNames.FILES);
83 | // Prepare folder hierarchy
84 | const root = {
85 | type: "root",
86 | children: [],
87 | };
88 | files.forEach((file) => {
89 | const nameParts = Array.from(file.name.matchAll(/(?:\/|^)([^\/\n]+)/g)).map((m) => m[1]);
90 | const folders = nameParts.length > 1 ? nameParts.slice(0, nameParts.length - 1) : [];
91 | let levelToPushTo = root;
92 | folders.forEach((folder) => {
93 | let existingFolder = levelToPushTo.children.find((obj) => obj.type === "folder" && obj.name === folder);
94 | if (!existingFolder) {
95 | const newLevel = {
96 | type: "folder",
97 | name: folder,
98 | children: [],
99 | };
100 | levelToPushTo.children.push(newLevel);
101 | existingFolder = newLevel;
102 | }
103 | levelToPushTo = existingFolder;
104 | });
105 | levelToPushTo.children.push({
106 | type: "file",
107 | name: nameParts[nameParts.length - 1],
108 | content: file.content,
109 | });
110 | });
111 | function processLevel(level) {
112 | return level.children
113 | .filter((obj) => obj.type === "file")
114 | .map((child) => {
115 | const file = (0, file_structure_1.TreeFile)({ name: child.name }, theme);
116 | file.onclick = () => {
117 | exports.ContractVerifierUI._setCode({ name: child.name, content: child.content }, document.querySelector(contentSelector), document.querySelector(fileListSelector), file);
118 | };
119 | return file;
120 | })
121 | .concat(level.children
122 | .filter((obj) => obj.type === "folder")
123 | .map((child) => (0, file_structure_1.TreeFolder)({ name: child.name, opened: true }, theme, ...processLevel(child))));
124 | }
125 | processLevel(root).forEach((el) => filePart.appendChild(el));
126 | },
127 | _populateContainer(selector, hideLineNumbers) {
128 | const el = document.querySelector(selector);
129 | el.classList.add(exports.classNames.CONTAINER);
130 | if (!hideLineNumbers) {
131 | el.classList.add("lineNumbers");
132 | }
133 | },
134 | loadSourcesData(sourcesData, opts) {
135 | this._populateContainer(opts.containerSelector, !!opts.hideLineNumbers);
136 | if (opts.fileListSelector) {
137 | this._populateFiles(opts.fileListSelector, opts.contentSelector, sourcesData.files, opts.theme);
138 | }
139 | this._populateStyle(opts.theme);
140 | this._populateCode(opts.contentSelector, opts.theme);
141 | this._setCode(sourcesData.files[0], document.querySelector(opts.contentSelector), document.querySelector(opts.fileListSelector), document.querySelector(`${opts.fileListSelector} .contract-verifier-file`));
142 | },
143 | };
144 | //# sourceMappingURL=contract-verifier-ui.js.map
--------------------------------------------------------------------------------
/lib/contract-verifier-ui.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"contract-verifier-ui.js","sourceRoot":"","sources":["../src/lib/contract-verifier-ui.ts"],"names":[],"mappings":";;;;;;AAAA,iEAAyC;AACzC,wEAA0C;AAE1C,+BAA4B;AAC5B,qDAAwD;AACxD,4DAAgC;AAEhC,IAAA,0BAAU,EAAC,cAAI,CAAC,CAAC;AAIJ,QAAA,UAAU,GAAG;IACxB,SAAS,EAAE,6BAA6B;IACxC,KAAK,EAAE,yBAAyB;IAChC,IAAI,EAAE,wBAAwB;IAC9B,MAAM,EAAE,0BAA0B;IAClC,SAAS,EAAE,6BAA6B;IACxC,gBAAgB,EAAE,oCAAoC;IACtD,cAAc,EAAE,wBAAwB;IACxC,UAAU,EAAE,8BAA8B;IAC1C,YAAY,EAAE,gCAAgC;CAC/C,CAAC;AAEW,QAAA,kBAAkB,GAAG;IAChC,gBAAgB,EAAE;QAChB,QAAQ,EAAE,KAAK;KAChB;IACD,cAAc,CAAC,KAAuB;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;YACjC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,CAAC,SAAS,GAAG,GAClB,KAAK,KAAK,OAAO;gBACf,CAAC,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;gBAC9D,CAAC,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,QAAQ,EAC/D,EAAE,CAAC;YAEH,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SACpC;QACD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE;YACnC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,IAAI,CAAC;YACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,CAAC,SAAS,GAAG,mBAAK,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SACpC;IACH,CAAC;IACD,aAAa,CAAC,eAAuB,EAAE,KAAuB;QAC5D,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;QAC9D,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAU,CAAC,cAAc,CAAC,CAAC;QACvD,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,aAAa,CAAC,SAAS,GAAG,qBAAqB,KAAK,iBAAiB,CAAC;IACxE,CAAC;IAED,QAAQ,CACN,EAAE,IAAI,EAAE,OAAO,EAAqC,EACpD,aAA0B,EAC1B,WAAyB,EACzB,MAAoB;QAEpB,IAAI,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO;QACjD,aAAa,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,WAAW,CAChB,IAAA,SAAG,EACD,EAAE,SAAS,EAAE,kBAAU,CAAC,UAAU,EAAE,EACpC,OAAO;aACJ,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;aACpB,IAAI,CAAC,IAAI,CAAC,CACd,CACF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAA,SAAG,EAAC,EAAE,SAAS,EAAE,kBAAU,CAAC,YAAY,EAAE,EAAE,OAAO,CAAC,CAAC;QACvE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAE9B,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;YAC5B,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;SAC1C;aAAM;YACL,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;SAC1C;QAED,cAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAEjC,WAAW;YACT,EAAE,aAAa,CAAC,IAAI,kBAAU,CAAC,IAAI,SAAS,CAAC;YAC7C,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE/B,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,eAAuB,EAAE,OAAe;QAC9C,IAAI,CAAC,QAAQ,CACX,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EACrB,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,CACxC,CAAC;IACJ,CAAC;IAED,cAAc,CACZ,gBAAwB,EACxB,eAAuB,EACvB,KAA0C,EAC1C,KAAuB;QAEvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC1D,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC;QACxB,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAU,CAAC,KAAK,CAAC,CAAC;QAEzC,2BAA2B;QAC3B,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAC1C,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnB,MAAM,OAAO,GACX,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEvE,IAAI,aAAa,GAAG,IAAI,CAAC;YAEzB,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzB,IAAI,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAC9C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CACtD,CAAC;gBAEF,IAAI,CAAC,cAAc,EAAE;oBACnB,MAAM,QAAQ,GAAG;wBACf,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,MAAM;wBACZ,QAAQ,EAAE,EAAE;qBACb,CAAC;oBACF,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAEtC,cAAc,GAAG,QAAQ,CAAC;iBAC3B;gBAED,aAAa,GAAG,cAAc,CAAC;YACjC,CAAC,CAAC,CAAC;YAEH,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC1B,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;gBACrC,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,YAAY,CAAC,KAAK;YACzB,OAAO,KAAK,CAAC,QAAQ;iBAClB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC;iBACpC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBACb,MAAM,IAAI,GAAG,IAAA,yBAAQ,EAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;gBACnD,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE;oBAClB,0BAAkB,CAAC,QAAQ,CACzB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAC5C,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,EACxC,IAAI,CACL,CAAC;gBACJ,CAAC,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;iBACD,MAAM,CACL,KAAK,CAAC,QAAQ;iBACX,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC;iBACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACb,IAAA,2BAAU,EACR,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAClC,KAAK,EACL,GAAG,YAAY,CAAC,KAAK,CAAC,CACvB,CACF,CACJ,CAAC;QACN,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,kBAAkB,CAAC,QAAgB,EAAE,eAAwB;QAC3D,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAU,CAAC,SAAS,CAAC,CAAC;QAEvC,IAAI,CAAC,eAAe,EAAE;YACpB,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SACjC;IACH,CAAC;IAED,eAAe,CACb,WAAwB,EACxB,IAMC;QAED,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAExE,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,IAAI,CAAC,cAAc,CACjB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,eAAe,EACpB,WAAW,CAAC,KAAK,EACjB,IAAI,CAAC,KAAK,CACX,CAAC;SACH;QACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ,CACX,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EACpB,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,EAC5C,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAC7C,QAAQ,CAAC,aAAa,CACpB,GAAG,IAAI,CAAC,gBAAgB,0BAA0B,CACnD,CACF,CAAC;IACJ,CAAC;CACF,CAAC"}
--------------------------------------------------------------------------------
/lib/contract-verifier.d.ts:
--------------------------------------------------------------------------------
1 | interface GetSourcesOptions {
2 | verifier?: string;
3 | httpApiEndpointV4?: string;
4 | testnet?: boolean;
5 | }
6 | export declare type FuncCompilerVersion = string;
7 | export declare type TactVersion = string;
8 | export declare type FiftVersion = FuncCompilerVersion;
9 | export declare type TolkVersion = string;
10 | export declare type FuncCompilerSettings = {
11 | funcVersion: FuncCompilerVersion;
12 | commandLine: string;
13 | };
14 | export type FiftCliCompileSettings = {
15 | fiftVersion: FiftVersion;
16 | commandLine: string;
17 | };
18 | export type TactCliCompileSettings = {
19 | tactVersion: TactVersion;
20 | };
21 | export type TolkCliCompileSettings = {
22 | tolkVersion: TolkVersion;
23 | };
24 | export type FuncSource = {
25 | name: string;
26 | content: string;
27 | isEntrypoint: boolean;
28 | };
29 | export type TolkSource = {
30 | name: string;
31 | content: string;
32 | isEntrypoint: boolean;
33 | };
34 | export type TactSource = {
35 | name: string;
36 | content: string;
37 | };
38 | export interface SourcesData {
39 | files: (TactSource | FuncSource | TolkSource)[];
40 | compiler: "func" | "tact" | "fift" | "tolk";
41 | compilerSettings: FuncCompilerSettings | FiftCliCompileSettings | TolkCliCompileSettings | TactCliCompileSettings;
42 | verificationDate: Date;
43 | ipfsHttpLink: string;
44 | }
45 | type IpfsUrlConverterFunc = (ipfsUrl: string, testnet: boolean) => string;
46 | export declare const ContractVerifier: {
47 | getSourcesJsonUrl(codeCellHash: string, options?: GetSourcesOptions): Promise;
48 | getSourcesData(sourcesJsonUrl: string, options?: {
49 | ipfsConverter?: IpfsUrlConverterFunc;
50 | testnet?: boolean;
51 | }): Promise;
52 | };
53 | export {};
54 |
--------------------------------------------------------------------------------
/lib/contract-verifier.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.ContractVerifier = void 0;
4 | const ton_1 = require("ton");
5 | const ton_access_1 = require("@orbs-network/ton-access");
6 | const sha256_js_1 = require("@aws-crypto/sha256-js");
7 | const SOURCES_REGISTRY = ton_1.Address.parse("EQD-BJSVUJviud_Qv7Ymfd3qzXdrmV525e3YDzWQoHIAiInL");
8 | const SOURCES_REGISTRY_TESTNET = ton_1.Address.parse("EQCsdKYwUaXkgJkz2l0ol6qT_WxeRbE_wBCwnEybmR0u5TO8");
9 | function toSha256Buffer(s) {
10 | const sha = new sha256_js_1.Sha256();
11 | sha.update(s);
12 | return Buffer.from(sha.digestSync());
13 | }
14 | function defaultIpfsConverter(ipfs, testnet) {
15 | let endpoint;
16 | if (testnet) {
17 | endpoint = "https://tonsource-testnet.infura-ipfs.io/ipfs/";
18 | }
19 | else {
20 | endpoint = "https://files.orbs.network/ipfs/";
21 | }
22 | return ipfs.replace("ipfs://", endpoint);
23 | }
24 | function bigIntFromBuffer(buffer) {
25 | return BigInt(`0x${buffer.toString("hex")}`);
26 | }
27 | exports.ContractVerifier = {
28 | async getSourcesJsonUrl(codeCellHash, options) {
29 | const tc = new ton_1.TonClient4({
30 | endpoint: options?.httpApiEndpointV4 ??
31 | (await (0, ton_access_1.getHttpV4Endpoint)({
32 | network: options.testnet ? "testnet" : "mainnet",
33 | })),
34 | });
35 | const { last: { seqno }, } = await tc.getLastBlock();
36 | const args = new ton_1.TupleBuilder();
37 | args.writeNumber(bigIntFromBuffer(toSha256Buffer(options?.verifier ?? "orbs.com")));
38 | args.writeNumber(bigIntFromBuffer(Buffer.from(codeCellHash, "base64")));
39 | const { result: itemAddRes } = await tc.runMethod(seqno, options.testnet ? SOURCES_REGISTRY_TESTNET : SOURCES_REGISTRY, "get_source_item_address", args.build());
40 | let reader = new ton_1.TupleReader(itemAddRes);
41 | const sourceItemAddr = reader.readAddress();
42 | const isDeployed = await tc.isContractDeployed(seqno, sourceItemAddr);
43 | if (isDeployed) {
44 | const { result: sourceItemDataRes } = await tc.runMethod(seqno, sourceItemAddr, "get_source_item_data");
45 | reader = new ton_1.TupleReader(sourceItemDataRes);
46 | const contentCell = reader.skip(3).readCell().beginParse();
47 | const version = contentCell.loadUint(8);
48 | if (version !== 1)
49 | throw new Error("Unsupported version");
50 | const ipfsLink = contentCell.loadStringTail();
51 | return ipfsLink;
52 | }
53 | return null;
54 | },
55 | async getSourcesData(sourcesJsonUrl, options) {
56 | const ipfsConverter = options.ipfsConverter ?? defaultIpfsConverter;
57 | const ipfsHttpLink = ipfsConverter(sourcesJsonUrl, !!options.testnet);
58 | const verifiedContract = await (await fetch(ipfsConverter(sourcesJsonUrl, !!options.testnet))).json();
59 | const files = (await Promise.all(verifiedContract.sources.map(async (source) => {
60 | const url = ipfsConverter(source.url, !!options.testnet);
61 | const content = await fetch(url).then((u) => u.text());
62 | return {
63 | name: source.filename,
64 | content,
65 | isEntrypoint: source.isEntrypoint,
66 | };
67 | })))
68 | .reverse()
69 | .sort((a, b) => {
70 | return Number(b.isEntrypoint) - Number(a.isEntrypoint);
71 | });
72 | return {
73 | files,
74 | verificationDate: new Date(verifiedContract.verificationDate),
75 | compilerSettings: verifiedContract.compilerSettings,
76 | compiler: verifiedContract.compiler,
77 | ipfsHttpLink,
78 | };
79 | },
80 | };
81 | //# sourceMappingURL=contract-verifier.js.map
--------------------------------------------------------------------------------
/lib/contract-verifier.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"contract-verifier.js","sourceRoot":"","sources":["../src/lib/contract-verifier.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/lib/dom.d.ts:
--------------------------------------------------------------------------------
1 | export declare const div: (props: any, ...children: any[]) => any;
2 | export declare const code: (props: any, ...children: any[]) => any;
3 | export declare const img: (props: any, ...children: any[]) => any;
4 | export declare function appendChildren(parent: any, children: any): void;
5 | export declare function setStyle(el: any, style: any): void;
6 | export declare function setClass(el: any, className: any): void;
7 | export declare function setProps(el: any, props: any): void;
8 | export declare function createElement(type: any, props: any, ...children: any[]): any;
9 |
--------------------------------------------------------------------------------
/lib/dom.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.createElement = exports.setProps = exports.setClass = exports.setStyle = exports.appendChildren = exports.img = exports.code = exports.div = void 0;
4 | const div = (props, ...children) => createElement("div", props, ...children);
5 | exports.div = div;
6 | const code = (props, ...children) => createElement("code", props, ...children);
7 | exports.code = code;
8 | const img = (props, ...children) => createElement("img", props, ...children);
9 | exports.img = img;
10 | function appendChildren(parent, children) {
11 | for (const child of children) {
12 | if (!child)
13 | continue;
14 | switch (typeof child) {
15 | case "string":
16 | const el = document.createTextNode(child);
17 | parent.appendChild(el);
18 | break;
19 | default:
20 | parent.appendChild(child);
21 | break;
22 | }
23 | }
24 | }
25 | exports.appendChildren = appendChildren;
26 | function setStyle(el, style) {
27 | if (typeof style === "string") {
28 | el.setAttribute("style", style);
29 | }
30 | else {
31 | Object.assign(el.style, style);
32 | }
33 | }
34 | exports.setStyle = setStyle;
35 | function setClass(el, className) {
36 | className.split(/\s/).forEach((element) => {
37 | if (element) {
38 | el.classList.add(element);
39 | }
40 | });
41 | }
42 | exports.setClass = setClass;
43 | function setProps(el, props) {
44 | const eventRegex = /^on([a-z]+)$/i;
45 | for (const propName in props) {
46 | if (!propName)
47 | continue;
48 | if (propName === "style") {
49 | setStyle(el, props[propName]);
50 | }
51 | else if (propName === "className") {
52 | setClass(el, props[propName]);
53 | }
54 | else if (eventRegex.test(propName)) {
55 | const eventToListen = propName.replace(eventRegex, "$1").toLowerCase();
56 | el.addEventListener(eventToListen, props[propName]);
57 | }
58 | else {
59 | el.setAttribute(propName, props[propName]);
60 | }
61 | }
62 | }
63 | exports.setProps = setProps;
64 | function createElement(type, props, ...children) {
65 | if (typeof type === "function") {
66 | return type(props);
67 | }
68 | else {
69 | const el = document.createElement(type);
70 | if (props && typeof props === "object") {
71 | setProps(el, props);
72 | }
73 | if (children) {
74 | appendChildren(el, children);
75 | }
76 | return el;
77 | }
78 | }
79 | exports.createElement = createElement;
80 | //# sourceMappingURL=dom.js.map
--------------------------------------------------------------------------------
/lib/dom.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/lib/dom.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/lib/file-structure.d.ts:
--------------------------------------------------------------------------------
1 | export declare const TreeFile: ({ name }: {
2 | name: any;
3 | }, theme: any) => any;
4 | export declare const TreeFolder: (props: any, theme: any, ...children: any[]) => any;
5 |
--------------------------------------------------------------------------------
/lib/file-structure.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
4 | };
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | exports.TreeFolder = exports.TreeFile = void 0;
7 | const dom_1 = require("./dom");
8 | const file_white_svg_1 = __importDefault(require("./res/file-white.svg"));
9 | const file_black_svg_1 = __importDefault(require("./res/file-black.svg"));
10 | const folder_closed_white_svg_1 = __importDefault(require("./res/folder-closed-white.svg"));
11 | const folder_closed_black_svg_1 = __importDefault(require("./res/folder-closed-black.svg"));
12 | const folder_open_white_svg_1 = __importDefault(require("./res/folder-open-white.svg"));
13 | const folder_open_black_svg_1 = __importDefault(require("./res/folder-open-black.svg"));
14 | const contract_verifier_ui_1 = require("./contract-verifier-ui");
15 | const icons = {
16 | dark: {
17 | file: file_white_svg_1.default,
18 | folder: {
19 | open: folder_open_white_svg_1.default,
20 | closed: folder_closed_white_svg_1.default,
21 | },
22 | },
23 | light: {
24 | file: file_black_svg_1.default,
25 | folder: {
26 | open: folder_open_black_svg_1.default,
27 | closed: folder_closed_black_svg_1.default,
28 | },
29 | },
30 | };
31 | const svgToInline = (svg) => `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`;
32 | const TreeFile = ({ name }, theme) => {
33 | return (0, dom_1.div)({ className: `${contract_verifier_ui_1.classNames.FILE} ${contract_verifier_ui_1.classNames.TREE_ITEM}` }, (0, dom_1.img)({
34 | src: svgToInline(icons[theme].file),
35 | }), (0, dom_1.div)(null, name));
36 | };
37 | exports.TreeFile = TreeFile;
38 | function changeOpened(theme, event) {
39 | const folderHeader = event.target.classList.contains("folder-header")
40 | ? event.target
41 | : event.target.parentElement;
42 | const opened = folderHeader.getAttribute("opened") === "true";
43 | const newOpened = !opened;
44 | folderHeader.children[0].attributes.src.value = svgToInline(newOpened ? icons[theme].folder.open : icons[theme].folder.closed);
45 | try {
46 | const sibling = folderHeader.nextElementSibling;
47 | if (newOpened) {
48 | sibling.classList.remove("hide");
49 | }
50 | else {
51 | sibling.classList.add("hide");
52 | }
53 | }
54 | catch (e) {
55 | console.warn(`No sibling of elem ${folderHeader} found ...`);
56 | }
57 | folderHeader.setAttribute("opened", newOpened);
58 | }
59 | const TreeFolder = (props, theme, ...children) => {
60 | const opened = props.opened || false;
61 | const folderIcon = icons[theme].folder[opened ? "open" : "closed"];
62 | const folderName = props.name || "unknown";
63 | return (0, dom_1.div)({ className: contract_verifier_ui_1.classNames.FOLDER_CONTAINER }, (0, dom_1.div)({
64 | onClick: changeOpened.bind(this, theme),
65 | className: `folder-header ${contract_verifier_ui_1.classNames.FOLDER} ${contract_verifier_ui_1.classNames.TREE_ITEM}`,
66 | opened,
67 | }, (0, dom_1.img)({
68 | src: svgToInline(folderIcon),
69 | }), (0, dom_1.div)(null, folderName)), (0, dom_1.div)({ className: `${opened ? "" : "hide"} folder-content` }, ...children));
70 | };
71 | exports.TreeFolder = TreeFolder;
72 | //# sourceMappingURL=file-structure.js.map
--------------------------------------------------------------------------------
/lib/file-structure.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"file-structure.js","sourceRoot":"","sources":["../src/lib/file-structure.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/lib/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from "./contract-verifier";
2 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15 | };
16 | Object.defineProperty(exports, "__esModule", { value: true });
17 | __exportStar(require("./contract-verifier"), exports);
18 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/lib/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC"}
--------------------------------------------------------------------------------
/lib/web.d.ts:
--------------------------------------------------------------------------------
1 | import { ContractVerifier as _ContractVerifier } from "./contract-verifier";
2 | import { ContractVerifierUI as _ContractVerifierUI } from "./contract-verifier-ui";
3 | declare global {
4 | var ContractVerifier: typeof _ContractVerifier;
5 | var ContractVerifierUI: typeof _ContractVerifierUI;
6 | }
7 | export { ContractVerifierUI } from "./contract-verifier-ui";
8 | export * from "./contract-verifier";
9 |
--------------------------------------------------------------------------------
/lib/web.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6 | desc = { enumerable: true, get: function() { return m[k]; } };
7 | }
8 | Object.defineProperty(o, k2, desc);
9 | }) : (function(o, m, k, k2) {
10 | if (k2 === undefined) k2 = k;
11 | o[k2] = m[k];
12 | }));
13 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15 | };
16 | Object.defineProperty(exports, "__esModule", { value: true });
17 | exports.ContractVerifierUI = void 0;
18 | const contract_verifier_1 = require("./contract-verifier");
19 | const contract_verifier_ui_1 = require("./contract-verifier-ui");
20 | window.ContractVerifier = contract_verifier_1.ContractVerifier;
21 | window.ContractVerifierUI = contract_verifier_ui_1.ContractVerifierUI;
22 | var contract_verifier_ui_2 = require("./contract-verifier-ui");
23 | Object.defineProperty(exports, "ContractVerifierUI", { enumerable: true, get: function () { return contract_verifier_ui_2.ContractVerifierUI; } });
24 | __exportStar(require("./contract-verifier"), exports);
25 | //# sourceMappingURL=web.js.map
--------------------------------------------------------------------------------
/lib/web.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/lib/web.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2DAA4E;AAC5E,iEAAmF;AAOnF,MAAM,CAAC,gBAAgB,GAAG,oCAAiB,CAAC;AAC5C,MAAM,CAAC,kBAAkB,GAAG,yCAAmB,CAAC;AAEhD,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,sDAAoC"}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ton-community/contract-verifier-sdk",
3 | "version": "1.4.0",
4 | "description": "TON verifier SDK - sources fetcher + code viewer for FunC with code highlighting ",
5 | "exports": {
6 | "node": "./lib/index.js",
7 | "import": "./dist/index.min.js"
8 | },
9 | "types": "lib/web.d.ts",
10 | "files": [
11 | "lib/**/**",
12 | "dist/index.min.js"
13 | ],
14 | "scripts": {
15 | "start": "webpack-dev-server --hot",
16 | "npm-publish": "npm publish --access=public",
17 | "cleanup": "rimraf ./lib",
18 | "build:web:min": "node build.js",
19 | "build:web": "rimraf ./dist && npm run build:web:min",
20 | "build": "npm run lint && rimraf ./lib && tsc && npm run build:web",
21 | "format": "prettier --write \"src/**/*.ts\"",
22 | "lint": "npx tslint -p tsconfig.json",
23 | "prepare": "npm run build",
24 | "prepublishOnly": "npm test && npm run lint",
25 | "preversion": "npm run lint",
26 | "version": "npm run format && git add -A src",
27 | "test": ""
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "https://github.com/ton-community/contract-verifier-sdk"
32 | },
33 | "bugs": {
34 | "url": "https://github.com/ton-community/contract-verifier-sdk/issues"
35 | },
36 | "author": "Shahar Yakir",
37 | "license": "MIT",
38 | "homepage": "https://github.com/ton-community/contract-verifier-sdk",
39 | "keywords": [
40 | "ton",
41 | "source",
42 | "verifier",
43 | "widget",
44 | "sources"
45 | ],
46 | "dependencies": {
47 | "@aws-crypto/sha256-js": "^2.0.2",
48 | "@orbs-network/ton-access": "^2.3.3",
49 | "highlight.js": "11.6.0",
50 | "highlightjs-func": "github:orbs-network/highlightjs-func",
51 | "husky": "^9.0.11",
52 | "prettier": "^3.2.5",
53 | "ton": "^13.4.1",
54 | "ton-core": "^0.48.0"
55 | },
56 | "devDependencies": {
57 | "@types/node": "^18.11.18",
58 | "esbuild": "^0.16.16",
59 | "esbuild-plugin-polyfill-node": "^0.1.3",
60 | "eslint": "^8.31.0",
61 | "source-map-explorer": "^2.5.3",
62 | "tslint": "^6.1.3",
63 | "tslint-config-prettier": "^1.18.0"
64 | },
65 | "engines": {
66 | "node": ">=14.16"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/lib/contract-verifier-ui.ts:
--------------------------------------------------------------------------------
1 | import hljs from "highlight.js/lib/core";
2 | import hljsDefine from "highlightjs-func";
3 | import { SourcesData } from "./contract-verifier";
4 | import { div } from "./dom";
5 | import { TreeFile, TreeFolder } from "./file-structure";
6 | import style from "./style.css";
7 |
8 | hljsDefine(hljs);
9 |
10 | type Theme = "light" | "dark";
11 |
12 | export const classNames = {
13 | CONTAINER: "contract-verifier-container",
14 | FILES: "contract-verifier-files",
15 | FILE: "contract-verifier-file",
16 | FOLDER: "contract-verifier-folder",
17 | TREE_ITEM: "contract-verifier-tree-item",
18 | FOLDER_CONTAINER: "contract-verifier-folder-container",
19 | CODE_CONTAINER: "contract-verifier-code",
20 | CODE_LINES: "contract-verifier-code-lines",
21 | CODE_CONTENT: "contract-verifier-code-content",
22 | };
23 |
24 | export const ContractVerifierUI = {
25 | _stylesPopulated: {
26 | internal: false,
27 | },
28 | _populateStyle(theme: "dark" | "light") {
29 | if (!this._stylesPopulated[theme]) {
30 | this._stylesPopulated[theme] = true;
31 | const styleEl = document.createElement("style");
32 | styleEl.innerHTML = `${
33 | theme === "light"
34 | ? require("highlight.js/styles/atom-one-light.css").toString()
35 | : require("highlight.js/styles/atom-one-dark.css").toString()
36 | }`;
37 |
38 | document.head.appendChild(styleEl);
39 | }
40 | if (!this._stylesPopulated.internal) {
41 | this._stylesPopulated.internal = true;
42 | const styleEl = document.createElement("style");
43 | styleEl.innerHTML = style;
44 | document.head.appendChild(styleEl);
45 | }
46 | },
47 | _populateCode(contentSelector: string, theme: "dark" | "light") {
48 | const codeContainer = document.querySelector(contentSelector);
49 | codeContainer.classList.add(classNames.CODE_CONTAINER);
50 | codeContainer.classList.add(theme);
51 | codeContainer.innerHTML = `
`;
52 | },
53 |
54 | _setCode(
55 | { name, content }: { name: string; content: string },
56 | codeWrapperEl: HTMLElement,
57 | filesListEl?: HTMLElement,
58 | fileEl?: HTMLElement,
59 | ) {
60 | if (fileEl?.classList.contains("active")) return;
61 | codeWrapperEl.scrollTo(0, 0);
62 | content = content.trim();
63 | const codeEl = codeWrapperEl.querySelector("code");
64 | codeEl.innerHTML = "";
65 | codeEl.appendChild(
66 | div(
67 | { className: classNames.CODE_LINES },
68 | content
69 | .split("\n")
70 | .map((_, i) => i + 1)
71 | .join("\n"),
72 | ),
73 | );
74 |
75 | const contentEl = div({ className: classNames.CODE_CONTENT }, content);
76 | codeEl.appendChild(contentEl);
77 |
78 | if (name.match(/\.fif(t)?$/)) {
79 | contentEl.classList.add("language-fift");
80 | } else {
81 | contentEl.classList.add("language-func");
82 | }
83 |
84 | hljs.highlightElement(contentEl);
85 |
86 | filesListEl
87 | ?.querySelector(`.${classNames.FILE}.active`)
88 | ?.classList.remove("active");
89 |
90 | fileEl?.classList.add("active");
91 | },
92 |
93 | setCode(contentSelector: string, content: string) {
94 | this._setCode(
95 | { name: "", content },
96 | document.querySelector(contentSelector),
97 | );
98 | },
99 |
100 | _populateFiles(
101 | fileListSelector: string,
102 | contentSelector: string,
103 | files: { name: string; content: string }[],
104 | theme: "dark" | "light",
105 | ) {
106 | const filePart = document.querySelector(fileListSelector);
107 | filePart.innerHTML = "";
108 | filePart.classList.add(theme);
109 | filePart.classList.add(classNames.FILES);
110 |
111 | // Prepare folder hierarchy
112 | const root = {
113 | type: "root",
114 | children: [],
115 | };
116 |
117 | files.forEach((file) => {
118 | const nameParts = Array.from(
119 | file.name.matchAll(/(?:\/|^)([^\/\n]+)/g),
120 | ).map((m) => m[1]);
121 |
122 | const folders =
123 | nameParts.length > 1 ? nameParts.slice(0, nameParts.length - 1) : [];
124 |
125 | let levelToPushTo = root;
126 |
127 | folders.forEach((folder) => {
128 | let existingFolder = levelToPushTo.children.find(
129 | (obj) => obj.type === "folder" && obj.name === folder,
130 | );
131 |
132 | if (!existingFolder) {
133 | const newLevel = {
134 | type: "folder",
135 | name: folder,
136 | children: [],
137 | };
138 | levelToPushTo.children.push(newLevel);
139 |
140 | existingFolder = newLevel;
141 | }
142 |
143 | levelToPushTo = existingFolder;
144 | });
145 |
146 | levelToPushTo.children.push({
147 | type: "file",
148 | name: nameParts[nameParts.length - 1],
149 | content: file.content,
150 | });
151 | });
152 |
153 | function processLevel(level) {
154 | return level.children
155 | .filter((obj) => obj.type === "file")
156 | .map((child) => {
157 | const file = TreeFile({ name: child.name }, theme);
158 | file.onclick = () => {
159 | ContractVerifierUI._setCode(
160 | { name: child.name, content: child.content },
161 | document.querySelector(contentSelector),
162 | document.querySelector(fileListSelector),
163 | file,
164 | );
165 | };
166 | return file;
167 | })
168 | .concat(
169 | level.children
170 | .filter((obj) => obj.type === "folder")
171 | .map((child) =>
172 | TreeFolder(
173 | { name: child.name, opened: true },
174 | theme,
175 | ...processLevel(child),
176 | ),
177 | ),
178 | );
179 | }
180 |
181 | processLevel(root).forEach((el) => filePart.appendChild(el));
182 | },
183 |
184 | _populateContainer(selector: string, hideLineNumbers: boolean) {
185 | const el = document.querySelector(selector);
186 | el.classList.add(classNames.CONTAINER);
187 |
188 | if (!hideLineNumbers) {
189 | el.classList.add("lineNumbers");
190 | }
191 | },
192 |
193 | loadSourcesData(
194 | sourcesData: SourcesData,
195 | opts: {
196 | containerSelector: string;
197 | fileListSelector?: string;
198 | contentSelector: string;
199 | theme: Theme;
200 | hideLineNumbers?: boolean;
201 | },
202 | ) {
203 | this._populateContainer(opts.containerSelector, !!opts.hideLineNumbers);
204 |
205 | if (opts.fileListSelector) {
206 | this._populateFiles(
207 | opts.fileListSelector,
208 | opts.contentSelector,
209 | sourcesData.files,
210 | opts.theme,
211 | );
212 | }
213 | this._populateStyle(opts.theme);
214 | this._populateCode(opts.contentSelector, opts.theme);
215 | this._setCode(
216 | sourcesData.files[0],
217 | document.querySelector(opts.contentSelector),
218 | document.querySelector(opts.fileListSelector),
219 | document.querySelector(
220 | `${opts.fileListSelector} .contract-verifier-file`,
221 | ), // Get first file
222 | );
223 | },
224 | };
225 |
--------------------------------------------------------------------------------
/src/lib/contract-verifier.ts:
--------------------------------------------------------------------------------
1 | import { TonClient4, Address, TupleReader, TupleBuilder } from "ton";
2 | import { getHttpV4Endpoint } from "@orbs-network/ton-access";
3 | import { Sha256 } from "@aws-crypto/sha256-js";
4 |
5 | interface GetSourcesOptions {
6 | verifier?: string;
7 | httpApiEndpointV4?: string;
8 | testnet?: boolean;
9 | }
10 |
11 | export declare type FuncCompilerVersion = string;
12 | export declare type TactVersion = string;
13 | export declare type FiftVersion = FuncCompilerVersion; // Fift is tied to a FunC version
14 | export declare type TolkVersion = string;
15 |
16 | export declare type FuncCompilerSettings = {
17 | funcVersion: FuncCompilerVersion;
18 | commandLine: string;
19 | };
20 | export type FiftCliCompileSettings = {
21 | fiftVersion: FiftVersion;
22 | commandLine: string;
23 | };
24 | export type TactCliCompileSettings = {
25 | tactVersion: TactVersion;
26 | };
27 |
28 | export type TolkCliCompileSettings = {
29 | tolkVersion: TolkVersion;
30 | };
31 |
32 |
33 | export type FuncSource = {
34 | name: string;
35 | content: string;
36 | isEntrypoint: boolean;
37 | };
38 | export type TolkSource = {
39 | name: string;
40 | content: string;
41 | isEntrypoint: boolean;
42 | }
43 |
44 | export type TactSource = {
45 | name: string;
46 | content: string;
47 | };
48 |
49 | export interface SourcesData {
50 | files: (TactSource | FuncSource | TolkSource)[];
51 | compiler: "func" | "tact" | "fift" | "tolk";
52 | compilerSettings:
53 | | FuncCompilerSettings
54 | | FiftCliCompileSettings
55 | | TolkCliCompileSettings
56 | | TactCliCompileSettings;
57 | verificationDate: Date;
58 | ipfsHttpLink: string;
59 | }
60 |
61 | type IpfsUrlConverterFunc = (ipfsUrl: string, testnet: boolean) => string;
62 |
63 | const SOURCES_REGISTRY = Address.parse(
64 | "EQD-BJSVUJviud_Qv7Ymfd3qzXdrmV525e3YDzWQoHIAiInL",
65 | );
66 | const SOURCES_REGISTRY_TESTNET = Address.parse(
67 | "EQCsdKYwUaXkgJkz2l0ol6qT_WxeRbE_wBCwnEybmR0u5TO8",
68 | );
69 |
70 | function toSha256Buffer(s: string) {
71 | const sha = new Sha256();
72 | sha.update(s);
73 | return Buffer.from(sha.digestSync());
74 | }
75 |
76 | function defaultIpfsConverter(ipfs: string, testnet: boolean) {
77 | let endpoint: string;
78 |
79 | if (testnet) {
80 | endpoint = "https://tonsource-testnet.infura-ipfs.io/ipfs/";
81 | } else {
82 | endpoint = "https://files.orbs.network/ipfs/";
83 | }
84 |
85 | return ipfs.replace("ipfs://", endpoint);
86 | }
87 |
88 | function bigIntFromBuffer(buffer: Buffer) {
89 | return BigInt(`0x${buffer.toString("hex")}`);
90 | }
91 |
92 | export const ContractVerifier = {
93 | async getSourcesJsonUrl(
94 | codeCellHash: string,
95 | options?: GetSourcesOptions,
96 | ): Promise {
97 | const tc = new TonClient4({
98 | endpoint:
99 | options?.httpApiEndpointV4 ??
100 | (await getHttpV4Endpoint({
101 | network: options.testnet ? "testnet" : "mainnet",
102 | })),
103 | });
104 | const {
105 | last: { seqno },
106 | } = await tc.getLastBlock();
107 |
108 | const args = new TupleBuilder();
109 | args.writeNumber(
110 | bigIntFromBuffer(toSha256Buffer(options?.verifier ?? "orbs.com")),
111 | );
112 | args.writeNumber(bigIntFromBuffer(Buffer.from(codeCellHash, "base64")));
113 | const { result: itemAddRes } = await tc.runMethod(
114 | seqno,
115 | options.testnet ? SOURCES_REGISTRY_TESTNET : SOURCES_REGISTRY,
116 | "get_source_item_address",
117 | args.build(),
118 | );
119 |
120 | let reader = new TupleReader(itemAddRes);
121 | const sourceItemAddr = reader.readAddress();
122 | const isDeployed = await tc.isContractDeployed(seqno, sourceItemAddr);
123 |
124 | if (isDeployed) {
125 | const { result: sourceItemDataRes } = await tc.runMethod(
126 | seqno,
127 | sourceItemAddr,
128 | "get_source_item_data",
129 | );
130 |
131 | reader = new TupleReader(sourceItemDataRes);
132 | const contentCell = reader.skip(3).readCell().beginParse();
133 | const version = contentCell.loadUint(8);
134 | if (version !== 1) throw new Error("Unsupported version");
135 | const ipfsLink = contentCell.loadStringTail();
136 |
137 | return ipfsLink;
138 | }
139 | return null;
140 | },
141 |
142 | async getSourcesData(
143 | sourcesJsonUrl: string,
144 | options?: {
145 | ipfsConverter?: IpfsUrlConverterFunc;
146 | testnet?: boolean;
147 | },
148 | ): Promise {
149 | const ipfsConverter = options.ipfsConverter ?? defaultIpfsConverter;
150 | const ipfsHttpLink = ipfsConverter(sourcesJsonUrl, !!options.testnet);
151 |
152 | const verifiedContract = await (
153 | await fetch(ipfsConverter(sourcesJsonUrl, !!options.testnet))
154 | ).json();
155 |
156 | const files = (
157 | await Promise.all(
158 | verifiedContract.sources.map(
159 | async (source: {
160 | url: string;
161 | filename: string;
162 | isEntrypoint?: boolean;
163 | }) => {
164 | const url = ipfsConverter(source.url, !!options.testnet);
165 | const content = await fetch(url).then((u) => u.text());
166 | return {
167 | name: source.filename,
168 | content,
169 | isEntrypoint: source.isEntrypoint,
170 | };
171 | },
172 | ),
173 | )
174 | )
175 | .reverse()
176 | .sort((a, b) => {
177 | return Number(b.isEntrypoint) - Number(a.isEntrypoint);
178 | });
179 |
180 | return {
181 | files,
182 | verificationDate: new Date(verifiedContract.verificationDate),
183 | compilerSettings: verifiedContract.compilerSettings,
184 | compiler: verifiedContract.compiler,
185 | ipfsHttpLink,
186 | };
187 | },
188 | };
189 |
--------------------------------------------------------------------------------
/src/lib/declaration.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.css";
2 | declare module "*.svg";
3 |
--------------------------------------------------------------------------------
/src/lib/dom.ts:
--------------------------------------------------------------------------------
1 | export const div = (props, ...children) =>
2 | createElement("div", props, ...children);
3 | export const code = (props, ...children) =>
4 | createElement("code", props, ...children);
5 | export const img = (props, ...children) =>
6 | createElement("img", props, ...children);
7 |
8 | export function appendChildren(parent, children) {
9 | for (const child of children) {
10 | if (!child) continue;
11 | switch (typeof child) {
12 | case "string":
13 | const el = document.createTextNode(child);
14 | parent.appendChild(el);
15 | break;
16 | default:
17 | parent.appendChild(child);
18 | break;
19 | }
20 | }
21 | }
22 |
23 | export function setStyle(el, style) {
24 | if (typeof style === "string") {
25 | el.setAttribute("style", style);
26 | } else {
27 | Object.assign(el.style, style);
28 | }
29 | }
30 |
31 | export function setClass(el, className) {
32 | className.split(/\s/).forEach((element) => {
33 | if (element) {
34 | el.classList.add(element);
35 | }
36 | });
37 | }
38 |
39 | export function setProps(el, props) {
40 | const eventRegex = /^on([a-z]+)$/i;
41 | for (const propName in props) {
42 | if (!propName) continue;
43 |
44 | if (propName === "style") {
45 | setStyle(el, props[propName]);
46 | } else if (propName === "className") {
47 | setClass(el, props[propName]);
48 | } else if (eventRegex.test(propName)) {
49 | const eventToListen = propName.replace(eventRegex, "$1").toLowerCase();
50 | el.addEventListener(eventToListen, props[propName]);
51 | } else {
52 | el.setAttribute(propName, props[propName]);
53 | }
54 | }
55 | }
56 |
57 | export function createElement(type, props, ...children) {
58 | if (typeof type === "function") {
59 | return type(props);
60 | } else {
61 | const el = document.createElement(type);
62 | if (props && typeof props === "object") {
63 | setProps(el, props);
64 | }
65 | if (children) {
66 | appendChildren(el, children);
67 | }
68 | return el;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/lib/file-structure.ts:
--------------------------------------------------------------------------------
1 | import { div, img } from "./dom";
2 | import fileWhite from "./res/file-white.svg";
3 | import fileBlack from "./res/file-black.svg";
4 | import folderClosedWhite from "./res/folder-closed-white.svg";
5 | import folderClosedBlack from "./res/folder-closed-black.svg";
6 | import folderOpenWhite from "./res/folder-open-white.svg";
7 | import folderOpenBlack from "./res/folder-open-black.svg";
8 | import { classNames } from "./contract-verifier-ui";
9 |
10 | const icons = {
11 | dark: {
12 | file: fileWhite,
13 | folder: {
14 | open: folderOpenWhite,
15 | closed: folderClosedWhite,
16 | },
17 | },
18 | light: {
19 | file: fileBlack,
20 | folder: {
21 | open: folderOpenBlack,
22 | closed: folderClosedBlack,
23 | },
24 | },
25 | };
26 |
27 | const svgToInline = (svg) =>
28 | `data:image/svg+xml;base64,${Buffer.from(svg, "utf8").toString("base64")}`;
29 |
30 | export const TreeFile = ({ name }, theme) => {
31 | return div(
32 | { className: `${classNames.FILE} ${classNames.TREE_ITEM}` },
33 | img({
34 | src: svgToInline(icons[theme].file),
35 | }),
36 | div(null, name),
37 | );
38 | };
39 |
40 | function changeOpened(theme, event) {
41 | const folderHeader = event.target.classList.contains("folder-header")
42 | ? event.target
43 | : event.target.parentElement;
44 | const opened = folderHeader.getAttribute("opened") === "true";
45 | const newOpened = !opened;
46 |
47 | folderHeader.children[0].attributes.src.value = svgToInline(
48 | newOpened ? icons[theme].folder.open : icons[theme].folder.closed,
49 | );
50 |
51 | try {
52 | const sibling = folderHeader.nextElementSibling;
53 | if (newOpened) {
54 | sibling.classList.remove("hide");
55 | } else {
56 | sibling.classList.add("hide");
57 | }
58 | } catch (e) {
59 | console.warn(`No sibling of elem ${folderHeader} found ...`);
60 | }
61 |
62 | folderHeader.setAttribute("opened", newOpened);
63 | }
64 |
65 | export const TreeFolder = (props, theme, ...children) => {
66 | const opened = props.opened || false;
67 | const folderIcon = icons[theme].folder[opened ? "open" : "closed"];
68 | const folderName = props.name || "unknown";
69 |
70 | return div(
71 | { className: classNames.FOLDER_CONTAINER },
72 | div(
73 | {
74 | onClick: changeOpened.bind(this, theme),
75 | className: `folder-header ${classNames.FOLDER} ${classNames.TREE_ITEM}`,
76 | opened,
77 | },
78 | img({
79 | src: svgToInline(folderIcon),
80 | }),
81 | div(null, folderName),
82 | ),
83 | div({ className: `${opened ? "" : "hide"} folder-content` }, ...children),
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/src/lib/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./contract-verifier";
2 |
--------------------------------------------------------------------------------
/src/lib/res/file-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/lib/res/file-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/lib/res/folder-closed-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/res/folder-closed-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/res/folder-open-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/res/folder-open-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/lib/style.css:
--------------------------------------------------------------------------------
1 | .contract-verifier-container {
2 | display: flex;
3 | height: 100%;
4 | }
5 |
6 | .contract-verifier-code {
7 | text-align: left;
8 | overflow: auto;
9 | height: 100%;
10 | width: 100%;
11 | }
12 |
13 | .contract-verifier-code.dark {
14 | background: #232222;
15 | }
16 |
17 | .contract-verifier-code code {
18 | display: flex;
19 | padding: 0.5em;
20 | }
21 |
22 | .contract-verifier-code code div {
23 | background: transparent;
24 | }
25 |
26 | .contract-verifier-code code .contract-verifier-code-lines {
27 | padding: 0 20px 0 0;
28 | text-align: right;
29 | display: none;
30 | }
31 |
32 | .contract-verifier-container.lineNumbers .contract-verifier-code-lines {
33 | display: initial;
34 | }
35 |
36 | .contract-verifier-code code.dark .contract-verifier-code-lines {
37 | color: #7e7e7e;
38 | }
39 |
40 | .contract-verifier-code code.light .contract-verifier-code-lines {
41 | color: #728a96;
42 | }
43 |
44 | .contract-verifier-code pre {
45 | margin: 0;
46 | }
47 |
48 | .contract-verifier-files {
49 | text-align: left;
50 | flex-shrink: 0;
51 | display: flex;
52 | flex-direction: column;
53 | width: 200px;
54 | overflow-y: auto;
55 | }
56 |
57 | .contract-verifier-files.dark {
58 | background: #28292d;
59 | color: white;
60 | }
61 |
62 | .contract-verifier-files.light {
63 | background: #fff;
64 | }
65 |
66 | .contract-verifier-tree-item {
67 | padding: 10px 6px;
68 | cursor: pointer;
69 | display: flex;
70 | gap: 4px;
71 | user-select: none;
72 | }
73 |
74 | .contract-verifier-files.dark .contract-verifier-tree-item:hover {
75 | filter: brightness(0.8);
76 | }
77 |
78 | .contract-verifier-files.light .contract-verifier-tree-item:hover {
79 | background-color: #f6f6f6;
80 | }
81 |
82 | .contract-verifier-files.dark .contract-verifier-file.active {
83 | background: #232222;
84 | }
85 |
86 | .contract-verifier-files.light .contract-verifier-file.active {
87 | background: #f2f2f2;
88 | }
89 |
90 | .contract-verifier-files .hide {
91 | display: none;
92 | }
93 |
94 | .contract-verifier-folder-container > .folder-content {
95 | padding-left: 12px;
96 | }
97 |
--------------------------------------------------------------------------------
/src/lib/web.ts:
--------------------------------------------------------------------------------
1 | import { ContractVerifier as _ContractVerifier } from "./contract-verifier";
2 | import { ContractVerifierUI as _ContractVerifierUI } from "./contract-verifier-ui";
3 |
4 | declare global {
5 | var ContractVerifier: typeof _ContractVerifier;
6 | var ContractVerifierUI: typeof _ContractVerifierUI;
7 | }
8 |
9 | window.ContractVerifier = _ContractVerifier;
10 | window.ContractVerifierUI = _ContractVerifierUI;
11 |
12 | export { ContractVerifierUI } from "./contract-verifier-ui";
13 | export * from "./contract-verifier";
14 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "module": "commonjs",
5 | "declaration": true,
6 | "outDir": "./lib",
7 | "strict": false,
8 | "sourceMap": true,
9 | "esModuleInterop": true,
10 | "isolatedModules": true
11 | },
12 | "include": ["src"],
13 | "exclude": ["src/demo", "build", "example", "node_modules", "lib"]
14 | }
15 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "tslint:recommended",
4 | "tslint-config-prettier"
5 | ],
6 | "rules": {
7 | "no-console": false,
8 | "comment-format": false,
9 | "no-empty": false
10 | }
11 | }
--------------------------------------------------------------------------------