├── .babelrc
├── .circleci
└── config.yml
├── .eslintrc
├── .gitignore
├── .nvmrc
├── .vscode
└── extensions.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── TERMS-OF-USE.md
├── configs
├── default.env
├── devServer.config.js
└── index.js
├── package-lock.json
├── package.json
├── src
├── App.js
├── App.scss
├── components
│ ├── AccountUpdate.js
│ ├── AccountUpdate.scss
│ ├── AccountUpdateFD.js
│ ├── AccountUpdateFDRatio.js
│ ├── AddToken.js
│ ├── AddToken.scss
│ ├── Button.js
│ ├── Button.scss
│ ├── BytecodeExample.js
│ ├── BytecodeExample.scss
│ ├── Dropdown.js
│ ├── Dropdown.scss
│ ├── FeeDelegation.js
│ ├── FeeDelegation.scss
│ ├── GithubLink.js
│ ├── GithubLink.scss
│ ├── Input.js
│ ├── Input.scss
│ ├── Message.js
│ ├── Message.scss
│ ├── Nav.js
│ ├── Nav.scss
│ ├── SignMessage.js
│ ├── SmartContractDeploy.js
│ ├── SmartContractDeployFD.js
│ ├── SmartContractDeployFDRatio.js
│ ├── SmartContractDeployLegacy.js
│ ├── SmartContractExecution.js
│ ├── SmartContractExecutionFD.js
│ ├── SmartContractExecutionFDRatio.js
│ ├── SmartContractExecutionLegacy.js
│ ├── TxResult.js
│ ├── TxResult.scss
│ ├── ValueTransfer.js
│ ├── ValueTransferFD.js
│ ├── ValueTransferFDRatio.js
│ ├── ValueTransferLegacy.js
│ ├── ValueTransferMemo.js
│ ├── ValueTransferMemoFD.js
│ ├── ValueTransferMemoFDRatio.js
│ ├── WalletInfo.js
│ └── WalletInfo.scss
├── constants
│ ├── networks.js
│ └── url.js
├── index.js
├── index.scss
├── klaytn
│ └── caver.js
├── pages
│ ├── KaikasPage.js
│ └── KaikasPage.scss
└── styles
│ ├── _colors.scss
│ ├── _fonts.scss
│ ├── _mixins.scss
│ ├── _sizes.scss
│ └── _variables.scss
├── static
├── fonts
│ ├── SFUIText-Bold.ttf
│ ├── SFUIText-Light.ttf
│ ├── SFUIText-Medium.ttf
│ ├── SFUIText-Regular.ttf
│ └── SFUIText-Semibold.ttf
├── images
│ ├── favicon@16.png
│ ├── ico-error.svg
│ ├── ico-receipt.svg
│ ├── icon-close.png
│ ├── icon-downArrow.svg
│ ├── icon-github.svg
│ ├── icon-tx.svg
│ ├── icon-upArrow.svg
│ ├── icon-wallet.png
│ ├── kaikas-tutorial-screen.png
│ ├── klaytn-logo.png
│ ├── logo-kaikas-tutorial.png
│ └── logo.svg
└── index.html
├── webpack.base.js
├── webpack.dev.js
└── webpack.prod.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "ie": 10,
8 | }
9 | }
10 | ],
11 | "@babel/preset-react"
12 | ],
13 | "plugins": [
14 | "@babel/plugin-proposal-class-properties",
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | default: &defaults
4 | working_directory: ~/kaikas-tutorial
5 | docker:
6 | - image: circleci/node:10
7 |
8 | jobs:
9 | deploy:
10 | <<: *defaults
11 | steps:
12 | - checkout
13 | - restore_cache:
14 | keys: node_modules-{{ checksum "package-lock.json" }}
15 | - run: |
16 | npm install
17 | npm run build
18 | sudo apt-get install awscli
19 | aws s3 sync dist/ s3://$FRONTEND_BUCKET/dist
20 | - save_cache:
21 | key: node_modules-{{ checksum "package-lock.json" }}
22 | paths:
23 | - node_modules
24 |
25 |
26 | workflows:
27 | deploy:
28 | jobs:
29 | - deploy:
30 | filters:
31 | branches:
32 | only: master
33 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "globals": {
3 | "window": true,
4 | "document": true,
5 | "DEV": true,
6 | "DEPLOYED_ADDRESS": true,
7 | "artifacts": true,
8 | },
9 | "parser": "babel-eslint",
10 | "extends": [
11 | "eslint:recommended",
12 | "plugin:react/recommended",
13 | "airbnb"
14 | ],
15 | "rules": {
16 | "no-undef": "off",
17 | "arrow-parens": ["error", "always"],
18 | "comma-dangle": ["error", "always-multiline"],
19 | "global-require": 0,
20 | "func-names": 0,
21 | "function-paren-newline": 0,
22 | "semi": 0,
23 | "prefer-arrow-callback": 0,
24 | "eqeqeq": 0,
25 | "wrap-iife": 0,
26 | "no-unused-expressions": 0,
27 | "no-console": 0,
28 | "no-bitwise": 0,
29 | "no-plusplus": 0,
30 | "no-multi-assign": 0,
31 | "jsx-a11y/anchor-is-valid": 0,
32 | "jsx-a11y/no-static-element-interactions": 0,
33 | "jsx-a11y/click-events-have-key-events": 0,
34 | "jsx-a11y/alt-text": 0,
35 | "jsx-a11y/label-has-for": "off",
36 | "import/no-unresolved": false,
37 | "import/prefer-default-export": false,
38 | "import/extensions": false,
39 | "import/no-extraneous-dependencies": 0,
40 | "react/jsx-filename-extension": false,
41 | "react/prop-types": "off"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | build/
3 | dist/
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4 |
5 | // List of extensions which should be recommended for users of this workspace.
6 | "recommendations": [
7 |
8 | ],
9 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
10 | "unwantedRecommendations": [
11 |
12 | ]
13 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to Kaikas Tutorial. As an open source project, Kaikas Tutorial is always open to the developer community and we welcome your contribution. Please read the guideline below and follow it in all interactions with the project.
4 |
5 | ## How to Contribute
6 |
7 | 1. Read this [contributing document](./CONTRIBUTING.md).
8 | 2. Sign [Contributor Licensing Agreement (CLA)](#contributor-license-agreement-cla).
9 | 3. Submit an issue with proper [labeling](#usage-of-labels).
10 | 4. Please wait until the label changes to `contribution welcome` - otherwise, it is not ready to be worked on.
11 | 5. After the label changed to `contribution welcome`, you can start working on the implementation. To avoid any duplicate efforts, it is recommended to update the issue so that other developers see someone working on the issue.
12 | 6. Before making a PR, please make sure you fully tested the code. It is highly recommended to provide the test code as well. After submitting the PR, wait for code review and approval. The reviewer may ask you for additional commits or changes.
13 | 7. Once the change has been approved, the PR is merged by the project moderator.
14 | 8. After merging the PR, we close the pull request. You can then delete the now obsolete branch.
15 |
16 | ## Types of Contribution
17 | There are various ways to contribute and participate. Please read the guidelines below regarding the process of each type of contribution.
18 |
19 | - [Issues and Bugs](#issues-and-bugs)
20 | - [Feature Requests](#feature-requests)
21 | - [Code Contribution](#code-contribution)
22 |
23 | ### Issues and Bugs
24 |
25 | If you find a bug or other issues in Kaikas Tutorial, please [submit an issue](https://github.com/klaytn/kaikas-tutorial/issues). Before submitting an issue, please invest some extra time to figure out that:
26 |
27 | - The issue is not a duplicate issue.
28 | - The issue has not been fixed in the latest release of Kaikas Tutorial.
29 | Please do not use the issue tracker for personal support requests. Use developer@klaytn.com for the personal support requests.
30 |
31 | When you report a bug, please make sure that your report has the following information.
32 | - Steps to reproduce the issue.
33 | - A clear and complete description of the issue.
34 | - Code and/or screen captures are highly recommended.
35 |
36 | After confirming your report meets the above criteria, [submit the issue](https://github.com/klaytn/kaikas-tutorial/issues). Please use [labels](#usage-of-labels) to categorize your issue.
37 |
38 | ### Feature Requests
39 |
40 | You can also use the [issue tracker](https://github.com/klaytn/kaikas-tutorial/issues) to request a new feature or enhancement. Note that any code contribution without an issue link will not be accepted. Please submit an issue explaining your proposal first so that Kaikas Tutorial community can fully understand and discuss the idea. Please use [labels](#usage-of-labels) for your feature request as well.
41 |
42 | #### Usage of Labels
43 |
44 | You can use the following labels:
45 |
46 | Labels for initial issue categories:
47 |
48 | - bug: Issues with the code-level bugs.
49 | - documentation: Issues with the documentation.
50 | - enhancement: Issues for enhancement requests.
51 |
52 | Status of open issues (will be tagged by the project moderators):
53 |
54 | - (no label): The default status.
55 | - need more information : The issue's creator needs to provide additional information to review.
56 | - reviewing: The issue is under review.
57 | - re-label needed: The label needs to be changed to confirmed as being a `bug` or future `enhancement`.
58 | - approved: The issue is confirmed as being a `bug` to be fixed or `enhancement` to be developed.
59 | - contribution welcome: The fix or enhancement is approved and you are invited to contribute to it.
60 |
61 | Status of closed issues:
62 |
63 | - fixed: A fix for the issue was provided.
64 | - duplicate: The issue is also reported in a different issue and is being managed there.
65 | - invalid: The issue cannot be reproduced.
66 | - reject: The issue is rejected after review.
67 |
68 | ### Code Contribution
69 |
70 | Please follow the coding style and quality requirements to satisfy the product standards. You must follow the coding style as best as you can when submitting code. Take note of naming conventions, separation of concerns, and formatting rules.
71 |
72 | ## Contributor License Agreement (CLA)
73 |
74 | Keep in mind when you submit your pull request, you'll need to sign the CLA via [CLA-Assistant](https://cla-assistant.io/klaytn/kaikas-tutorial) for legal purposes. You will have to sign the CLA just one time, either as an individual or corporation.
75 |
76 | You will be prompted to sign the agreement by CLA Assistant (bot) when you open a Pull Request for the first time.
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Kaikas Tutorial Authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Notice
2 | The features on this repo are integrated into the https://github.com/klaytn/klaytn-online-toolkit.
3 |
4 | # Kaikas Tutorial
5 |
6 | > [tutorial.kaikas.io](tutorial.kaikas.io)
7 |
8 | 
9 |
10 | ### 1) Introduction
11 | Kaikas Tutorial is a reference BApp that works with Kaikas. You can send Klaytn's various types of transactions in the Kaikas tutorial and refer to the source code to create your BApp.
12 |
13 | ### 2) Getting started
14 | 1. Open terminal
15 | 2. Clone the repo by running `git clone https://github.com/klaytn/kaikas-tutorial.git`
16 | 3. `cd kaikas-tutorial`
17 | 4. Run `npm install` to install node packages
18 | 5. Run `npm run local`
19 | 6. App should be running on https://localhost:8888
20 |
21 | #### Builds the app for production
22 | 1. Run `npm run build` to build app
23 | 2. Run `npm start`
24 | 3. App should be running on https://localhost:5555
25 |
26 |
27 | ### 3) npm package information
28 | > dependencies
29 | ```
30 | The Kaikas Tutorial project is optimized for caver-js version "1.3.2".
31 | caver-js needs confirmation before updating.
32 | ```
33 |
34 | ### 4) Directory Structure
35 | > Folder structure
36 | ```
37 | webpack.base.js // Base webpack settings
38 | webpack.dev.js // Settings for local development
39 | webpack.prod.js // Settings for build. (note: NODE_ENV= must be set to production)
40 |
41 | dist // Files built with 'npm run build'
42 | static // Contains static resources (index.html, images, font files etc...)
43 |
44 | 1. src
45 | src - pages // React page components
46 | src - components // React components
47 | src - constants // Constants used throughout the project
48 | src - klaytn // Klaytn related definition folder
49 | src - styles // Style util files. Contains color, size, font info and etc. as well as Sass at-rules
50 | index.js // Project build entry point.
51 | index.scss // .scss file for index.js mentioned above.
52 | ```
53 |
54 | ### 5) Web browser support scope
55 | > Supported browsers.
56 |
57 | Chrome | Safari | Firefox | IE Edge*
58 | ---------------------- | ---------------------- | ---------------------- | ----------------------
59 | Supported (Optimized) | Supported | Supported | Not supported
60 |
61 | ### 6) License
62 | Kaikas Tutorial is released under the [MIT license](./LICENSE).
63 |
64 | ```
65 | MIT License
66 |
67 | Copyright (c) 2020 Kaikas Tutorial Authors
68 |
69 | Permission is hereby granted, free of charge, to any person obtaining a copy
70 | of this software and associated documentation files (the "Software"), to deal
71 | in the Software without restriction, including without limitation the rights
72 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
73 | copies of the Software, and to permit persons to whom the Software is
74 | furnished to do so, subject to the following conditions:
75 |
76 | The above copyright notice and this permission notice shall be included in
77 | all copies or substantial portions of the Software.
78 |
79 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
81 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
82 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
83 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
84 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
85 | THE SOFTWARE.
86 | ```
87 |
88 | ### 7) Contributing
89 |
90 | As an open source project, Kaikas Tutorial is always welcoming your contribution. Please read our [CONTTIBUTING.md](./CONTRIBUTING.md) for a walk-through of the contribution process.
91 |
--------------------------------------------------------------------------------
/TERMS-OF-USE.md:
--------------------------------------------------------------------------------
1 | # Terms of Use
2 |
3 | ## 1. Your Use of Open Source Software
4 |
5 | We may make (but are not obligated to make) the source code of Klaytn Blockchain Network Platform ("Platform"), the software on the Platform, etc. for download as open source software. If you use this open source software, you agree to be bound by and comply with any license that applies to this open source software. You will not indicate that you are associated with us in connection with your use, modifications or distributions of this open source software.
6 |
7 | ## 2. Services Provided on the Platform
8 |
9 | The Platform is a combination of peer-to-peer subnetworks of nodes transmitting transactions and blocks to execute value transfers and run smart contracts. The Core Cell Network ("CCN"), which is one of the subnetworks that constitute the Platform, verifies and executes transactions that occur on the Platform. The CCN is operated by Klaytn Governance Council, which is a collective group of Core Cell Operators, and Klaytn is not directly involved in any services that are provided in or individual transactions that occur on the Platform.
10 |
11 | ## 3. Your Installation of BApp on the Platform
12 |
13 | Your use of open source software is free of charge. However, you may be required to pay a certain number of KLAY as a transaction fee in order to execute a transaction on the Platform, including the installation of the BApp on the Platform.
14 |
15 | Once transaction is executed successfully and respective block generation is verified successfully by the Platform’s mechanism, the block is irreversibly stored in the blockchain. As such, your installation of the BApp and any other transactions on the Platform, as well as the submission of transaction fee is final and irrevocable.
16 |
17 | ## 4. User Content
18 |
19 | If you or the users of your BApp post, upload, input, provide or submit any content on the Platform (collectively, your "User Content"), you must ensure that the User Content provided by you or the users of your BApp at that or at any other time is true, accurate, up to date and complete and that any User Content you or the users of your BApp post, upload, input, provide or submit via the Platform do not breach or infringe legal rights of any third party. To the extent that is technically possible, you agree to prevent, remove or block access of any User Content that you or the users of your BApp post, upload, input, provide or submit via the Platform that violate or may violate legal rights (such as rights of privacy and publicity) of others or any applicable laws or regulations. We do not own, control or endorse any User Content that is transmitted, stored or processed via the Platform or sent to us and we are not responsible or liable for any User Content. We make no assurance that any of Your Content will be secured or that such content will remain confidential.
20 |
21 | You are solely responsible and liable for all of your User Content and for your use of any interactive features, links or information or content on the Platform, and you represent and warrant that (i) you own all intellectual property rights (or have obtained all necessary permissions) to provide your User Content and to grant the licenses in these Terms of Use; (ii) your User Content will not violate any agreements or confidentiality obligations; and (iii) your User Content will not violate, infringe or misappropriate any intellectual property right or other proprietary right, including the right of publicity or privacy, of any person or entity.
22 |
23 | You shall not include in User Content, or upload, transmit to or create or include in the Services environment any production data or any sensitive, proprietary, confidential or other data with particular data protection requirements such as personal data or personally identifiable information relating to an identified or identifiable natural person.
24 |
25 | You are prohibited from using the Platform to post or transmit any threatening, libellous, defamatory, obscene, scandalous, inflammatory, pornographic or profane material, any material that is contrary to applicable local, federal, or international laws and regulations, or any material that could constitute or encourage unlawful conduct. You must ensure that your User Content do not include such materials. We may from time to time monitor or review material transmitted or posted using the Network, and we reserve the right to delete any material we deem inappropriate.
26 |
27 | We are under no obligation to do so and assume no responsibility or liability arising from any material transmitted or posted using the Platform.
28 |
29 | You understand that any information you or users of your BApp upload to the Platform will be distributed among the blockchain nodes and may not removable due to technical limitations of the blockchain technology.
30 |
31 | You are entirely responsible for any and all activities that occur under your account or your BApp (if any). You agree to notify us immediately of any unauthorized use of your User Content, your BApp or account or any other breach of security. We will not be liable for any loss or damages that you may incur as a result of someone else using your User Content, your BApp or account, either with or without your knowledge. However, you could be held liable for losses incurred by us or another party due to someone else using your User Content, your BApp or account. You may not use anyone else’s User Content, your BApp or account at any time without the permission of such person or entity.
32 |
33 | By posting, uploading, inputting, providing or submitting your User Content to the Platform, you grant to participants of the Platform and any necessary sub-licensees a non-exclusive, worldwide, perpetual, right and permission to use, reproduce, copy, edit, modify, translate, reformat, create derivative works from, distribute, transmit, publicly perform and publicly display your User Content and sub-license such rights to others.
34 |
35 | If we have reason to believe that there is likely to be a breach of security, breach or misuse of the Platform or if you breach any of your obligations under these terms, we may suspend your use of the Platform at any time and for any reason.
36 |
--------------------------------------------------------------------------------
/configs/default.env:
--------------------------------------------------------------------------------
1 | PORT=8888
2 | API_HOST='http://localhost'
3 | API_PORT='8888'
4 |
--------------------------------------------------------------------------------
/configs/devServer.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | module.exports = {
4 | contentBase: path.resolve(__dirname, '../static'),
5 | host: '0.0.0.0',
6 | port: 8888,
7 | compress: true,
8 | historyApiFallback: true,
9 | hot: true,
10 | inline: true,
11 | open: true,
12 | }
13 |
--------------------------------------------------------------------------------
/configs/index.js:
--------------------------------------------------------------------------------
1 |
2 | const path = require('path')
3 | const dotenv = require('dotenv')
4 |
5 | const envFilename = process.env.ENV_FILENAME || ''
6 | const envPath = path.resolve(__dirname, `${envFilename}.env`)
7 | const defaultEnvPath = path.resolve(__dirname, 'default.env')
8 |
9 | // load system env -> .env -> default.env
10 | dotenv.config({ path: envPath });
11 | dotenv.config({ path: defaultEnvPath });
12 |
13 | module.exports = {
14 | envPath,
15 | defaultEnvPath,
16 | }
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kaikas-tutorial",
3 | "version": "1.0.0",
4 | "description": "Kaikas Reference BApp",
5 | "main": "index.js",
6 | "author": "developer@klaytn.com",
7 | "license": "MIT",
8 | "scripts": {
9 | "build": "webpack --config ./webpack.prod.js",
10 | "start": "serve ./dist -p 5555",
11 | "local": "webpack-dev-server --config webpack.dev.js"
12 | },
13 | "repository": {
14 | "type": "git"
15 | },
16 | "dependencies": {
17 | "caver-js": "^1.3.2",
18 | "classnames": "^2.2.6",
19 | "dotenv": "^8.0.0",
20 | "dotenv-webpack": "^1.7.0",
21 | "git-revision-webpack-plugin": "^3.0.4",
22 | "lodash": "^4.17.15",
23 | "mini-css-extract-plugin": "^0.9.0",
24 | "optimize-css-assets-webpack-plugin": "^5.0.3",
25 | "react": "^16.8.6",
26 | "react-dom": "^16.8.6",
27 | "serve": "^11.3.0",
28 | "webpack-merge": "^4.2.2"
29 | },
30 | "devDependencies": {
31 | "@babel/core": "^7.5.5",
32 | "@babel/plugin-proposal-class-properties": "^7.5.5",
33 | "@babel/polyfill": "^7.4.4",
34 | "@babel/preset-env": "^7.5.5",
35 | "@babel/preset-react": "^7.0.0",
36 | "@babel/register": "^7.5.5",
37 | "babel-eslint": "^10.0.2",
38 | "babel-loader": "^8.0.6",
39 | "clean-webpack-plugin": "^1.0.0",
40 | "compression-webpack-plugin": "^3.0.0",
41 | "copy-webpack-plugin": "^5.0.3",
42 | "css-loader": "^3.1.0",
43 | "eslint": "^6.1.0",
44 | "eslint-config-airbnb": "^17.1.1",
45 | "eslint-plugin-import": "^2.18.2",
46 | "eslint-plugin-jsx-a11y": "^6.2.3",
47 | "eslint-plugin-react": "^7.14.3",
48 | "extract-text-webpack-plugin": "^4.0.0-beta.0",
49 | "html-webpack-plugin": "^3.2.0",
50 | "node-sass": "^4.12.0",
51 | "opn": "^6.0.0",
52 | "react-hot-loader": "^4.12.9",
53 | "redux-devtools-extension": "^2.13.8",
54 | "sass-loader": "^7.1.0",
55 | "style-loader": "^0.23.1",
56 | "uglifyjs-webpack-plugin": "^2.1.3",
57 | "webpack": "^4.37.0",
58 | "webpack-cli": "^3.3.6",
59 | "webpack-dev-middleware": "^3.7.0",
60 | "webpack-dev-server": "^3.7.2",
61 | "webpack-hot-middleware": "^2.25.0"
62 | },
63 | "eslintConfig": {
64 | "env": {
65 | "browser": true,
66 | "node": true
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import KaikasPage from 'pages/KaikasPage'
3 |
4 | import './App.scss'
5 |
6 | const App = () => {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 |
14 | export default App
15 |
--------------------------------------------------------------------------------
/src/App.scss:
--------------------------------------------------------------------------------
1 | .App {
2 | position: relative;
3 | width: 100%;
4 | height: 1px;
5 | min-width: 414px;
6 | min-height: 100%;
7 | }
8 |
--------------------------------------------------------------------------------
/src/components/AccountUpdate.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | import './AccountUpdate.scss'
8 |
9 | class AccountUpdate extends Component {
10 | constructor(props) {
11 | super(props)
12 | this.state = {
13 | from: props.from,
14 | publicKey: '',
15 | walletKey: '',
16 | gas: 3000000,
17 | txHash: null,
18 | receipt: null,
19 | error: null,
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = (e) => {
31 | this.setState({
32 | [e.target.name]: e.target.value,
33 | })
34 | }
35 |
36 | handleGenerateKeypair = () => {
37 | const { privateKey } = caver.klay.accounts.create()
38 | const publicKey = caver.klay.accounts.privateKeyToPublicKey(privateKey)
39 | const walletKey = `${privateKey}0x00${this.state.from}`
40 | this.setState({ publicKey, walletKey })
41 | }
42 |
43 | signTransaction = () => {
44 | const { from, gas, publicKey } = this.state
45 |
46 | caver.klay.sendTransaction({
47 | type: 'ACCOUNT_UPDATE',
48 | from,
49 | publicKey,
50 | gas,
51 | })
52 | .once('transactionHash', (transactionHash) => {
53 | console.log('txHash', transactionHash)
54 | this.setState({ txHash: transactionHash })
55 | })
56 | .once('receipt', (receipt) => {
57 | console.log('receipt', receipt)
58 | this.setState({ receipt: JSON.stringify(receipt) })
59 | })
60 | .once('error', (error) => {
61 | console.log('error', error)
62 | this.setState({ error: error.message })
63 | })
64 | }
65 |
66 | render() {
67 | const { from, publicKey, walletKey, gas, txHash, receipt, error } = this.state
68 |
69 | return (
70 |
118 | )
119 | }
120 | }
121 |
122 | export default AccountUpdate
123 |
--------------------------------------------------------------------------------
/src/components/AccountUpdate.scss:
--------------------------------------------------------------------------------
1 | .AccountUpdate {
2 | margin-bottom: 30px;
3 | }
4 |
5 | .AccountUpdate__generateKeypair {
6 | margin-bottom: 30px;
7 | padding: 20px;
8 | border: 1px solid $middle-grey;
9 | border-radius: 10px;
10 |
11 | & > .Input { margin-bottom: 0; }
12 | }
13 |
14 | .AccountUpdate__generateButton {
15 | margin-bottom: 10px;
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/AccountUpdateFD.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from './FeeDelegation';
7 |
8 | import './AccountUpdate.scss'
9 |
10 | class AccountUpdateFD extends Component {
11 | constructor(props) {
12 | super(props)
13 | this.state = {
14 | from: props.from,
15 | publicKey: '',
16 | walletKey: '',
17 | gas: 3000000,
18 | senderRawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | handleGenerateKeypair = () => {
36 | const { privateKey } = caver.klay.accounts.create()
37 | const publicKey = caver.klay.accounts.privateKeyToPublicKey(privateKey)
38 | const walletKey = `${privateKey}0x00${this.state.from}`
39 | this.setState({ publicKey, walletKey })
40 | }
41 |
42 | signTransaction = async () => {
43 | const { from, publicKey, gas } = this.state
44 |
45 | const txData = {
46 | type: 'FEE_DELEGATED_ACCOUNT_UPDATE',
47 | from,
48 | publicKey,
49 | gas,
50 | }
51 |
52 | const { rawTransaction: senderRawTransaction } = await caver.klay.signTransaction(txData)
53 |
54 | this.setState({
55 | senderAddress: from,
56 | senderRawTransaction,
57 | })
58 | }
59 |
60 | render() {
61 | const { from, publicKey, walletKey, ratio, gas, senderRawTransaction } = this.state
62 |
63 | return (
64 |
117 | )
118 | }
119 | }
120 |
121 | export default AccountUpdateFD
122 |
--------------------------------------------------------------------------------
/src/components/AccountUpdateFDRatio.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from './FeeDelegation';
7 |
8 | import './AccountUpdate.scss'
9 |
10 | class AccountUpdateFDRatio extends Component {
11 | constructor(props) {
12 | super(props)
13 | this.state = {
14 | from: props.from,
15 | publicKey: '',
16 | walletKey: '',
17 | ratio: '',
18 | gas: 3000000,
19 | senderRawTransaction: null,
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = (e) => {
31 | this.setState({
32 | [e.target.name]: e.target.value,
33 | })
34 | }
35 |
36 | handleGenerateKeypair = () => {
37 | const { privateKey } = caver.klay.accounts.create()
38 | const publicKey = caver.klay.accounts.privateKeyToPublicKey(privateKey)
39 | const walletKey = `${privateKey}0x00${this.state.from}`
40 | this.setState({ publicKey, walletKey })
41 | }
42 |
43 | signTransaction = async () => {
44 | const { from, publicKey, ratio, gas } = this.state
45 |
46 | const txData = {
47 | type: 'FEE_DELEGATED_ACCOUNT_UPDATE_WITH_RATIO',
48 | from,
49 | publicKey,
50 | feeRatio: ratio,
51 | gas,
52 | }
53 |
54 | const { rawTransaction: senderRawTransaction } = await caver.klay.signTransaction(txData)
55 |
56 | this.setState({
57 | senderAddress: from,
58 | senderRawTransaction,
59 | })
60 | }
61 |
62 | render() {
63 | const { from, publicKey, walletKey, ratio, gas, senderRawTransaction } = this.state
64 |
65 | return (
66 |
126 | )
127 | }
128 | }
129 |
130 | export default AccountUpdateFDRatio
131 |
--------------------------------------------------------------------------------
/src/components/AddToken.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Input from 'components/Input'
3 | import Button from 'components/Button'
4 |
5 | import './AddToken.scss'
6 |
7 | const BongToken = {
8 | tokenAddress: '0xEa51fb63dD8cfc8574BB158054D86CA786e00F87',
9 | tokenSymbol: 'BONG',
10 | tokenDecimals: 18,
11 | tokenImage: 'https://avatars3.githubusercontent.com/u/32095134?s=460&v=4',
12 | }
13 | class AddToken extends Component {
14 | state = {
15 | tokenAddress: '',
16 | tokenSymbol: '',
17 | tokenDecimals: '',
18 | tokenImage: '',
19 | }
20 |
21 | handleChange = (e) => {
22 | this.setState({
23 | [e.target.name]: e.target.value,
24 | })
25 | }
26 |
27 | handleAddToken = () => {
28 | const { tokenAddress, tokenSymbol, tokenDecimals, tokenImage } = this.state
29 | klaytn.sendAsync({
30 | method: 'wallet_watchAsset',
31 | params: {
32 | type: 'ERC20',
33 | options: {
34 | address: tokenAddress,
35 | symbol: tokenSymbol,
36 | decimals: tokenDecimals,
37 | image: tokenImage,
38 | },
39 | },
40 | id: Math.round(Math.random() * 100000),
41 | }, (err, result) => console.log(err, result))
42 | }
43 |
44 | addExampleToken = () => {
45 | const { tokenAddress, tokenSymbol, tokenDecimals, tokenImage } = BongToken
46 | this.setState({
47 | tokenAddress,
48 | tokenSymbol,
49 | tokenDecimals,
50 | tokenImage,
51 | }, () => this.handleAddToken())
52 | }
53 |
54 | render() {
55 | const { tokenAddress, tokenSymbol, tokenDecimals, tokenImage } = this.state
56 | return (
57 |
58 |
59 | # Sample Token
60 |
61 |
66 |
67 |
{`BongToken (${BongToken.tokenSymbol})`}
68 |
{BongToken.tokenAddress}
69 |
{`Decimals: ${BongToken.tokenDecimals}`}
70 |
74 |
75 |
76 |
77 |
112 |
113 | )
114 | }
115 | }
116 |
117 | export default AddToken
118 |
--------------------------------------------------------------------------------
/src/components/AddToken.scss:
--------------------------------------------------------------------------------
1 | .AddToken {
2 | .Input { margin-bottom: 10px; }
3 | }
4 |
5 | .AddToken__section {
6 | &:first-child {
7 | margin-bottom: 25px;
8 | padding-bottom: 25px;
9 | border-bottom: 1px solid $light-grey;
10 | }
11 | }
12 |
13 | .AddToken__title {
14 | color: $brownish-grey;
15 | margin-bottom: 15px;
16 | }
17 |
18 | .AddToken__sample {
19 | width: 530px;
20 | padding: 15px;
21 | line-height: 1.5;
22 | border: 1px solid $light-grey;
23 | border-radius: 5px;
24 | @include clear-both();
25 | }
26 |
27 | .AddToken__sampleImage {
28 | float: left;
29 | width: 50px;
30 | margin-right: 10px;
31 | border-radius: 50%;
32 | }
33 |
34 | .AddToken__sampleContent {
35 | float: right;
36 | }
37 |
38 | .AddToken__sampleName {
39 | font-size: 20px;
40 | font-weight: bold;
41 | color: $dark-brown;
42 | }
43 |
44 | .AddToken__sampleAddress {
45 | font-size: 16px;
46 | font-weight: bold;
47 | color: $brown-grey;
48 | }
49 |
50 | .AddToken__sampleDecimals {
51 | font-size: 12px;
52 | color: $brown-grey;
53 | margin-bottom: 10px;
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/Button.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import cx from 'classnames'
3 |
4 | import './Button.scss'
5 |
6 | const Button = ({
7 | className,
8 | title,
9 | onClick,
10 | icon,
11 | disabled,
12 | }) => {
13 | const iconStyle = {
14 | paddingLeft: '18px',
15 | background: `left / 12px no-repeat url('/images/${icon}')`,
16 | }
17 |
18 | return (
19 |
24 |
25 | {title}
26 |
27 |
28 | )
29 | }
30 |
31 | export default Button
32 |
--------------------------------------------------------------------------------
/src/components/Button.scss:
--------------------------------------------------------------------------------
1 | .Button {
2 | -webkit-appearance: none;
3 | width: 100%;
4 | background-color: $light-grey;
5 | color: $brown-grey;
6 | border-radius: 5px;
7 | text-align: center;
8 | font-size: 12px;
9 | font-weight: bold;
10 | padding: 23px;
11 | cursor: pointer;
12 | outline: none;
13 |
14 | &:hover,
15 | &:active {
16 | background-color: $dark-brown;
17 | color: $white;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/components/BytecodeExample.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './BytecodeExample.scss'
3 |
4 | const BytecodeExample = ({ network }) => (
5 |
6 |
# bytecode example (GX Token contract)
7 |
Copy and Paste bytecode into data field. Deploy 9999 GroundX Tokens!
8 |
9 | 0x60806040523480156200001157600080fd5b506040516200141b3803806200141b833981018060405260808110156200003757600080fd5b8101908080516401000000008111156200005057600080fd5b828101905060208101848111156200006757600080fd5b81518560018202830111640100000000821117156200008557600080fd5b50509291906020018051640100000000811115620000a257600080fd5b82810190506020810184811115620000b957600080fd5b8151856001820283011164010000000082111715620000d757600080fd5b5050929190602001805190602001909291908051906020019092919050505083600390805190602001906200010e929190620003c9565b50826004908051906020019062000127929190620003c9565b5081600560006101000a81548160ff021916908360ff1602179055506200016c33600560009054906101000a900460ff1660ff16600a0a83026200017660201b60201c565b5050505062000478565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200021a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b62000236816002546200034060201b62000e511790919060201c565b60028190555062000294816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200034060201b62000e511790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015620003bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200040c57805160ff19168380011785556200043d565b828001600101855582156200043d579182015b828111156200043c5782518255916020019190600101906200041f565b5b5090506200044c919062000450565b5090565b6200047591905b808211156200047157600081600090555060010162000457565b5090565b90565b610f9380620004886000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80633950935111610071578063395093511461025f57806370a08231146102c557806395d89b411461031d578063a457c2d7146103a0578063a9059cbb14610406578063dd62ed3e1461046c576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b66104e4565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610582565b604051808215151515815260200191505060405180910390f35b61019f610599565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105a3565b604051808215151515815260200191505060405180910390f35b610243610654565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610667565b604051808215151515815260200191505060405180910390f35b610307600480360360208110156102db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061070c565b6040518082815260200191505060405180910390f35b610325610754565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036557808201518184015260208101905061034a565b50505050905090810190601f1680156103925780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ec600480360360408110156103b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506107f2565b604051808215151515815260200191505060405180910390f35b6104526004803603604081101561041c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610897565b604051808215151515815260200191505060405180910390f35b6104ce6004803603604081101561048257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506108ae565b6040518082815260200191505060405180910390f35b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561057a5780601f1061054f5761010080835404028352916020019161057a565b820191906000526020600020905b81548152906001019060200180831161055d57829003601f168201915b505050505081565b600061058f338484610935565b6001905092915050565b6000600254905090565b60006105b0848484610b2c565b610649843361064485600160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610dc890919063ffffffff16565b610935565b600190509392505050565b600560009054906101000a900460ff1681565b600061070233846106fd85600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5190919063ffffffff16565b610935565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107ea5780601f106107bf576101008083540402835291602001916107ea565b820191906000526020600020905b8154815290600101906020018083116107cd57829003601f168201915b505050505081565b600061088d338461088885600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610dc890919063ffffffff16565b610935565b6001905092915050565b60006108a4338484610b2c565b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109bb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180610f446024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610efd6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180610f1f6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610c38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610eda6023913960400191505060405180910390fd5b610c89816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610dc890919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610d1c816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5190919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b600082821115610e40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080828401905083811015610ecf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b809150509291505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373a165627a7a723058202a10b39ea88b3c0eb48f5612d90a75e7ed5eeef2ac4cff2306e32940f8e220c30029000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000270f000000000000000000000000000000000000000000000000000000000000000d47726f756e645820546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024758000000000000000000000000000000000000000000000000000000000000
10 |
11 |
12 | )
13 |
14 | export default BytecodeExample
15 |
--------------------------------------------------------------------------------
/src/components/BytecodeExample.scss:
--------------------------------------------------------------------------------
1 | .BytecodeExample {
2 | padding: 20px 15px;
3 | margin-bottom: 20px;
4 | border: 1px solid #e1e1e1;
5 | border-radius: 5px;
6 |
7 | h3 {
8 | color: #707070;
9 | margin-bottom: 15px;
10 | }
11 |
12 | p {
13 | color: #999999;
14 | margin-bottom: 10px;
15 | }
16 |
17 | &__code {
18 | width: 100%;
19 | height: 70px;
20 | padding: 10px;
21 | background-color: #eaeaea;
22 | border-radius: 5px;
23 | word-break: break-all;
24 | overflow: scroll;
25 | }
26 | }
--------------------------------------------------------------------------------
/src/components/Dropdown.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import cx from 'classnames'
3 |
4 | import './Dropdown.scss'
5 |
6 | class Dropdown extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.setWrapperRef = this.setWrapperRef.bind(this);
10 | this.handleClickOutside = this.handleClickOutside.bind(this);
11 | }
12 |
13 | state = {
14 | isShow: false,
15 | }
16 |
17 | setWrapperRef(node) {
18 | this.wrapperRef = node;
19 | }
20 |
21 | componentDidMount() {
22 | document.addEventListener('mousedown', this.handleClickOutside);
23 | }
24 |
25 | componentWillUnmount() {
26 | document.removeEventListener('mousedown', this.handleClickOutside);
27 | }
28 |
29 | handleToggle = () => this.setState({ isShow: !this.state.isShow })
30 |
31 | handleClose = () => this.setState({ isShow: false })
32 |
33 | handleSelect = (item) => {
34 | this.props.handleSelect(item)
35 | this.handleClose()
36 | }
37 |
38 | handleClickOutside(event) {
39 | if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
40 | this.handleClose()
41 | }
42 | }
43 |
44 | render() {
45 | const { placeholder, list, className, selectedItem } = this.props
46 | const { isShow } = this.state
47 |
48 | return (
49 |
55 |
59 | {selectedItem || placeholder}
60 |
61 | {isShow &&
62 |
63 | {list.map((item) => (
64 |
this.handleSelect(item)}
68 | >
69 | {item}
70 |
71 | ))}
72 |
73 | }
74 |
75 | )
76 | }
77 | }
78 |
79 | export default Dropdown
80 |
--------------------------------------------------------------------------------
/src/components/Dropdown.scss:
--------------------------------------------------------------------------------
1 | .Dropdown {
2 | position: relative;
3 | text-align: left;
4 | color: $brown-grey;
5 | cursor: pointer;
6 | @include font-style('font-3');
7 | }
8 |
9 | .Dropdown__title {
10 | position: relative;
11 | color: $dark-brown;
12 | text-align: center;
13 | font-size: 16px;
14 | padding: 15px 24px 14px;
15 | border-radius: 3px;
16 | border: 1px solid $light-grey;
17 | background-color: white;
18 |
19 | &::after {
20 | content:"";
21 | position: absolute;
22 | top: 18px;
23 | right: 16px;
24 | display: inline-block;
25 | width: 12px;
26 | height: 12px;
27 | background: center / contain no-repeat url('/images/icon-downArrow.svg');
28 | }
29 |
30 | .Dropdown--active &::after {
31 | background: center / contain no-repeat url('/images/icon-upArrow.svg');
32 | }
33 | }
34 |
35 | .Dropdown__list {
36 | position: absolute;
37 | padding: 12px 0;
38 | border-bottom-left-radius: 3px;
39 | border-bottom-right-radius: 3px;
40 | background-color: #fff;
41 | box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.08);
42 |
43 | width: 100%;
44 | border: 1px solid $light-grey;
45 | border-radius: 3px;
46 | z-index: 10;
47 | }
48 |
49 | .Dropdown__listItem {
50 | text-align: left;
51 | padding: 16px 24px 15px;
52 |
53 | &:hover {
54 | color: $dark-brown;
55 | background-color: $light-grey;
56 | }
57 | &:nth-child(4) { border-top: 1px solid $light-grey; }
58 | &:nth-child(6) { border-top: 1px solid $light-grey; }
59 | &:nth-child(9) { border-top: 1px solid $light-grey; }
60 | &:nth-child(12) { border-top: 1px solid $light-grey; }
61 | &:nth-child(15) { border-top: 1px solid $light-grey; }
62 | &:nth-child(18) { border-top: 1px solid $light-grey; }
63 |
64 | &--white {
65 | color: $brown-grey;
66 | text-align: center;
67 | &:hover {
68 | background-color: $brown-grey;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/components/FeeDelegation.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react'
2 | import Caver from 'caver-js'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | import './FeeDelegation.scss'
8 |
9 | class FeeDelegation extends PureComponent {
10 | constructor(props) {
11 | super(props)
12 | this.state = {
13 | feePayerAddress: props.feePayerAddress,
14 | txHash: null,
15 | receipt: null,
16 | error: null,
17 | }
18 | }
19 |
20 | static getDerivedStateFromProps = (nextProps, prevState) => {
21 | if (nextProps.feePayerAddress !== prevState.feePayerAddress) {
22 | return { feePayerAddress: nextProps.feePayerAddress }
23 | }
24 | return null
25 | }
26 |
27 | handleChange = (e) => {
28 | this.setState({
29 | [e.target.name]: e.target.value,
30 | })
31 | }
32 |
33 | sendTransaction = () => {
34 | const { feePayerAddress } = this.state
35 | const caver = new Caver(window.klaytn)
36 | caver.klay.sendTransaction({
37 | senderRawTransaction: this.props.senderRawTransaction,
38 | feePayer: feePayerAddress,
39 | })
40 | .once('transactionHash', (transactionHash) => {
41 | console.log('txHash', transactionHash)
42 | this.setState({ txHash: transactionHash })
43 | })
44 | .once('receipt', (receipt) => {
45 | console.log('receipt', receipt)
46 | this.setState({ receipt: JSON.stringify(receipt) })
47 | })
48 | .once('error', (error) => {
49 | console.log('error', error)
50 | this.setState({ error: error.message })
51 | })
52 | }
53 |
54 | render() {
55 | const { feePayerAddress, txHash, receipt, error } = this.state
56 | return (
57 |
58 |
Fee Payer
59 |
66 |
70 |
75 |
76 | )
77 | }
78 | }
79 |
80 | export default FeeDelegation
--------------------------------------------------------------------------------
/src/components/FeeDelegation.scss:
--------------------------------------------------------------------------------
1 | .FeeDelegation {
2 | padding-top: 20px;
3 | margin-top: 20px;
4 | border-top: 1px dashed #ccc;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/GithubLink.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './GithubLink.scss'
3 |
4 | const GithubLink = ({ className, component }) => (
5 |
11 | View source code
12 |
13 | )
14 |
15 | export default GithubLink
16 |
--------------------------------------------------------------------------------
/src/components/GithubLink.scss:
--------------------------------------------------------------------------------
1 | .GithubLink {
2 | display: inline-block;
3 | width: 120px;
4 | margin-left: 8px;
5 | color: $brown-grey;
6 | text-align: right;
7 | font-size: 12px;
8 | cursor: pointer;
9 |
10 | &:hover { text-decoration: underline; }
11 |
12 | &::before {
13 | content: '';
14 | display: inline-block;
15 | width: 12px;
16 | height: 12px;
17 | vertical-align: text-top;
18 | margin-right: 3px;
19 | background: center / 12px no-repeat url('/images/icon-github.svg');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/Input.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import cx from 'classnames'
3 |
4 | import './Input.scss'
5 |
6 | const Input = ({
7 | className,
8 | type,
9 | name,
10 | label,
11 | value,
12 | onChange,
13 | placeholder,
14 | err,
15 | readOnly,
16 | }) => (
17 |
18 | {
19 | label &&
20 |
21 | {label}
22 |
23 | }
24 |
40 | {
41 | err &&
42 |
{err}
43 | }
44 |
45 | )
46 |
47 | export default Input
48 |
--------------------------------------------------------------------------------
/src/components/Input.scss:
--------------------------------------------------------------------------------
1 | .Input {
2 | position: relative;
3 | margin-bottom: 10px;
4 | }
5 |
6 | .Input__label {
7 | display: block;
8 | font-size: 12px;
9 | font-weight: bold;
10 | color: $brown-grey;
11 | margin-bottom: 8px;
12 | }
13 |
14 | .Input__input {
15 | width: 100%;
16 | font-size: 14px;
17 | border: 1px solid $light-grey;
18 | padding: 22px 24px;
19 | border-radius: 5px;
20 |
21 | &::placeholder { color: $middle-grey; }
22 | &--err { border-color: $alert-red; }
23 | &--readOnly {
24 | color: $middle-grey;
25 | }
26 | }
27 |
28 | .Input__err {
29 | position: absolute;
30 | top: 0;
31 | right: 0;
32 | font-size: 12px;
33 | color: $alert-red;
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/Message.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from 'react'
2 | import cx from 'classnames'
3 |
4 | import './Message.scss'
5 |
6 | const Message = ({
7 | className,
8 | type,
9 | message,
10 | }) => {
11 | return (
12 |
21 |
22 | {type === 'error' && 'error'}
23 | {type === 'txHash' && 'txHash'}
24 | {type === 'receipt' && 'receipt'}
25 | {type === 'signedMessage' && (
26 |
27 | Signed
28 | Message
29 |
30 | )}
31 | {type === 'rawTransaction' && (
32 |
33 | Signed
34 | Transaction
35 |
36 | )}
37 |
38 |
39 | {message}
40 |
41 |
42 | )
43 | }
44 |
45 | export default Message
46 |
--------------------------------------------------------------------------------
/src/components/Message.scss:
--------------------------------------------------------------------------------
1 | .Message {
2 | @include font-style('font-4');
3 | display: flex;
4 | align-items: center;
5 | padding: 10px 10px 10px 0;
6 | margin-bottom: 10px;
7 | border-radius: 5px;
8 | background-color: $black;
9 | word-break: break-all;
10 | color: white;
11 |
12 | &--error {
13 | .Message__status {
14 | color: $alert-red;
15 | background-image: url('/images/ico-error.svg');
16 | }
17 | .Message__message { color: $alert-red; }
18 | }
19 |
20 | &--txHash {
21 | .Message__status {
22 | padding-top: 0;
23 | color: $warning-yellow;
24 | background-image: none;
25 | .Message__message { color: $warning-yellow; }
26 | }
27 | }
28 |
29 | &--receipt {
30 | .Message__status {
31 | background-image: url('/images/ico-receipt.svg');
32 | }
33 | }
34 |
35 | &--rawTransaction,
36 | &--signedMessage {
37 | margin-top: 20px;
38 | .Message__status {
39 | padding-top: 25px;
40 | background-size: 22px 22px;
41 | background-image: url('/images/icon-tx.svg');
42 | }
43 | }
44 | }
45 |
46 | .Message__status {
47 | display: inline-block;
48 | width: 80px;
49 | padding-top: 18px;
50 | line-height: 1.1;
51 | background-repeat: no-repeat;
52 | background-position: top center;
53 | background-size: 14px 14px;
54 | text-align: center;
55 | font-weight: bold;
56 | color: white;
57 | }
58 |
59 | .Message__message {
60 | display: inline-block;
61 | width: calc(100% - 80px);
62 | max-height: 150px;
63 | overflow: scroll;
64 | font-size: 14px;
65 | color: white;
66 | }
67 |
--------------------------------------------------------------------------------
/src/components/Nav.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import cx from 'classnames'
3 | import { isNull } from 'lodash'
4 | import networks from 'constants/networks'
5 | import './Nav.scss'
6 |
7 | const Nav = ({ network }) => (
8 |
27 | )
28 |
29 | export default Nav
30 |
--------------------------------------------------------------------------------
/src/components/Nav.scss:
--------------------------------------------------------------------------------
1 | .Nav {
2 | width: 100%;
3 | height: 75px;
4 | position: sticky;
5 | top: 0;
6 | left: 0;
7 | z-index: 100;
8 | @include cardBox();
9 | }
10 |
11 | .Nav__inner {
12 | max-width: $max-page-width;
13 | height: 100%;
14 | margin: 0 auto;
15 | padding: 0 20px;
16 | display: flex;
17 | justify-content: space-between;
18 | align-items: center;
19 | }
20 |
21 | .Nav__logo {
22 | width: 160px;
23 | overflow: hidden;
24 | img { width: 180px; }
25 | }
26 |
27 | .Nav__network {
28 | padding: 2px 15px;
29 | border: 1px solid $dark-brown;
30 | border-radius: 12px;
31 | font-size: 12px;
32 | color: $dark-brown;
33 | text-align: center;
34 |
35 | &--loading {
36 | color: $brown-grey;
37 | border-color: $brown-grey;
38 | }
39 |
40 | &--error {
41 | color: $alert-red;
42 | border-color: $alert-red;
43 | }
44 |
45 | span {
46 | display: inline-block;
47 | margin-right: 6px;
48 | font-size: 10px;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/SignMessage.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Input from 'components/Input'
3 | import Button from 'components/Button'
4 | import Message from 'components/Message'
5 |
6 | class SignMessage extends Component {
7 | constructor(props) {
8 | super(props)
9 | this.state = {
10 | from: props.from,
11 | message: '',
12 | signedMessage: null,
13 | }
14 | }
15 |
16 | static getDerivedStateFromProps = (nextProps, prevState) => {
17 | if (nextProps.from !== prevState.from) {
18 | return { from: nextProps.from }
19 | }
20 | return null
21 | }
22 |
23 | handleChange = (e) => {
24 | this.setState({
25 | [e.target.name]: e.target.value,
26 | })
27 | }
28 |
29 | signMessage = async () => {
30 | const { from, message } = this.state
31 | const signedMessage = await caver.klay.sign(message, from)
32 | this.setState({ signedMessage })
33 | }
34 |
35 | render() {
36 | const {
37 | from,
38 | message,
39 | signedMessage,
40 | } = this.state
41 |
42 | return (
43 |
72 | )
73 | }
74 | }
75 |
76 | export default SignMessage
77 |
--------------------------------------------------------------------------------
/src/components/SmartContractDeploy.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 | import BytecodeExample from 'components/BytecodeExample'
7 |
8 | class SmartContractDeploy extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | data: '',
14 | value: 0,
15 | gas: 3000000,
16 | txHash: null,
17 | receipt: null,
18 | error: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | signTransaction = () => {
36 | const { from, data, value, gas } = this.state
37 |
38 | caver.klay.sendTransaction({
39 | type: 'SMART_CONTRACT_DEPLOY',
40 | from,
41 | data,
42 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
43 | gas,
44 | })
45 | .once('transactionHash', (transactionHash) => {
46 | console.log('txHash', transactionHash)
47 | this.setState({ txHash: transactionHash })
48 | })
49 | .once('receipt', (receipt) => {
50 | console.log('receipt', receipt)
51 | this.setState({ receipt: JSON.stringify(receipt) })
52 | })
53 | .once('error', (error) => {
54 | console.log('error', error)
55 | this.setState({ error: error.message })
56 | })
57 | }
58 |
59 | render() {
60 | const { from, data, value, gas, txHash, receipt, error } = this.state
61 |
62 | return (
63 |
64 |
65 |
73 |
80 |
87 |
94 |
98 |
103 |
104 | )
105 | }
106 | }
107 |
108 | export default SmartContractDeploy
109 |
--------------------------------------------------------------------------------
/src/components/SmartContractDeployFD.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 | import BytecodeExample from 'components/BytecodeExample'
8 |
9 | class SmartContractDeployFD extends Component {
10 | constructor(props) {
11 | super(props)
12 | this.state = {
13 | from: props.from,
14 | data: '',
15 | value: 0,
16 | gas: 3000000,
17 | senderAddress: '',
18 | senderRawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | signTransaction = async () => {
36 | const { from, data, gas, value } = this.state
37 |
38 | const txData = {
39 | type: 'FEE_DELEGATED_SMART_CONTRACT_DEPLOY',
40 | from,
41 | data,
42 | gas,
43 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
44 | }
45 |
46 | const { rawTransaction: senderRawTransaction } = await caver.klay.signTransaction(txData)
47 |
48 | this.setState({
49 | senderAddress: from,
50 | senderRawTransaction
51 | })
52 | }
53 |
54 | render() {
55 | const { from, data, gas, value, senderRawTransaction } = this.state
56 |
57 | return (
58 |
59 |
60 |
Sender
61 |
68 |
75 |
82 |
89 |
93 | {senderRawTransaction && (
94 |
98 | )}
99 |
103 |
104 | )
105 | }
106 | }
107 |
108 | export default SmartContractDeployFD
109 |
--------------------------------------------------------------------------------
/src/components/SmartContractDeployFDRatio.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 | import BytecodeExample from 'components/BytecodeExample'
8 |
9 | class SmartContractDeployFDRatio extends Component {
10 | constructor(props) {
11 | super(props)
12 | this.state = {
13 | from: props.from,
14 | data: '',
15 | value: 0,
16 | ratio: '',
17 | gas: 3000000,
18 | senderAddress: '',
19 | senderRawTransaction: null,
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = (e) => {
31 | this.setState({
32 | [e.target.name]: e.target.value,
33 | })
34 | }
35 |
36 | signTransaction = async () => {
37 | const { from, data, value, ratio, gas } = this.state
38 |
39 | const txData = {
40 | type: 'FEE_DELEGATED_SMART_CONTRACT_DEPLOY_WITH_RATIO',
41 | from,
42 | data,
43 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
44 | feeRatio: ratio,
45 | gas,
46 | }
47 |
48 | const { rawTransaction: senderRawTransaction } = await caver.klay.signTransaction(txData)
49 |
50 | this.setState({
51 | senderAddress: from,
52 | senderRawTransaction
53 | })
54 | }
55 |
56 | render() {
57 | const { from, data, value, ratio, gas, senderRawTransaction } = this.state
58 |
59 | return (
60 |
61 |
62 |
Sender
63 |
70 |
77 |
84 |
91 |
98 |
102 | {senderRawTransaction && (
103 |
107 | )}
108 |
112 |
113 | )
114 | }
115 | }
116 |
117 | export default SmartContractDeployFDRatio
118 |
--------------------------------------------------------------------------------
/src/components/SmartContractDeployLegacy.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 | import BytecodeExample from 'components/BytecodeExample'
7 |
8 | class SmartContractDeployLegacy extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | data: '',
14 | gas: 3000000,
15 | txHash: null,
16 | receipt: null,
17 | error: null,
18 | }
19 | }
20 |
21 | static getDerivedStateFromProps = (nextProps, prevState) => {
22 | if (nextProps.from !== prevState.from) {
23 | return { from: nextProps.from }
24 | }
25 | return null
26 | }
27 |
28 | handleChange = (e) => {
29 | this.setState({
30 | [e.target.name]: e.target.value,
31 | })
32 | }
33 |
34 | handleSmartContractDeploy = () => {
35 | const { from, data, gas } = this.state
36 |
37 | caver.klay.sendTransaction({
38 | from,
39 | data,
40 | gas,
41 | })
42 | .once('transactionHash', (transactionHash) => {
43 | console.log('txHash', transactionHash)
44 | this.setState({ txHash: transactionHash })
45 | })
46 | .once('receipt', (receipt) => {
47 | console.log('receipt', receipt)
48 | this.setState({ receipt: JSON.stringify(receipt) })
49 | })
50 | .once('error', (error) => {
51 | console.log('error', error)
52 | this.setState({ error: error.message })
53 | })
54 | }
55 |
56 | render() {
57 | const { from, data, gas, txHash, receipt, error } = this.state
58 |
59 | return (
60 |
61 |
62 |
69 |
76 |
83 |
87 |
92 |
93 | )
94 | }
95 | }
96 |
97 | export default SmartContractDeployLegacy
98 |
--------------------------------------------------------------------------------
/src/components/SmartContractExecution.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | class SmartContractExecution extends Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | from: props.from,
12 | to: '',
13 | amount: '',
14 | contractAddress: '',
15 | gas: 3000000,
16 | txHash: null,
17 | receipt: null,
18 | error: null,
19 | decimal: 18
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = e => {
31 | this.setState({
32 | [e.target.name]: e.target.value
33 | })
34 | }
35 |
36 | signTransaction = () => {
37 | const { from, contractAddress, to, amount, gas, decimal } = this.state
38 | if (decimal > 20) {
39 | return alert('decimal should be less than 21')
40 | }
41 |
42 | const data = caver.klay.abi.encodeFunctionCall(
43 | {
44 | name: 'transfer',
45 | type: 'function',
46 | inputs: [
47 | {
48 | type: 'address',
49 | name: 'recipient'
50 | },
51 | {
52 | type: 'uint256',
53 | name: 'amount'
54 | }
55 | ]
56 | },
57 | [
58 | to,
59 | caver.utils
60 | .toBN(amount)
61 | .mul(caver.utils.toBN(Number(`1e${decimal}`)))
62 | .toString()
63 | ]
64 | )
65 |
66 | caver.klay
67 | .sendTransaction({
68 | type: 'SMART_CONTRACT_EXECUTION',
69 | from,
70 | to: contractAddress,
71 | data,
72 | gas
73 | })
74 | .on('transactionHash', transactionHash => {
75 | console.log('txHash', transactionHash)
76 | this.setState({ txHash: transactionHash })
77 | })
78 | .on('receipt', receipt => {
79 | console.log('receipt', receipt)
80 | this.setState({ receipt: JSON.stringify(receipt) })
81 | })
82 | .on('error', error => {
83 | console.log('error', error)
84 | this.setState({ error: error.message })
85 | })
86 | }
87 |
88 | render() {
89 | const {
90 | from,
91 | to,
92 | amount,
93 | contractAddress,
94 | gas,
95 | txHash,
96 | receipt,
97 | error,
98 | decimal
99 | } = this.state
100 |
101 | return (
102 |
103 |
110 |
117 |
124 |
131 |
138 |
145 |
146 |
147 |
148 | )
149 | }
150 | }
151 |
152 | export default SmartContractExecution
153 |
--------------------------------------------------------------------------------
/src/components/SmartContractExecutionFD.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class SmartContractExecutionFD extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | amount: '',
15 | contractAddress: '',
16 | gas: 3000000,
17 | senderAddress: '',
18 | senderRawTransaction: null,
19 | decimal: 18
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = e => {
31 | this.setState({
32 | [e.target.name]: e.target.value
33 | })
34 | }
35 |
36 | signTransaction = async () => {
37 | const { from, to, amount, contractAddress, gas, decimal } = this.state
38 | if (decimal > 20) {
39 | return alert('decimal should be less than 21')
40 | }
41 |
42 | const data = caver.klay.abi.encodeFunctionCall(
43 | {
44 | name: 'transfer',
45 | type: 'function',
46 | inputs: [
47 | {
48 | type: 'address',
49 | name: 'recipient'
50 | },
51 | {
52 | type: 'uint256',
53 | name: 'amount'
54 | }
55 | ]
56 | },
57 | [
58 | to,
59 | caver.utils
60 | .toBN(amount)
61 | .mul(caver.utils.toBN(Number(`1e${decimal}`)))
62 | .toString()
63 | ]
64 | )
65 |
66 | const txData = {
67 | type: 'FEE_DELEGATED_SMART_CONTRACT_EXECUTION',
68 | from,
69 | to: contractAddress,
70 | gas,
71 | data
72 | }
73 |
74 | const {
75 | rawTransaction: senderRawTransaction
76 | } = await caver.klay.signTransaction(txData)
77 |
78 | this.setState({
79 | senderAddress: from,
80 | senderRawTransaction
81 | })
82 | }
83 |
84 | render() {
85 | const {
86 | from,
87 | to,
88 | amount,
89 | contractAddress,
90 | gas,
91 | senderRawTransaction,
92 | decimal
93 | } = this.state
94 |
95 | return (
96 |
97 |
104 |
111 |
118 |
125 |
132 |
139 |
140 | {senderRawTransaction && (
141 |
145 | )}
146 |
150 |
151 | )
152 | }
153 | }
154 |
155 | export default SmartContractExecutionFD
156 |
--------------------------------------------------------------------------------
/src/components/SmartContractExecutionFDRatio.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class SmartContractExecutionFDRatio extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | amount: '',
15 | contractAddress: '',
16 | ratio: '',
17 | gas: 3000000,
18 | senderAddress: '',
19 | senderRawTransaction: null,
20 | decimal: 18
21 | }
22 | }
23 |
24 | static getDerivedStateFromProps = (nextProps, prevState) => {
25 | if (nextProps.from !== prevState.from) {
26 | return { from: nextProps.from }
27 | }
28 | return null
29 | }
30 |
31 | handleChange = e => {
32 | this.setState({
33 | [e.target.name]: e.target.value
34 | })
35 | }
36 |
37 | signTransaction = async () => {
38 | const {
39 | from,
40 | to,
41 | amount,
42 | contractAddress,
43 | ratio,
44 | gas,
45 | decimal
46 | } = this.state
47 | if (decimal > 20) {
48 | return alert('decimal should be less than 21')
49 | }
50 |
51 | const data = caver.klay.abi.encodeFunctionCall(
52 | {
53 | name: 'transfer',
54 | type: 'function',
55 | inputs: [
56 | {
57 | type: 'address',
58 | name: 'recipient'
59 | },
60 | {
61 | type: 'uint256',
62 | name: 'amount'
63 | }
64 | ]
65 | },
66 | [
67 | to,
68 | caver.utils
69 | .toBN(amount)
70 | .mul(caver.utils.toBN(Number(`1e${decimal}`)))
71 | .toString()
72 | ]
73 | )
74 |
75 | const txData = {
76 | type: 'FEE_DELEGATED_SMART_CONTRACT_EXECUTION_WITH_RATIO',
77 | from,
78 | to: contractAddress,
79 | data,
80 | feeRatio: ratio,
81 | gas
82 | }
83 |
84 | const {
85 | rawTransaction: senderRawTransaction
86 | } = await caver.klay.signTransaction(txData)
87 |
88 | this.setState({
89 | senderAddress: from,
90 | senderRawTransaction
91 | })
92 | }
93 |
94 | render() {
95 | const {
96 | from,
97 | to,
98 | amount,
99 | contractAddress,
100 | gas,
101 | ratio,
102 | senderRawTransaction,
103 | decimal
104 | } = this.state
105 |
106 | return (
107 |
108 |
115 |
122 |
129 |
136 |
143 |
150 |
157 |
158 | {senderRawTransaction && (
159 |
163 | )}
164 |
168 |
169 | )
170 | }
171 | }
172 |
173 | export default SmartContractExecutionFDRatio
174 |
--------------------------------------------------------------------------------
/src/components/SmartContractExecutionLegacy.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | class SmartContractExecutionLegacy extends Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | from: props.from,
12 | to: '',
13 | amount: '',
14 | contractAddress: '',
15 | gas: '3000000',
16 | txHash: null,
17 | receipt: null,
18 | error: null,
19 | decimal: 18
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = e => {
31 | this.setState({
32 | [e.target.name]: e.target.value
33 | })
34 | }
35 |
36 | signTransaction = () => {
37 | const { from, contractAddress, to, amount, gas, decimal } = this.state
38 | if (decimal > 20) {
39 | return alert('decimal should be less than 21')
40 | }
41 |
42 | const data = caver.klay.abi.encodeFunctionCall(
43 | {
44 | name: 'transfer',
45 | type: 'function',
46 | inputs: [
47 | {
48 | type: 'address',
49 | name: 'recipient'
50 | },
51 | {
52 | type: 'uint256',
53 | name: 'amount'
54 | }
55 | ]
56 | },
57 | [
58 | to,
59 | caver.utils
60 | .toBN(amount)
61 | .mul(caver.utils.toBN(Number(`1e${decimal}`)))
62 | .toString()
63 | ]
64 | )
65 |
66 | caver.klay
67 | .sendTransaction({
68 | from,
69 | to: contractAddress,
70 | data,
71 | gas
72 | })
73 | .on('transactionHash', transactionHash => {
74 | console.log('txHash', transactionHash)
75 | this.setState({ txHash: transactionHash })
76 | })
77 | .on('receipt', receipt => {
78 | console.log('receipt', receipt)
79 | this.setState({ receipt: JSON.stringify(receipt) })
80 | })
81 | .on('error', error => {
82 | console.log('error', error)
83 | this.setState({ error: error.message })
84 | })
85 | }
86 |
87 | render() {
88 | const {
89 | from,
90 | to,
91 | amount,
92 | contractAddress,
93 | gas,
94 | txHash,
95 | receipt,
96 | error,
97 | decimal
98 | } = this.state
99 |
100 | return (
101 |
102 |
109 |
116 |
123 |
130 |
137 |
144 |
145 |
146 |
147 | )
148 | }
149 | }
150 |
151 | export default SmartContractExecutionLegacy
152 |
--------------------------------------------------------------------------------
/src/components/TxResult.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import cx from 'classnames'
3 | import Message from 'components/Message'
4 |
5 | import './TxResult.scss'
6 |
7 | const TxResult = ({ className, txHash, receipt, error }) => (
8 |
9 |
Transaction Result
10 | {txHash && (
11 |
15 | )}
16 | {receipt && (
17 |
21 | )}
22 | {error && (
23 |
27 | )}
28 |
29 | )
30 |
31 | export default TxResult
32 |
--------------------------------------------------------------------------------
/src/components/TxResult.scss:
--------------------------------------------------------------------------------
1 | .TxResult {
2 | padding-top: 20px;
3 | margin-top: 20px;
4 | border-top: 1px dashed $middle-grey;
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/ValueTransfer.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | class ValueTransfer extends Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | from: props.from,
12 | to: '',
13 | value: '',
14 | gas: 3000000,
15 | txHash: null,
16 | receipt: null,
17 | error: null,
18 | rawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | signTransaction = () => {
36 | const { from, to, value, gas } = this.state
37 |
38 | caver.klay.sendTransaction({
39 | type: 'VALUE_TRANSFER',
40 | from,
41 | to,
42 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
43 | gas,
44 | })
45 | .once('transactionHash', (transactionHash) => {
46 | console.log('txHash', transactionHash)
47 | this.setState({ txHash: transactionHash })
48 | })
49 | .once('receipt', (receipt) => {
50 | console.log('receipt', receipt)
51 | this.setState({ receipt: JSON.stringify(receipt) })
52 | })
53 | .once('error', (error) => {
54 | console.log('error', error)
55 | this.setState({ error: error.message })
56 | })
57 | }
58 |
59 | render() {
60 | const { from, to, value, gas, txHash, receipt, error } = this.state
61 |
62 | return (
63 |
64 |
71 |
78 |
85 |
92 |
96 |
101 |
102 | )
103 | }
104 | }
105 |
106 | export default ValueTransfer
107 |
--------------------------------------------------------------------------------
/src/components/ValueTransferFD.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class ValueTransferFDRatio extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | value: '',
15 | gas: 3000000,
16 | senderAddress: '',
17 | senderRawTransaction: null,
18 | }
19 | }
20 |
21 | static getDerivedStateFromProps = (nextProps, prevState) => {
22 | if (nextProps.from !== prevState.from) {
23 | return { from: nextProps.from }
24 | }
25 | return null
26 | }
27 |
28 | handleChange = (e) => {
29 | this.setState({
30 | [e.target.name]: e.target.value,
31 | })
32 | }
33 |
34 | signTransaction = async () => {
35 | const { from, to, value, gas } = this.state
36 |
37 | const txData = {
38 | type: 'FEE_DELEGATED_VALUE_TRANSFER',
39 | from,
40 | to,
41 | gas,
42 | value: caver.utils.toPeb(value, 'KLAY'),
43 | }
44 |
45 | const { rawTransaction: senderRawTransaction} = await caver.klay.signTransaction(txData)
46 |
47 | this.setState({
48 | senderAddress: from,
49 | senderRawTransaction
50 | })
51 | }
52 |
53 | render() {
54 | const { from, to, value, gas, senderAddress, senderRawTransaction } = this.state
55 |
56 | return (
57 |
58 |
Sender
59 |
66 |
73 |
80 |
87 |
91 | {senderRawTransaction && (
92 |
96 | )}
97 |
101 |
102 | )
103 | }
104 | }
105 |
106 | export default ValueTransferFDRatio
107 |
--------------------------------------------------------------------------------
/src/components/ValueTransferFDRatio.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class ValueTransferFD extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | value: '',
15 | ratio: '',
16 | gas: 3000000,
17 | senderAddress: '',
18 | senderRawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | signTransaction = async () => {
36 | const { from, to, value, gas, ratio } = this.state
37 |
38 | const txData = {
39 | type: 'FEE_DELEGATED_VALUE_TRANSFER_WITH_RATIO',
40 | from,
41 | to,
42 | value: caver.utils.toPeb(value, 'KLAY'),
43 | feeRatio: ratio,
44 | gas,
45 | }
46 |
47 | const { rawTransaction: senderRawTransaction} = await caver.klay.signTransaction(txData)
48 |
49 | this.setState({
50 | senderAddress: from,
51 | senderRawTransaction
52 | })
53 | }
54 |
55 | render() {
56 | const { from, to, value, ratio, gas, senderAddress, senderRawTransaction } = this.state
57 |
58 | return (
59 |
60 |
Sender
61 |
68 |
75 |
82 |
89 |
96 |
100 | {senderRawTransaction && (
101 |
105 | )}
106 |
110 |
111 | )
112 | }
113 | }
114 |
115 | export default ValueTransferFD
116 |
--------------------------------------------------------------------------------
/src/components/ValueTransferLegacy.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | class ValueTransferLegacy extends Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | from: props.from,
12 | to: '',
13 | value: '',
14 | gas: 3000000,
15 | txHash: null,
16 | receipt: null,
17 | error: null,
18 | rawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | signTransaction = () => {
36 | const { from, to, value, gas } = this.state
37 |
38 | caver.klay.sendTransaction({
39 | from,
40 | to,
41 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
42 | gas,
43 | })
44 | .once('transactionHash', (transactionHash) => {
45 | console.log('txHash', transactionHash)
46 | this.setState({ txHash: transactionHash })
47 | })
48 | .once('receipt', (receipt) => {
49 | console.log('receipt', receipt)
50 | this.setState({ receipt: JSON.stringify(receipt) })
51 | })
52 | .once('error', (error) => {
53 | console.log('error', error)
54 | this.setState({ error: error.message })
55 | })
56 | }
57 |
58 | render() {
59 | const { from, to, value, gas, txHash, receipt, error } = this.state
60 |
61 | return (
62 |
63 |
70 |
77 |
84 |
91 |
95 |
100 |
101 | )
102 | }
103 | }
104 |
105 | export default ValueTransferLegacy
106 |
--------------------------------------------------------------------------------
/src/components/ValueTransferMemo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import TxResult from 'components/TxResult'
6 |
7 | class ValueTransfer extends Component {
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | from: props.from,
12 | to: '',
13 | value: '',
14 | memo: '',
15 | gas: 3000000,
16 | txHash: null,
17 | receipt: null,
18 | error: null,
19 | rawTransaction: null,
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = (e) => {
31 | this.setState({
32 | [e.target.name]: e.target.value,
33 | })
34 | }
35 |
36 | handleValueTransfer = () => {
37 | const { from, to, value, memo, gas } = this.state
38 |
39 |
40 | caver.klay.sendTransaction({
41 | type: 'VALUE_TRANSFER_MEMO',
42 | from,
43 | to,
44 | value: caver.utils.toPeb(value.toString(), 'KLAY'),
45 | gas,
46 | data: memo,
47 | })
48 | .once('transactionHash', (transactionHash) => {
49 | console.log('txHash', transactionHash)
50 | this.setState({ txHash: transactionHash })
51 | })
52 | .once('receipt', (receipt) => {
53 | console.log('receipt', receipt)
54 | this.setState({ receipt: JSON.stringify(receipt) })
55 | })
56 | .once('error', (error) => {
57 | console.log('error', error)
58 | this.setState({ error: error.message })
59 | })
60 | }
61 |
62 | render() {
63 | const { from, to, value, gas, memo, txHash, receipt, error } = this.state
64 |
65 | return (
66 |
67 |
74 |
81 |
88 |
95 |
102 |
106 |
111 |
112 | )
113 | }
114 | }
115 |
116 | export default ValueTransfer
117 |
--------------------------------------------------------------------------------
/src/components/ValueTransferMemoFD.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class ValueTransferMemoFD extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | value: '',
15 | memo: '',
16 | gas: 3000000,
17 | senderAddress: '',
18 | senderRawTransaction: null,
19 | }
20 | }
21 |
22 | static getDerivedStateFromProps = (nextProps, prevState) => {
23 | if (nextProps.from !== prevState.from) {
24 | return { from: nextProps.from }
25 | }
26 | return null
27 | }
28 |
29 | handleChange = (e) => {
30 | this.setState({
31 | [e.target.name]: e.target.value,
32 | })
33 | }
34 |
35 | handleSignTransaction = async () => {
36 | const { from, to, value, memo, gas } = this.state
37 |
38 | const txData = {
39 | type: 'FEE_DELEGATED_VALUE_TRANSFER_MEMO',
40 | from,
41 | to,
42 | gas,
43 | value: caver.utils.toPeb(value, 'KLAY'),
44 | data: memo,
45 | }
46 |
47 | const { rawTransaction: senderRawTransaction} = await caver.klay.signTransaction(txData)
48 |
49 | this.setState({
50 | senderAddress: from,
51 | senderRawTransaction
52 | })
53 | }
54 |
55 | render() {
56 | const { from, to, value, memo, gas, senderAddress, senderRawTransaction } = this.state
57 |
58 | return (
59 |
60 |
Sender
61 |
68 |
75 |
82 |
89 |
96 |
100 | {senderRawTransaction && (
101 |
105 | )}
106 |
110 |
111 | )
112 | }
113 | }
114 |
115 | export default ValueTransferMemoFD
116 |
--------------------------------------------------------------------------------
/src/components/ValueTransferMemoFDRatio.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 | import Input from 'components/Input'
4 | import Button from 'components/Button'
5 | import Message from 'components/Message'
6 | import FeeDelegation from 'components/FeeDelegation'
7 |
8 | class ValueTransferMemoFDRatio extends Component {
9 | constructor(props) {
10 | super(props)
11 | this.state = {
12 | from: props.from,
13 | to: '',
14 | value: '',
15 | memo: '',
16 | ratio: '',
17 | gas: 3000000,
18 | senderAddress: '',
19 | senderRawTransaction: null,
20 | }
21 | }
22 |
23 | static getDerivedStateFromProps = (nextProps, prevState) => {
24 | if (nextProps.from !== prevState.from) {
25 | return { from: nextProps.from }
26 | }
27 | return null
28 | }
29 |
30 | handleChange = (e) => {
31 | this.setState({
32 | [e.target.name]: e.target.value,
33 | })
34 | }
35 |
36 | handleSignTransaction = async () => {
37 | const { from, to, value, memo, gas, ratio } = this.state
38 |
39 | const txData = {
40 | type: 'FEE_DELEGATED_VALUE_TRANSFER_MEMO_WITH_RATIO',
41 | from,
42 | to,
43 | gas,
44 | value: caver.utils.toPeb(value, 'KLAY'),
45 | data: memo,
46 | feeRatio: ratio,
47 | }
48 |
49 | const { rawTransaction: senderRawTransaction} = await caver.klay.signTransaction(txData)
50 |
51 | this.setState({
52 | senderAddress: from,
53 | senderRawTransaction
54 | })
55 | }
56 |
57 | render() {
58 | const { from, to, value, memo, ratio, gas, senderAddress, senderRawTransaction } = this.state
59 |
60 | return (
61 |
62 |
Sender
63 |
70 |
77 |
84 |
91 |
98 |
105 |
109 | {senderRawTransaction && (
110 |
114 | )}
115 |
119 |
120 | )
121 | }
122 | }
123 |
124 | export default ValueTransferMemoFDRatio
125 |
--------------------------------------------------------------------------------
/src/components/WalletInfo.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { KLAY_FAUCET } from 'constants/url'
3 |
4 | import './WalletInfo.scss'
5 |
6 | const WalletInfo = ({ address, balance }) => {
7 | return (
8 |
9 |
Wallet Information
10 |
11 |
12 | Wallet Address
13 | {address || 'Login with Kaikas :)'}
14 |
15 |
16 | Balance
17 | {balance}
18 | KLAY
19 |
20 |
21 |
22 | If you need small amount of Klay for testing.
23 |
29 | Run Klay Faucet
30 |
31 |
32 |
33 | )
34 | }
35 |
36 | export default WalletInfo
37 |
--------------------------------------------------------------------------------
/src/components/WalletInfo.scss:
--------------------------------------------------------------------------------
1 | .WalletInfo {
2 | width: 100%;
3 | padding-bottom: 20px;
4 | border-bottom: 1px solid $light-grey;
5 | }
6 |
7 | .WalletInfo__title {
8 | margin-bottom: 15px;
9 | }
10 |
11 | .WalletInfo__infoBox {
12 | width: 100%;
13 | font-size: 14px;
14 | margin-bottom: 10px;
15 | border: 1px solid $light-grey;
16 | border-radius: 5px;
17 | background-color: white;
18 | }
19 |
20 | .WalletInfo__info {
21 | @include textEllipsis();
22 | display: inline-block;
23 | padding: 12px 18px;
24 |
25 | &:first-child {
26 | width: 60%;
27 | border-right: 1px solid $light-grey;
28 | }
29 | &:nth-child(2) {
30 | width: 40%;
31 | }
32 | }
33 |
34 | .WalletInfo__label {
35 | display: block;
36 | font-size: 12px;
37 | font-weight: bold;
38 | color: $brown-grey;
39 | margin-bottom: 3px;
40 | }
41 |
42 | .WalletInfo__balance {
43 | @include textEllipsis();
44 | display: inline-block;
45 | max-width: calc(100% - 35px);
46 | vertical-align: bottom;
47 | }
48 |
49 | .WalletInfo__unit {
50 | display: inline-block;
51 | width: 35px;
52 | padding-left: 5px;
53 | text-align: right;
54 | }
55 |
56 | .WalletInfo__faucet {
57 | font-size: 12px;
58 | color: $brown-grey;
59 | text-align: right;
60 | padding-right: 10px;
61 | }
62 |
63 | .WalletInfo__link {
64 | display: inline-block;
65 | font-weight: bold;
66 | margin-left: 8px;
67 | cursor: pointer;
68 | &:hover { text-decoration: underline; }
69 | }
--------------------------------------------------------------------------------
/src/constants/networks.js:
--------------------------------------------------------------------------------
1 | const networks = {
2 | 8217: 'Mainnet Network',
3 | 1001: 'Baobab Network',
4 | loading: 'Connecting...'
5 | }
6 |
7 | export default networks
--------------------------------------------------------------------------------
/src/constants/url.js:
--------------------------------------------------------------------------------
1 | export const KLAY_FAUCET = 'https://baobab.wallet.klaytn.com/access?next=faucet'
2 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import App from './App'
4 |
5 | import './index.scss'
6 |
7 | const rootElement = document.getElementById('root')
8 |
9 | ReactDOM.render(
10 | ,
11 | rootElement
12 | )
13 |
--------------------------------------------------------------------------------
/src/index.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'SFUIText';
3 | font-style: normal;
4 | font-weight: bold;
5 | src: url('/fonts/SFUIText-Bold.ttf') format('truetype');
6 | font-display: swap;
7 | }
8 |
9 | @font-face {
10 | font-family: 'SFUIText';
11 | font-style: normal;
12 | font-weight: 600;
13 | src: url('/fonts/SFUIText-Semibold.ttf') format('truetype');
14 | font-display: swap;
15 | }
16 |
17 | @font-face {
18 | font-family: 'SFUIText';
19 | font-style: normal;
20 | font-weight: normal;
21 | src: url('/fonts/SFUIText-Regular.ttf') format('truetype');
22 | font-display: swap;
23 | }
24 |
25 | @font-face {
26 | font-family: 'SFUIText';
27 | font-style: normal;
28 | font-weight: 300;
29 | src: url('/fonts/SFUIText-Medium.ttf') format('truetype');
30 | font-display: swap;
31 | }
32 |
33 | @font-face {
34 | font-family: 'SFUIText';
35 | font-style: normal;
36 | font-weight: 200;
37 | src: url('/fonts/SFUIText-Light.ttf') format('truetype');
38 | font-display: swap;
39 | }
40 |
41 | html, body, #root { height: 100%; }
42 |
43 | html { font-size: 10px; }
44 |
45 | body {
46 | margin: 0;
47 | padding: 0;
48 | background-color: $bg-color;
49 | font-family: SFUIText, Apple SD Gothic Neo, sans-serif;
50 | font-size: 14px;
51 | line-height: 18px;
52 | color: $dark-brown;
53 |
54 | *, *::before, *::after {
55 | box-sizing: border-box;
56 | -webkit-font-smoothing: antialiased;
57 | -moz-osx-font-smoothing: grayscale;
58 | }
59 |
60 | a {
61 | color: inherit;
62 | text-decoration: none;
63 | }
64 |
65 | p, h1, h2, h3, h4, h5, h6 {
66 | margin: 0;
67 | }
68 |
69 | button, input, select, textarea {
70 | font-family: unset;
71 | }
72 |
73 | button {
74 | padding: unset;
75 | background-color: unset;
76 | border: unset;
77 | }
78 |
79 | ul {
80 | margin: 0;
81 | padding: 0;
82 | list-style: none;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/klaytn/caver.js:
--------------------------------------------------------------------------------
1 | import Caver from 'caver-js'
2 |
3 | const caver = new Caver(window.klaytn)
4 |
5 | export default caver
6 |
--------------------------------------------------------------------------------
/src/pages/KaikasPage.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import caver from 'klaytn/caver'
3 |
4 | import Nav from 'components/Nav'
5 | import WalletInfo from 'components/WalletInfo'
6 | import Dropdown from 'components/Dropdown'
7 | import GithubLink from 'components/GithubLink'
8 | import ValueTransferLegacy from 'components/ValueTransferLegacy'
9 | import SmartContractExecutionLegacy from 'components/SmartContractExecutionLegacy'
10 | import SmartContractDeployLegacy from 'components/SmartContractDeployLegacy'
11 | import AddToken from 'components/AddToken'
12 | import SignMessage from 'components/SignMessage'
13 | import ValueTransfer from 'components/ValueTransfer'
14 | import ValueTransferFD from 'components/ValueTransferFD'
15 | import ValueTransferFDRatio from 'components/ValueTransferFDRatio'
16 | import ValueTransferMemo from 'components/ValueTransferMemo'
17 | import ValueTransferMemoFD from 'components/ValueTransferMemoFD'
18 | import ValueTransferMemoFDRatio from 'components/ValueTransferMemoFDRatio'
19 | import AccountUpdate from 'components/AccountUpdate'
20 | import AccountUpdateFD from 'components/AccountUpdateFD'
21 | import AccountUpdateFDRatio from 'components/AccountUpdateFDRatio'
22 | import SmartContractDeploy from 'components/SmartContractDeploy'
23 | import SmartContractDeployFD from 'components/SmartContractDeployFD'
24 | import SmartContractDeployFDRatio from 'components/SmartContractDeployFDRatio'
25 | import SmartContractExecution from 'components/SmartContractExecution'
26 | import SmartContractExecutionFD from 'components/SmartContractExecutionFD'
27 | import SmartContractExecutionFDRatio from 'components/SmartContractExecutionFDRatio'
28 |
29 | import './KaikasPage.scss'
30 |
31 | const txTypeList = {
32 | 'Value Transfer (Legacy)': 'ValueTransferLegacy',
33 | 'Smart Contract Deploy (Legacy)': 'SmartContractDeployLegacy',
34 | 'Token Transfer (Legacy)': 'SmartContractExecutionLegacy',
35 | 'Add Token': 'AddToken',
36 | 'Sign Message': 'SignMessage',
37 | 'Value Transfer': 'ValueTransfer',
38 | 'Value Transfer (Fee Delegation)': 'ValueTransferFD',
39 | 'Value Transfer (Fee Delegation with Ratio)': 'ValueTransferFDRatio',
40 | 'Value Transfer with Memo': 'ValueTransferMemo',
41 | 'Value Transfer with Memo (Fee Delegation)': 'ValueTransferMemoFD',
42 | 'Value Transfer with Memo (Fee Delegation with Ratio)': 'ValueTransferMemoFDRatio',
43 | 'Account Update': 'AccountUpdate',
44 | 'Account Update (Fee Delegation)': 'AccountUpdateFD',
45 | 'Account Update (Fee Delegation with Ratio)': 'AccountUpdateFDRatio',
46 | 'Smart Contract Deploy': 'SmartContractDeploy',
47 | 'Smart Contract Deploy (Fee Delegation)': 'SmartContractDeployFD',
48 | 'Smart Contract Deploy (Fee Delegation with Ratio)': 'SmartContractDeployFDRatio',
49 | 'Token Transfer': 'SmartContractExecution',
50 | 'Token Transfer (Fee Delegation)': 'SmartContractExecutionFD',
51 | 'Token Transfer (Fee Delegation with Ratio)': 'SmartContractExecutionFDRatio',
52 | }
53 |
54 | class KaikasPage extends Component {
55 | constructor(props) {
56 | super(props)
57 | this.state = {
58 | txType: null,
59 | account: '',
60 | balance: 0,
61 | network: null,
62 | }
63 | }
64 |
65 | componentDidMount() {
66 | this.loadAccountInfo()
67 | this.setNetworkInfo()
68 | }
69 |
70 | loadAccountInfo = async () => {
71 | const { klaytn } = window
72 |
73 | if (klaytn) {
74 | try {
75 | await klaytn.enable()
76 | this.setAccountInfo(klaytn)
77 | klaytn.on('accountsChanged', () => this.setAccountInfo(klaytn))
78 | } catch (error) {
79 | console.log('User denied account access')
80 | }
81 | } else {
82 | console.log('Non-Kaikas browser detected. You should consider trying Kaikas!')
83 | }
84 | }
85 |
86 | setAccountInfo = async () => {
87 | const { klaytn } = window
88 | if (klaytn === undefined) return
89 |
90 | const account = klaytn.selectedAddress
91 | const balance = await caver.klay.getBalance(account)
92 | this.setState({
93 | account,
94 | balance: caver.utils.fromPeb(balance, 'KLAY'),
95 | })
96 | }
97 |
98 | setNetworkInfo = () => {
99 | const { klaytn } = window
100 | if (klaytn === undefined) return
101 |
102 | this.setState({ network: klaytn.networkVersion })
103 | klaytn.on('networkChanged', () => this.setNetworkInfo(klaytn.networkVersion))
104 | }
105 |
106 | selectTxType = (txType) => this.setState({ txType })
107 |
108 | renderTxExample = (txType, from) => {
109 | switch (txType) {
110 | case 'Value Transfer (Legacy)':
111 | return
112 | case 'Smart Contract Deploy (Legacy)':
113 | return
114 | case 'Token Transfer (Legacy)':
115 | return
116 | case 'Add Token':
117 | return
118 | case 'Sign Message':
119 | return
120 | case 'Value Transfer':
121 | return
122 | case 'Value Transfer (Fee Delegation)':
123 | return
124 | case 'Value Transfer (Fee Delegation with Ratio)':
125 | return
126 | case 'Value Transfer with Memo':
127 | return
128 | case 'Value Transfer with Memo (Fee Delegation)':
129 | return
130 | case 'Value Transfer with Memo (Fee Delegation with Ratio)':
131 | return
132 | case 'Smart Contract Deploy':
133 | return
134 | case 'Smart Contract Deploy (Fee Delegation)':
135 | return
136 | case 'Smart Contract Deploy (Fee Delegation with Ratio)':
137 | return
138 | case 'Token Transfer':
139 | return
140 | case 'Token Transfer (Fee Delegation)':
141 | return
142 | case 'Token Transfer (Fee Delegation with Ratio)':
143 | return
144 | case 'Account Update':
145 | return
146 | case 'Account Update (Fee Delegation)':
147 | return
148 | case 'Account Update (Fee Delegation with Ratio)':
149 | return
150 | default:
151 | return (Select a Transaction example :D
)
152 | }
153 | }
154 |
155 | render() {
156 | const { account, balance, txType, network } = this.state
157 | const txTypeTitles = Object.keys(txTypeList)
158 |
159 | return (
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
175 |
176 |
177 | {txType}
178 | {txType && }
179 |
180 | {this.renderTxExample(txType, account)}
181 |
182 |
183 |
184 |
185 | )
186 | }
187 | }
188 |
189 | export default KaikasPage
190 |
--------------------------------------------------------------------------------
/src/pages/KaikasPage.scss:
--------------------------------------------------------------------------------
1 | .KaikasPage {
2 | width: 100%;
3 | height: 100%;
4 | }
5 |
6 | .KaikasPage__githubLink {
7 | width: 32px;
8 | height: 32px;
9 | position: fixed;
10 | bottom: 35px;
11 | right: 35px;
12 | z-index: 9999;
13 | transition: opacity .2s;
14 |
15 | &:hover { opacity: .8; }
16 | }
17 |
18 | .KaikasPage__main {
19 | width: 100%;
20 | min-height: 100%;
21 | max-width: 700px;
22 | margin: 0 auto;
23 | padding-top: 70px;
24 | padding: 60px 10px;
25 |
26 | h3 { margin-bottom: 15px; }
27 | }
28 |
29 | .KaikasPage__content {
30 | padding: 40px 0;
31 | }
32 |
33 | .KaikasPage__txExample {
34 | padding: 15px 20px 20px 20px;
35 | }
36 |
37 | .KaikasPage__txExampleHeader {
38 | display: flex;
39 | justify-content: space-between;
40 | align-items: baseline;
41 | padding-bottom: 15px;
42 | }
43 |
44 | .KaikasPage__txExampleTitle {
45 | width: calc(100% - 120px);
46 | @include textEllipsis();
47 | }
48 |
49 | .KaikasPage__dropdown {
50 | margin-bottom: 20px;
51 | }
52 |
53 | .KaikasPage__guide {
54 | padding: 30px 0;
55 | text-align: center;
56 | font-size: 18px;
57 | font-weight: bold;
58 | }
--------------------------------------------------------------------------------
/src/styles/_colors.scss:
--------------------------------------------------------------------------------
1 | $alert-red: rgb(245,65,55); // #f54137
2 | $warning-yellow: rgb(245,166,10); // #f5a60a
3 | $bg-color: rgb(250,250,250); // #fafafa
4 | $border-grey: rgb(234,234,234); // #eaeaea
5 | $light-grey: rgb(225,225,225); // #e1e1e1
6 | $middle-grey: rgb(204,204,204); // #cccccc
7 | $brown-grey: rgb(153,153,153); // #999999
8 | $brownish-grey: rgb(112,112,112); // #707070
9 | $dark-brown: rgb(79,71,62); // #4f473e
10 | $black: rgb(19,20,31); // #13141F
11 | $white: rgb(255,255,255); // #ffffff
12 |
--------------------------------------------------------------------------------
/src/styles/_fonts.scss:
--------------------------------------------------------------------------------
1 | @mixin font-style($type) {
2 | @if $type == 'font-1' {
3 | font-size: 11px;
4 | line-height: 18px;
5 | font-family: 'Roboto';
6 | font-weight: bold;
7 | }
8 |
9 | @else if $type == 'font-2' {
10 | font-size: 11px;
11 | line-height: 18px;
12 | font-family: 'Roboto';
13 | font-weight: normal;
14 | }
15 |
16 | @else if $type == 'font-3' {
17 | font-size: 14px;
18 | line-height: 18px;
19 | font-family: 'GoogleSans';
20 | font-weight: bold;
21 | }
22 |
23 | @else if $type == 'font-4' {
24 | font-size: 12px;
25 | line-height: 18px;
26 | font-family: 'RobotoMono';
27 | }
28 |
29 | @else if $type == 'font-5' {
30 | font-size: 10px;
31 | line-height: 18px;
32 | font-family: 'Roboto';
33 | font-weight: bold;
34 | }
35 |
36 | @else if $type == 'font-6' {
37 | font-size: 10px;
38 | line-height: 18px;
39 | font-family: 'Roboto';
40 | }
41 |
42 | @else if $type == 'font-7' {
43 | font-size: 10px;
44 | line-height: 18px;
45 | font-family: 'RobotoMono';
46 | }
47 |
48 | @else if $type == 'font-8' {
49 | font-size: 13px;
50 | line-height: 18px;
51 | font-family: 'Roboto';
52 | font-weight: normal;
53 | }
54 |
55 | @else if $type == 'font-9' {
56 | font-size: 13px;
57 | line-height: 18px;
58 | font-family: 'Roboto';
59 | font-weight: bold;
60 | }
61 |
62 | @else if $type == 'font-10' {
63 | font-size: 12px;
64 | line-height: 18px;
65 | font-family: 'Roboto';
66 | font-weight: normal;
67 | }
68 |
69 | @else if $type == 'font-11' {
70 | font-size: 12px;
71 | line-height: 18px;
72 | font-family: 'RobotoMono';
73 | font-weight: normal;
74 | }
75 |
76 | @else if $type == 'font-12' {
77 | font-size: 12px;
78 | line-height: 18px;
79 | font-family: 'Roboto';
80 | font-weight: bold;
81 | }
82 | }
83 |
84 | /*
85 | 1.
86 | font-size: 11px;
87 | line-height: 18px;
88 | font-family: 'Roboto';
89 | font-weight: bold;
90 |
91 | 2.
92 | font-size: 11px;
93 | line-height: 18px;
94 | font-family: 'Roboto';
95 | font-weight: normal;
96 |
97 | */
98 |
--------------------------------------------------------------------------------
/src/styles/_mixins.scss:
--------------------------------------------------------------------------------
1 | $max-page-width: 935px;
2 | $min-page-width: 320px;
3 | $max-card-width: 600px;
4 |
5 | @mixin breakpoint($breakpoint) {
6 | @if $breakpoint == "max-page" {
7 | @media screen and (max-width: $max-page-width - 1) {
8 | @content;
9 | }
10 | }
11 | @else if $breakpoint == "max-card" {
12 | @media screen and (max-width: $max-card-width - 1) {
13 | @content;
14 | }
15 | }
16 | }
17 |
18 | @mixin fixed-center() {
19 | position: fixed;
20 | top: 50%;
21 | left: 50%;
22 | transform: translate(-50%, -50%);
23 | }
24 |
25 | @mixin absolute-center() {
26 | position: absolute;
27 | top: 50%;
28 | left: 50%;
29 | transform: translate(-50%, -50%);
30 | }
31 |
32 | @mixin borderBox($radius){
33 | background-color: #fff;
34 | border: 1px solid $light-grey;
35 | @if $radius == yes {
36 | border-radius: 3px;
37 | }
38 | }
39 |
40 | @mixin cardBox(){
41 | background-color: #fff;
42 | border: 1px solid $light-grey;
43 | }
44 |
45 | @mixin imageReplacement($width, $height, $url, $bgColor) {
46 | width: $width;
47 | height: $height;
48 | overflow: hidden;
49 | &::after {
50 | content: "";
51 | position: absolute;
52 | top: 0;
53 | left: 0;
54 | width: $width;
55 | height: $height;
56 | background: center / contain no-repeat url($url) $bgColor;
57 | }
58 | }
59 |
60 | @mixin clear-both() {
61 | &:after {
62 | content: "";
63 | display: block;
64 | clear: both;
65 | }
66 | }
67 |
68 | @mixin textEllipsis() {
69 | overflow: hidden;
70 | text-overflow: ellipsis;
71 | white-space: nowrap;
72 | }
73 |
74 | @mixin breakWord() {
75 | overflow: hidden;
76 | white-space: normal;
77 | word-wrap: break-word;
78 | }
--------------------------------------------------------------------------------
/src/styles/_sizes.scss:
--------------------------------------------------------------------------------
1 | $max-page-width: 935px;
2 | $max-card-width: 600px;
3 |
--------------------------------------------------------------------------------
/src/styles/_variables.scss:
--------------------------------------------------------------------------------
1 | @import "./colors.scss";
2 | @import "./sizes.scss";
3 | @import "./mixins.scss";
4 | @import "./fonts.scss";
--------------------------------------------------------------------------------
/static/fonts/SFUIText-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/fonts/SFUIText-Bold.ttf
--------------------------------------------------------------------------------
/static/fonts/SFUIText-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/fonts/SFUIText-Light.ttf
--------------------------------------------------------------------------------
/static/fonts/SFUIText-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/fonts/SFUIText-Medium.ttf
--------------------------------------------------------------------------------
/static/fonts/SFUIText-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/fonts/SFUIText-Regular.ttf
--------------------------------------------------------------------------------
/static/fonts/SFUIText-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/fonts/SFUIText-Semibold.ttf
--------------------------------------------------------------------------------
/static/images/favicon@16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/favicon@16.png
--------------------------------------------------------------------------------
/static/images/ico-error.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/static/images/ico-receipt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/static/images/icon-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/icon-close.png
--------------------------------------------------------------------------------
/static/images/icon-downArrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/static/images/icon-github.svg:
--------------------------------------------------------------------------------
1 | GitHub icon
--------------------------------------------------------------------------------
/static/images/icon-tx.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
16 |
17 |
--------------------------------------------------------------------------------
/static/images/icon-upArrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/static/images/icon-wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/icon-wallet.png
--------------------------------------------------------------------------------
/static/images/kaikas-tutorial-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/kaikas-tutorial-screen.png
--------------------------------------------------------------------------------
/static/images/klaytn-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/klaytn-logo.png
--------------------------------------------------------------------------------
/static/images/logo-kaikas-tutorial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/klaytn/kaikas-tutorial/7a6b5f5d377b27cd8f3e412b4906da52fd3411fc/static/images/logo-kaikas-tutorial.png
--------------------------------------------------------------------------------
/static/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Kaikas Tutorial
9 |
10 |
11 |
12 | You need to enable JavaScript to run this app.
13 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/webpack.base.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const CopyWebpackPlugin = require('copy-webpack-plugin')
3 | const Dotenv = require('dotenv-webpack')
4 | const { envPath, defaultEnvPath } = require('./configs')
5 |
6 | module.exports = {
7 | entry: [
8 | '@babel/polyfill',
9 | path.resolve(__dirname, 'src/index.js'),
10 | ],
11 | module: {
12 | rules: [
13 | {
14 | test: /\.js$/,
15 | exclude: /node_modules/,
16 | use: {
17 | loader: 'babel-loader',
18 | },
19 | },
20 | ],
21 | },
22 | resolve: {
23 | modules: [
24 | 'node_modules',
25 | path.resolve(__dirname, 'src'),
26 | ],
27 | extensions: ['.js'],
28 | },
29 | plugins: [
30 | new CopyWebpackPlugin([
31 | {
32 | from: path.resolve(__dirname, 'static'),
33 | to: path.resolve(__dirname, 'dist'),
34 | ignore: ['*.ejs'],
35 | },
36 | ]),
37 | new Dotenv({
38 | path: envPath,
39 | defaults: defaultEnvPath,
40 | systemvars: true,
41 | }),
42 | ],
43 | }
44 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const fs = require('fs')
3 | const merge = require('webpack-merge')
4 | const { HotModuleReplacementPlugin, DefinePlugin } = require('webpack')
5 | const HtmlWebpackPlugin = require('html-webpack-plugin')
6 | const GitRevisionPlugin = require('git-revision-webpack-plugin')
7 |
8 | const baseConfig = require('./webpack.base')
9 | const devServerConfig = require('./configs/devServer.config')
10 |
11 | const gitRevisionPlugin = new GitRevisionPlugin()
12 |
13 | module.exports = merge(baseConfig, {
14 | mode: 'development',
15 | devtool: 'inline-source-map',
16 | output: {
17 | filename: '[name].bundle.js',
18 | publicPath: '/',
19 | path: path.resolve(__dirname, 'dist'),
20 | },
21 | devServer: devServerConfig,
22 | module: {
23 | rules: [
24 | {
25 | test: /\.scss$/,
26 | use: [
27 | 'style-loader',
28 | {
29 | loader: 'css-loader',
30 | options: { importLoaders: 1 },
31 | },
32 | {
33 | loader: 'sass-loader',
34 | options: {
35 | includePaths: [path.resolve(__dirname, 'src/styles')],
36 | data: '@import "./src/styles/_variables.scss";',
37 | },
38 | },
39 | ],
40 | },
41 | ],
42 | },
43 | plugins: [
44 | new HtmlWebpackPlugin({
45 | title: 'dev',
46 | template: path.resolve(__dirname, 'static/index.html'),
47 | inject: true,
48 | origin: `http://localhost:8888/`,
49 | }),
50 | new DefinePlugin({
51 | DEV: true,
52 | 'process.env.version': JSON.stringify(gitRevisionPlugin.commithash().slice(0, 7)), // TODO: delete when real
53 | }),
54 | new HotModuleReplacementPlugin(),
55 | ],
56 | })
57 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const fs = require('fs')
3 | const merge = require('webpack-merge')
4 | const { DefinePlugin } = require('webpack')
5 | const CleanWebpackPlugin = require('clean-webpack-plugin')
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
7 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const CompressionPlugin = require('compression-webpack-plugin')
11 | const GitRevisionPlugin = require('git-revision-webpack-plugin')
12 |
13 | const baseConfig = require('./webpack.base')
14 |
15 | const gitRevisionPlugin = new GitRevisionPlugin()
16 |
17 | const ENV = process.env.NODE_ENV
18 | const isProduction = ENV === 'production'
19 | const isDev = ENV === 'dev'
20 |
21 | module.exports = merge(baseConfig, {
22 | mode: 'production',
23 | devtool: isDev ? 'cheap-eval-source-map' : false,
24 | output: {
25 | filename: '[name].[hash].bundle.js',
26 | chunkFilename: '[name].[chunkhash].js',
27 | publicPath: '/',
28 | path: path.resolve(__dirname, 'dist'),
29 | },
30 | module: {
31 | rules: [
32 | {
33 | test: /\.scss$/,
34 | use: [
35 | MiniCssExtractPlugin.loader,
36 | {
37 | loader: 'css-loader',
38 | options: { importLoaders: 1 },
39 | },
40 | {
41 | loader: 'sass-loader',
42 | options: {
43 | includePaths: [path.resolve(__dirname, 'src/styles')],
44 | data: '@import "./src/styles/_variables.scss";',
45 | },
46 | },
47 | ],
48 | },
49 | ],
50 | },
51 | plugins: [
52 | new CleanWebpackPlugin('dist', { root: __dirname }),
53 | new OptimizeCssAssetsPlugin(),
54 | new CopyWebpackPlugin([{
55 | from: path.resolve(__dirname, 'static'),
56 | to: path.resolve(__dirname, 'dist'),
57 | ignore: ['*.ejs'],
58 | }]),
59 | new DefinePlugin({
60 | DEV: false,
61 | 'process.env.NODE_ENV': JSON.stringify('production'),
62 | 'process.env.version': JSON.stringify(gitRevisionPlugin.commithash().slice(0, 7)), // TODO: delete when real
63 | }),
64 | new HtmlWebpackPlugin({
65 | filename: 'index.html',
66 | template: path.resolve(__dirname, 'static/index.html'),
67 | inject: true,
68 | title: 'Klaytnscope',
69 | origin: process.env.SERVICE_URL,
70 | chunksSortMode: 'dependency',
71 | hash: true,
72 | }),
73 | new MiniCssExtractPlugin({
74 | filename: 'bundle.[chunkHash].css',
75 | chunkFilename: 'bundle.[chunkHash].css',
76 | }),
77 | new CompressionPlugin({
78 | filename: '[file].gz',
79 | algorithm: 'gzip',
80 | }),
81 | ],
82 | optimization: {
83 | splitChunks: {
84 | automaticNameDelimiter: '~',
85 | cacheGroups: {
86 | commons: {
87 | test: /[\\/]node_modules[\\/]/,
88 | chunks: 'all',
89 | name: 'vendor',
90 | enforce: true,
91 | },
92 | styles: {
93 | name: 'styles',
94 | test: /\.css$/,
95 | chunks: 'all',
96 | enforce: true,
97 | },
98 | },
99 | },
100 | },
101 | })
102 |
--------------------------------------------------------------------------------