From 1dae8442ce1f11a0b0cefbfcbb67eeaf4f623ce0 Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Sat, 5 Jun 2021 15:25:34 +0300 Subject: [PATCH 01/20] feat(context): add signer context --- src/context.jsx | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/context.jsx b/src/context.jsx index e15518b7d..ab2d4f5ea 100644 --- a/src/context.jsx +++ b/src/context.jsx @@ -8,7 +8,14 @@ const valueContext = { ws: null, }; +const valueSignerContxt = { + tx: null, + isVisible: false, + cyberSigner: null, +}; + export const AppContext = React.createContext(valueContext); +export const AppContextSigner = React.createContext(valueSignerContxt); export const useContextProvider = () => useContext(AppContext); @@ -91,6 +98,8 @@ export async function createClient(signer) { const AppContextProvider = ({ children }) => { const [value, setValue] = useState(valueContext); + const [valueSigner, setValueSigner] = useState(valueSignerContxt); + const [signer, setSigner] = useState(null); const [client, setClient] = useState(null); @@ -128,7 +137,32 @@ const AppContextProvider = ({ children }) => { console.log('value', value); - return {children}; + const updateValueIsVisible = (isVisible) => { + setValueSigner((item) => ({ ...item, isVisible })); + }; + + const updateValueTxs = (tx) => { + setValueSigner((item) => ({ ...item, tx })); + }; + + const updateCyberSigner = (cyberSigner) => { + setValueSigner((item) => ({ ...item, cyberSigner })); + }; + + return ( + + + {children} + + + ); }; export default AppContextProvider; From 246ee7745642bc759ae4872bf426505854a10e14 Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Sat, 5 Jun 2021 15:26:38 +0300 Subject: [PATCH 02/20] fix(app): change router - add signer to router --- src/router.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/router.jsx b/src/router.jsx index b97fb9436..70b6d1050 100644 --- a/src/router.jsx +++ b/src/router.jsx @@ -38,6 +38,7 @@ import ForceGraph from './containers/forceGraph/forceGraph'; import ForceQuitter from './containers/forceGraph/forceQuitter'; import PortPages from './containers/port'; import TestKeplr from './containers/testKeplre'; +import AppSign from './containers/signer/app'; export const history = createBrowserHistory({}); @@ -68,6 +69,7 @@ function AppRouter({ return ( + From 42344e31fde572e93209f791118851cd51dd1fca Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Sat, 5 Jun 2021 15:55:43 +0300 Subject: [PATCH 03/20] fix(ipfs): change ipfs config --- src/ipfsHook.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ipfsHook.js b/src/ipfsHook.js index 53a534c08..e6a1a0a71 100644 --- a/src/ipfsHook.js +++ b/src/ipfsHook.js @@ -32,10 +32,6 @@ const initIpfsNode = async () => { ], }, Bootstrap: [ - // '/dns4/ams-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd', - // '/dns4/lon-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3', - // '/dns4/nyc-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm', - // '/dns4/nyc-2.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64', '/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic', '/dns4/node1.preload.ipfs.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6', ], @@ -72,17 +68,12 @@ const initIpfsNode = async () => { config: { Addresses: { Swarm: [ - // '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star', '/dns4/ws-star.discovery.cybernode.ai/tcp/443/wss/p2p-webrtc-star', '/ip4/159.89.24.179/tcp/4001/p2p/QmZBfqaL2L92rrTWR2Cdmor3R3EBLaoYzeVLEEwE3AJmWe', '/ip6/2a03:b0c0:3:d0::4ed:8001/tcp/4001/p2p/QmZBfqaL2L92rrTWR2Cdmor3R3EBLaoYzeVLEEwE3AJmWe', ], }, Bootstrap: [ - // '/dns4/ams-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd', - // '/dns4/lon-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3', - // '/dns4/nyc-1.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm', - // '/dns4/nyc-2.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64', '/dns4/node0.preload.ipfs.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic', '/dns4/node1.preload.ipfs.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6', ], From 8ec22cd870696b44c06b2f6d8a50916d4c56794a Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Sat, 5 Jun 2021 15:57:04 +0300 Subject: [PATCH 04/20] fix(search): add cyber signer to actionbar --- package.json | 1 + src/components/ledger/stageActionBar.jsx | 10 ++- src/containers/Search/ActionBar.jsx | 23 ++++++ src/containers/Search/ActionBarContainer.jsx | 86 ++++++++++++++++++-- src/containers/Search/SearchResults.jsx | 2 +- 5 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 src/containers/Search/ActionBar.jsx diff --git a/package.json b/package.json index 420f4ad07..b0cac4e30 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@babel/preset-react": "^7.0.0", "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", + "@cosmjs/crypto": "^0.25.3", "axios": "^0.21.1", "babel-eslint": "^10.0.1", "babel-loader": "^8.0.5", diff --git a/src/components/ledger/stageActionBar.jsx b/src/components/ledger/stageActionBar.jsx index 1c064e737..20ab6c3fa 100644 --- a/src/components/ledger/stageActionBar.jsx +++ b/src/components/ledger/stageActionBar.jsx @@ -92,6 +92,14 @@ const imgRead = require('../../image/duplicate-outline.svg'); const imgEth = require('../../image/Ethereum_logo_2014.svg'); const imgCyber = require('../../image/blue-circle.png'); const imgCosmos = require('../../image/cosmos-2.svg'); +const imgCyberSigner = require('../../image/wallet-outline.svg'); + +const imgData = { + ledger: imgLedger, + keplr: imgKeplr, + cyber: imgCyber, + cyberSigner: imgCyberSigner, +}; const T = new LocalizedStrings(i18n); const ledger = require('../../image/select-pin-nano2.svg'); @@ -368,7 +376,7 @@ export const StartStageSearchActionBar = ({ } disabled={!contentHash.length} onClick={onClickBtn} - img={keys === 'ledger' ? imgLedger : imgKeplr} + img={imgData[keys]} /> diff --git a/src/containers/Search/ActionBar.jsx b/src/containers/Search/ActionBar.jsx new file mode 100644 index 000000000..df15d0b40 --- /dev/null +++ b/src/containers/Search/ActionBar.jsx @@ -0,0 +1,23 @@ +import React from 'react'; +import InnerActionBarContainer from './ActionBarContainer'; +import { AppContext, AppContextSigner } from '../../context'; + +const ActionBarContainer = (props) => { + return ( + + {(valueAppContext) => ( + + {(valueAppContextSigner) => ( + + )} + + )} + + ); +}; + +export default ActionBarContainer; diff --git a/src/containers/Search/ActionBarContainer.jsx b/src/containers/Search/ActionBarContainer.jsx index dc2f1b997..0727c58eb 100644 --- a/src/containers/Search/ActionBarContainer.jsx +++ b/src/containers/Search/ActionBarContainer.jsx @@ -29,11 +29,18 @@ import { import { LEDGER, CYBER, PATTERN_IPFS_HASH } from '../../utils/config'; import { trimString } from '../../utils/utils'; -import { AppContext } from '../../context'; const imgKeplr = require('../../image/keplr-icon.svg'); const imgLedger = require('../../image/ledger.svg'); const imgCyber = require('../../image/blue-circle.png'); +const imgCyberSigner = require('../../image/wallet-outline.svg'); + +const imgData = { + ledger: imgLedger, + keplr: imgKeplr, + cyber: imgCyber, + cyberSigner: imgCyberSigner, +}; const { MEMO, @@ -56,8 +63,9 @@ const ADD_ADDRESS = 11; const LEDGER_TX_ACOUNT_INFO = 12; const STAGE_IPFS_HASH = 3.1; const STAGE_KEPLR_APPROVE = 3.2; +const STAGE_CHECK_TYPE_SIGNER = 8.1; -class ActionBarContainer extends Component { +class InnerActionBarContainer extends Component { constructor(props) { super(props); this.state = { @@ -110,7 +118,9 @@ class ActionBarContainer extends Component { if ( address !== null && addressInfo !== null && + toCid && toCid !== null && + fromCid && fromCid !== null ) { this.stageReady(); @@ -118,8 +128,8 @@ class ActionBarContainer extends Component { } if (stage === STAGE_IPFS_HASH) { - if (toCid !== null && fromCid !== null) { - this.generateTx(); + if (toCid && toCid !== null && fromCid && fromCid !== null) { + this.checkTypeSigner(); } } if (prevProps.defaultAccount.name !== defaultAccount.name) { @@ -272,8 +282,24 @@ class ActionBarContainer extends Component { }); }; + checkTypeSigner = () => { + const { addressLocalStor } = this.state; + + this.setState({ + stage: STAGE_CHECK_TYPE_SIGNER, + }); + + if (addressLocalStor.keys === 'keplr') { + this.generateTx(); + } + if (addressLocalStor.keys === 'cyberSigner') { + this.sendTxSigner(); + } + }; + generateTx = async () => { - const { keplr } = this.context; + const { valueAppContext } = this.props; + const { keplr } = valueAppContext; const { fromCid, toCid, addressLocalStor } = this.state; this.setState({ @@ -283,7 +309,7 @@ class ActionBarContainer extends Component { const chainId = CYBER.CHAIN_ID; await window.keplr.enable(chainId); const { address } = await keplr.getAccount(); - console.log('address', address) + console.log('address', address); if (addressLocalStor !== null && addressLocalStor.address === address) { const msgs = []; msgs.push({ @@ -497,6 +523,34 @@ class ActionBarContainer extends Component { }); }; + sendTxSigner = async () => { + const { valueAppContextSigner } = this.props; + const { fromCid, toCid, addressLocalStor } = this.state; + const { cyberSigner, updateValueTxs } = valueAppContextSigner; + if (cyberSigner !== null) { + const [{ address }] = await cyberSigner.getAccounts(); + const msgs = []; + msgs.push({ + type: 'cyber/Link', + value: { + address, + links: [ + { + from: fromCid, + to: toCid, + }, + ], + }, + }); + + updateValueTxs(msgs); + this.setState({ + stage: STAGE_INIT, + }); + this.cleatState(); + } + }; + onClickBtnRank = async () => { const { addressLocalStor } = this.state; const { rankLink } = this.props; @@ -521,6 +575,9 @@ class ActionBarContainer extends Component { if (addressLocalStor.keys === 'keplr') { this.onClickInitKeplr(); } + if (addressLocalStor.keys === 'cyberSigner') { + this.onClickInitKeplr(); + } }; render() { @@ -590,7 +647,7 @@ class ActionBarContainer extends Component { } onClick={() => this.onClickBtnRank()} - img={keys === 'ledger' ? imgLedger : imgKeplr} + img={imgData[keys]} /> @@ -660,6 +717,16 @@ class ActionBarContainer extends Component { ); } + if (stage === STAGE_CHECK_TYPE_SIGNER) { + return ( + + + + + + ); + } + if (stage === STAGE_WAIT) { return ( { }; }; -ActionBarContainer.contextType = AppContext; +// ActionBarContainer.contextType = AppContext; +// ActionBarContainer.contextType = AppContextSigner; -export default connect(mapStateToProps)(ActionBarContainer); +export default connect(mapStateToProps)(InnerActionBarContainer); diff --git a/src/containers/Search/SearchResults.jsx b/src/containers/Search/SearchResults.jsx index 9c0aa69de..2ae046be9 100644 --- a/src/containers/Search/SearchResults.jsx +++ b/src/containers/Search/SearchResults.jsx @@ -16,7 +16,7 @@ import { LinkWindow, Rank, } from '../../components'; -import ActionBarContainer from './ActionBarContainer'; +import ActionBarContainer from './ActionBar'; import { PATTERN, PATTERN_CYBER, From 0d998514faa907b7537c4f679a2e92bf5fb49077 Mon Sep 17 00:00:00 2001 From: dimakorzhovnik Date: Sat, 5 Jun 2021 16:05:20 +0300 Subject: [PATCH 05/20] feat(signer): signer - add new stage in signer - gen. vanity address - send txs - add fnc for chek msgs tx --- src/components/tabBtn/index.jsx | 31 ++- src/containers/Wallet/actionBar.jsx | 24 ++ .../Wallet/components/pocketCard.jsx | 2 + src/containers/signer/app.jsx | 127 +++++++++ .../signer/component/MsgsSigner.jsx | 0 src/containers/signer/component/ui.jsx | 263 ++++++++++++++++++ src/containers/signer/index.jsx | 87 ++++++ src/containers/testKeplre/index.jsx | 100 +++---- src/containers/txs/msgType.jsx | 5 +- src/style/main.css | 3 +- src/style/signer.css | 18 ++ src/utils/config.js | 1 + 12 files changed, 591 insertions(+), 70 deletions(-) create mode 100644 src/containers/signer/app.jsx create mode 100644 src/containers/signer/component/MsgsSigner.jsx create mode 100644 src/containers/signer/component/ui.jsx create mode 100644 src/containers/signer/index.jsx create mode 100644 src/style/signer.css diff --git a/src/components/tabBtn/index.jsx b/src/components/tabBtn/index.jsx index 3b262da47..50dcdf993 100644 --- a/src/components/tabBtn/index.jsx +++ b/src/components/tabBtn/index.jsx @@ -2,8 +2,31 @@ import React from 'react'; import { Link } from 'react-router-dom'; import { Tab } from '@cybercongress/gravity'; -const TabBtn = ({ key, text, isSelected, onSelect, to, ...props }) => ( - +const TabBtn = ({ key, text, isSelected, onSelect, to, ...props }) => { + if (to) { + return ( + + + {text} + + + ); + } + return ( ( > {text} - -); + ); +}; export default TabBtn; diff --git a/src/containers/Wallet/actionBar.jsx b/src/containers/Wallet/actionBar.jsx index 121f13e0c..7596dd2f3 100644 --- a/src/containers/Wallet/actionBar.jsx +++ b/src/containers/Wallet/actionBar.jsx @@ -15,6 +15,7 @@ import ActionBarConnect from './actionBarConnect'; const imgLedger = require('../../image/ledger.svg'); const imgKeplr = require('../../image/keplr-icon.svg'); const imgRead = require('../../image/duplicate-outline.svg'); +const imgCyberSigner = require('../../image/wallet-outline.svg'); const STAGE_INIT = 1; const STAGE_CONNECT = 2; @@ -271,6 +272,29 @@ function ActionBar({ ); } + if (typeActionBar === 'cyberSigner' && stage === STAGE_INIT) { + return ( + + + {connect && ( + + )} + setStage(STAGE_SEND_READ_ONLY)} + /> + {makeActive && ( + + )} + + + ); + } + if (typeActionBar === 'gol' && stage === STAGE_INIT) { return ( diff --git a/src/containers/Wallet/components/pocketCard.jsx b/src/containers/Wallet/components/pocketCard.jsx index 85716ac92..23092ba20 100644 --- a/src/containers/Wallet/components/pocketCard.jsx +++ b/src/containers/Wallet/components/pocketCard.jsx @@ -14,6 +14,7 @@ const deleteIcon = require('../../../image/trash-outline.svg'); const imgEth = require('../../../image/Ethereum_logo_2014.svg'); const imgCyber = require('../../../image/blue-circle.png'); const imgCosmos = require('../../../image/cosmos-2.svg'); +const imgCyberSigner = require('../../../image/wallet-outline.svg'); const imgData = { ledger: imgLedger, @@ -23,6 +24,7 @@ const imgData = { cyber: imgCyber, cosmos: imgCosmos, eth: imgEth, + cyberSigner: imgCyberSigner, }; export const FormatNumber = ({ diff --git a/src/containers/signer/app.jsx b/src/containers/signer/app.jsx new file mode 100644 index 000000000..230a67b52 --- /dev/null +++ b/src/containers/signer/app.jsx @@ -0,0 +1,127 @@ +import React, { useEffect, useState, useContext } from 'react'; +import { useLocation } from 'react-router-dom'; +import Signer from './index'; +import { AppContextSigner } from '../../context'; +import { + StateSign, + StateBroadcast, + StateConfirmed, + StateInitAccount, + StateCreateNew, + StateRestore, +} from './component/ui'; + +const STAGE_INIT = 0; +const STAGE_SIGN = 1; +const STAGE_CONFIRMING = 2; +const STAGE_CONFIRMED = 3; +const STAGE_INIT_ACC = 1.1; +const STAGE_CREATE_NEW_ACCOUNT = 1.2; +const STAGE_RESTORE_PHARSE = 1.3; + +function AppSign() { + const { + tx, + isVisible, + cyberSigner, + updateValueIsVisible, + updateValueTxs, + updateCyberSigner, + } = useContext(AppContextSigner); + const location = useLocation(); + const [stage, setStage] = useState(STAGE_INIT); + const [msgData, setMsgData] = useState(null); + const [txHash, setTxHash] = useState(null); + + useEffect(() => { + rejectStage(); + }, [location.pathname]); + + useEffect(() => { + const getSigner = async () => { + const signerObj = new Signer(); + const signerCyber = await signerObj.initSigner(); + const pk = Buffer.from(signerCyber.pubkey).toString('hex'); + console.log(`pk`, pk); + console.log(`signerCyber`, signerCyber); + updateCyberSigner(signerCyber); + }; + getSigner(); + }, []); + + useEffect(() => { + if (tx !== null) { + setMsgData(tx); + setStage(STAGE_SIGN); + updateValueIsVisible(true); + } + }, [tx]); + + useEffect(() => { + if (txHash !== null) { + setStage(STAGE_CONFIRMED); + } + }, [txHash]); + + const signTx = async () => { + console.log(`signer`, cyberSigner); + console.log(`msgData`, msgData); + if (cyberSigner !== null && msgData !== null) { + const signerObj = new Signer(); + setStage(STAGE_CONFIRMING); + const response = await signerObj.sendTxs(cyberSigner, msgData); + console.log(`response Txs`, response); + setTxHash(response.transactionHash); + updateValueTxs(null); + setMsgData(null); + } + }; + + const cleaneStage = () => { + setStage(STAGE_INIT); + setTxHash(null); + updateValueIsVisible(false); + }; + + const rejectStage = () => { + setStage(STAGE_INIT); + setMsgData(null); + setTxHash(null); + updateValueTxs(null); + updateValueIsVisible(false); + }; + + if (isVisible && stage === STAGE_SIGN) { + return ( + + ); + } + + if (isVisible && stage === STAGE_CONFIRMING) { + return ; + } + + if (isVisible && stage === STAGE_CONFIRMED) { + return ; + } + + if (isVisible && stage === STAGE_INIT_ACC) { + return ; + } + + if (isVisible && stage === STAGE_CREATE_NEW_ACCOUNT) { + return ; + } + + if (isVisible && stage === STAGE_RESTORE_PHARSE) { + return ; + } + + return null; +} + +export default AppSign; diff --git a/src/containers/signer/component/MsgsSigner.jsx b/src/containers/signer/component/MsgsSigner.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/containers/signer/component/ui.jsx b/src/containers/signer/component/ui.jsx new file mode 100644 index 000000000..c11e8e2ea --- /dev/null +++ b/src/containers/signer/component/ui.jsx @@ -0,0 +1,263 @@ +import React, { useState } from 'react'; +import { Link } from 'react-router-dom'; +import { Pane, Button, Tablist } from '@cybercongress/gravity'; +import MsgType from '../../txs/msgType'; +import { PillNumber, TabBtn, Dots } from '../../../components'; +import { trimString } from '../../../utils/utils'; + +const HeaderSigner = ({ children }) => ( + + {children} + +); + +function StateSign({ msgData, onClick, onClickReject }) { + const [selected, setSelected] = useState('details'); + + let content; + + if (selected === 'details' && msgData !== null) { + content = ( + + + Messages{' '} + + {Object.keys(msgData).length} + {' '} + + + {Object.keys(msgData).map((key) => ( + + + {/* {msgData[key].type} */} + + + ))} + + + ); + } + + if (selected === 'data' && msgData !== null) { + content = ( + +
{JSON.stringify(msgData, null, 2)}
+
+ ); + } + + return ( + + + sign tx + + + setSelected('details')} + /> + setSelected('data')} + /> + + {content} + + + + + + + + ); +} + +function StateBroadcast() { + return ( + + Broadcast txs + + + Please wait while we confirm the transaction on the blockchain{' '} + + + + + ); +} + +function StateConfirmed({ txHash, onClick }) { + return ( + + Confirmed + + + Transaction hash:{' '} + + {trimString(txHash, 6, 6)} + + + + + + + + ); +} + +function StateInitAccount({ onClickCreateNew, onClickRestore }) { + return ( + + Init Account + + + + + + + + ); +} + +function StateRestore({ valuePhrase, onChangeInputPhrase, onClick }) { + return ( + + Restore phrase + + + Input your seed : +