setValuePhrase(e.target.value)}
+ onClick={() => restorePhrase()}
+ />
+ );
+ }
+
+ return null;
+}
+
+const mapStateToProps = (store) => {
+ return {
+ defaultAccount: store.pocket.defaultAccount,
+ };
+};
+
+export default connect(mapStateToProps)(AppSign);
diff --git a/src/containers/signer/component/MsgsSigner.jsx b/src/containers/signer/component/MsgsSigner.jsx
new file mode 100644
index 000000000..15537b945
--- /dev/null
+++ b/src/containers/signer/component/MsgsSigner.jsx
@@ -0,0 +1,151 @@
+import React from 'react';
+import { Pane } from '@cybercongress/gravity';
+
+import { trimString, formatNumber } from '../../../utils/utils';
+import MsgType from '../../txs/msgType';
+
+const CT = ({ children }) => (
+ {children}
+);
+
+function MsgsSigner({ msgData }) {
+ if (msgData.typeUrl === '/cosmos.bank.v1beta1.MsgSend') {
+ let recipient;
+ let amount;
+ if (msgData.value.toAddress && msgData.value.amount) {
+ recipient = trimString(msgData.value.toAddress, 8, 4);
+ amount = msgData.value.amount.map((coin, j) => {
+ return (
+
+ {' '}
+ {formatNumber(coin.amount)} {coin.denom.toUpperCase()}
+
+ );
+ });
+ }
+ return (
+
+
+
+ {recipient} will receive {amount}
+
+
+ );
+ }
+
+ if (msgData.type === 'cosmos-sdk/MsgDelegate') {
+ let amount;
+ let validator;
+ if (msgData.value.validator_address && msgData.value.amount) {
+ amount = `${formatNumber(
+ msgData.value.amount.amount
+ )} ${msgData.value.amount.denom.toUpperCase()}`;
+ validator = trimString(msgData.value.validator_address, 16);
+ }
+
+ return (
+
+
+ Delegate Delegate {amount} to {validator}
+
+ );
+ }
+
+ if (msgData.type === 'cosmos-sdk/MsgUndelegate') {
+ let amount;
+ let validator;
+ if (msgData.value.validator_address && msgData.value.amount) {
+ amount = `${formatNumber(
+ msgData.value.amount.amount
+ )} ${msgData.value.amount.denom.toUpperCase()}`;
+ validator = trimString(msgData.value.validator_address, 16, 4);
+ }
+ return (
+
+
+ Undelegate Undelegate {amount} from {validator}
+
+ Asset will be liquid after unbonding period
+
+ );
+ }
+
+ if (msgData.type === 'cosmos-sdk/MsgBeginRedelegate') {
+ let amount;
+ let fromValidator;
+ let toValidator;
+ if (
+ msgData.value.validator_dst_address &&
+ msgData.value.validator_src_address &&
+ msgData.value.amount
+ ) {
+ amount = `${formatNumber(
+ msgData.value.amount.amount
+ )} ${msgData.value.amount.denom.toUpperCase()}`;
+ fromValidator = trimString(msgData.value.validator_src_address, 16, 4);
+ toValidator = trimString(msgData.value.validator_dst_address, 16, 4);
+ }
+
+ return (
+
+
+ Redelegate Redelegate {amount} from {fromValidator} to{' '}
+ {toValidator}
+
+ );
+ }
+
+ if (msgData.type === 'cosmos-sdk/MsgWithdrawDelegatorReward') {
+ let validator;
+ if (msgData.value.validator_address) {
+ validator = trimString(msgData.value.validator_address, 16, 4);
+ }
+ return (
+
+
+ Claim Staking Reward Claim pending staking reward from{' '}
+ {validator}
+
+ );
+ }
+
+ if (msgData.type === 'cyber/Link') {
+ let links;
+ let address;
+ const cyberlinks = [];
+ if (msgData.value.address) {
+ address = trimString(msgData.value.address, 8, 4);
+ }
+ if (msgData.value.links) {
+ msgData.value.links.forEach((link) => {
+ cyberlinks.push({
+ from: link.from,
+ to: link.to,
+ });
+ });
+ }
+ if (cyberlinks.length > 0) {
+ links = cyberlinks
+ .map((link) => {
+ return `${trimString(link.from, 4, 4)} → ${trimString(
+ link.to,
+ 4,
+ 4
+ )}`;
+ })
+ .join(', ');
+ }
+
+ return (
+
+
+ {address} create link
+ {links}
+
+ );
+ }
+
+ return {msgData.type}
;
+}
+
+export default MsgsSigner;
diff --git a/src/containers/signer/component/ui.jsx b/src/containers/signer/component/ui.jsx
new file mode 100644
index 000000000..dc6119ad3
--- /dev/null
+++ b/src/containers/signer/component/ui.jsx
@@ -0,0 +1,237 @@
+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';
+import MsgsSigner from './MsgsSigner';
+import { JsonView } from '../../wasm/ui/ui';
+
+const HeaderSigner = ({ children }) => (
+
+ {children}
+
+);
+
+const ContainerSigner = ({ children }) => (
+
+ {children}
+
+);
+
+function StateSign({ msgData, onClick, onClickReject }) {
+ let content;
+
+ if (msgData !== null) {
+ content = (
+
+
+ Messages{' '}
+
+ {Object.keys(msgData).length}
+ {' '}
+
+
+
+ {/* {Object.keys(msgData).map((key) => (
+
+
+
+
+ ))} */}
+
+
+ );
+ }
+
+ return (
+
+ sign tx
+
+ {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 :
+
+
+
+
+
+
+
+ );
+}
+
+function StateCreateNew({ valuePhrase = '', onClick }) {
+ const [copyPhrase, setCopyPhrase] = useState(false);
+
+ return (
+
+ Create new account
+
+
+
+ Backup your mnemonic seed securely.
+
+ Mnemonic Seed:
+
+
+ setCopyPhrase(!copyPhrase)}
+ />{' '}
+ I saved the mnemonic phrase
+
+
+
+
+
+
+
+ );
+}
+
+export {
+ StateSign,
+ StateBroadcast,
+ StateConfirmed,
+ StateInitAccount,
+ StateCreateNew,
+ StateRestore,
+};
diff --git a/src/containers/signer/index.jsx b/src/containers/signer/index.jsx
new file mode 100644
index 000000000..ac1b44678
--- /dev/null
+++ b/src/containers/signer/index.jsx
@@ -0,0 +1,141 @@
+/* eslint-disable no-await-in-loop */
+import React from 'react';
+import {
+ SigningCosmosClient,
+ coins,
+ GasPrice,
+ BroadcastMode,
+ OfflineSigner,
+} from '@cosmjs/launchpad';
+import { SigningCyberClient, CyberClient } from '@cybercongress/cyber-js';
+import { Decimal } from '@cosmjs/math';
+import { stringToPath } from '@cosmjs/crypto';
+import { Secp256k1HdWallet } from '@cosmjs/amino';
+import { CYBER } from '../../utils/config';
+
+// ччы
+
+class Signer {
+ constructor() {
+ this.prefix = CYBER.BECH32_PREFIX_ACC_ADDR_CYBER;
+ this.word = 24;
+ this.hdPath = stringToPath("m/44'/118'/0'/0/0");
+ this.client = null;
+ this.signer = null;
+ this.msgsArr = [];
+ }
+
+ get getClient() {
+ return this.client;
+ }
+
+ get getSigner() {
+ return this.signer;
+ }
+
+ initSigner = async (defaultAccount) => {
+ const { account } = defaultAccount;
+ if (
+ account &&
+ account !== null &&
+ Object.prototype.hasOwnProperty.call(account, 'cyber')
+ ) {
+ if (account.cyber.keys === 'cyberSigner' && account.cyber.secret) {
+ const mnemonic = account.cyber.secret;
+ const mnemonicString = atob(mnemonic);
+ const signer = await Secp256k1HdWallet.fromMnemonic(mnemonicString, {
+ prefix: this.prefix,
+ });
+ this.signer = signer;
+ this.client = await this.createClient();
+
+ return this.client;
+ }
+ }
+
+ return null;
+ };
+
+ restorePhrase = async (mnemonic, callback) => {
+ const signer = await Secp256k1HdWallet.fromMnemonic(mnemonic, {
+ prefix: this.prefix,
+ });
+
+ this.signer = signer;
+ this.client = await this.createClient();
+
+ if (callback) {
+ callback(this.client);
+ }
+ return this.client;
+ };
+
+ generationAccount = async () => {
+ const address = await this.getVanityAccount();
+ return address;
+ };
+
+ getVanityAccount = async (callback) => {
+ try {
+ let condition = true;
+ while (condition) {
+ const signer = await Secp256k1HdWallet.generate(this.word, {
+ prefix: this.prefix,
+ });
+ const [{ address }] = await signer.getAccounts();
+ if (address.match(/^bostrom1a[a-zA-Z0-9]{37}$/g)) {
+ condition = false;
+ if (callback) {
+ callback(signer);
+ }
+ this.signer = signer;
+ this.client = await this.createClient();
+
+ return this.client;
+ }
+ }
+ } catch (error) {
+ console.log(`error`, error);
+ return error;
+ }
+ };
+
+ createClient = async () => {
+ const client = await SigningCyberClient.connectWithSigner(
+ CYBER.CYBER_NODE_URL_API,
+ this.signer
+ );
+
+ return client;
+ };
+
+ sendTxs = async (msgs, callback) => {
+ try {
+ if (this.client !== null) {
+ const [{ address }] = await this.client.signer.getAccounts();
+
+ const fee = {
+ amount: [],
+ gas: '200000',
+ };
+
+ const response = await this.client.signAndBroadcast(
+ address,
+ msgs,
+ fee,
+ CYBER.MEMO_CYBER_SIGNER
+ );
+ console.log('response1', response);
+ if (callback && callback !== null) {
+ callback(response);
+ }
+ return response;
+ }
+ } catch (error) {
+ console.log(`error`, error);
+ return error;
+ }
+ };
+}
+
+export default Signer;
diff --git a/src/containers/testKeplre/index.jsx b/src/containers/testKeplre/index.jsx
index 75d78349a..9d0e01818 100644
--- a/src/containers/testKeplre/index.jsx
+++ b/src/containers/testKeplre/index.jsx
@@ -1,109 +1,71 @@
import React, { useState, useEffect, useContext, useCallback } from 'react';
-import axios from 'axios';
-import { connect } from 'react-redux';
-import ReactMarkdown from 'react-markdown';
+import { useLocation } from 'react-router-dom';
+import { coins } from '@cosmjs/launchpad';
+import { fromAscii, fromBase64 } from '@cosmjs/encoding';
+import { AppContext, AppContextSigner } from '../../context';
+import { CYBER, CYBER_SIGNER } from '../../utils/config';
+const uint8ArrayConcat = require('uint8arrays/concat');
-import { coin, coins } from '@cosmjs/launchpad';
-import {
- SigningCyberClient,
- SigningCyberClientOptions,
-} from '@cybercongress/cyber-js';
-import { Tablist, Pane } from '@cybercongress/gravity';
-import { AppContext } from '../../context';
-import { CYBER } from '../../utils/config';
-import { trimString, formatNumber, reduceBalances } from '../../utils/utils';
-import { Btn } from './ui';
-import Convert from './convert';
-import { getPinsCid } from '../../utils/search/utils';
-import Denom from '../../components/denom';
+// import Signer from '../signer';
-import DenomTest from './testDenom';
-import AddTest from './testAdd';
-import { Signatures } from '../portal/components';
-import Carousel from '../portal/gift/carousel1/Carousel';
+const testData =
+ 'eyJ0eXBlVXJsIjoiL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZCIsInZhbHVlIjp7ImZyb21BZGRyZXNzIjoiYm9zdHJvbTFmcms5azM4cHZwNzB2aGVlemhkZmQ0bnZxbmxzbTlkdzNqOGhscSIsInRvQWRkcmVzcyI6ImJvc3Ryb20xZnJrOWszOHB2cDcwdmhlZXpoZGZkNG52cW5sc205ZHczajhobHEiLCJhbW91bnQiOlt7ImRlbm9tIjoiYm9vdCIsImFtb3VudCI6IjQyIn1dfX0=';
-// const token = Buffer.from(`anonymas:mouse123west`, 'utf8').toString('base64');
-const token = 'anonymas:mouse123west';
+// dune pottery shield bracket shuffle orchard frown mail exercise destroy enroll nothing scheme allow pudding match mass world glow razor that attend blame follow
-// const headers = {
-// authorization: `Basic YW5vbnltYXM6bW91c2UxMjN3ZXN0`,
-// };
-const addressTest = 'bostrom19nk207agguzdvpj9nqsf4zrjw8mcuu9afun3fv';
+function useQuery() {
+ const { search } = useLocation();
-const headers = {
- 'Content-Type': 'application/json',
-};
-
-const bootTocyb =
- 'pool5D83035BE0E7AB904379161D3C52FB4C1C392265AC19CE39A864146198610628';
-const milliampere = 'milliampere';
-
-const testDenom =
- 'ibc/13B2C536BB057AC79D5696B8EA1B6720EC1F2170708CAFF6F0183C963FFFED0B';
-
-const slidesTest = [
- {
- title: 'STEP_GIFT_INFO',
- },
- {
- title: 'STEP_PROVE_ADD',
- },
- {
- title: 'STEP_CLAIME',
- },
-];
+ return React.useMemo(() => new URLSearchParams(search), [search]);
+}
function TestKeplr() {
- const { keplr, jsCyber } = useContext(AppContext);
- // return ;
- // return ;
+ const { keplr } = useContext(AppContext);
+ const {
+ cyberSigner,
+ updateValueTxs,
+ updateValueIsVisible,
+ updateCallbackSigner,
+ updateStageSigner,
+ } = useContext(AppContextSigner);
- const checkGift = async () => {
- const response = await axios({
- method: 'GET',
- url: 'https://titan.cybernode.ai/graphql/api/rest/get-cybergift/0x0000000c01915e253a7f1017c975812edd5e8ec3',
- });
+ const [hashTx, setHashTx] = useState('');
+ const [msgsData, setMsgsData] = useState([]);
+ const search = useQuery();
- console.log('response', response.data);
- };
- const getCredit = useCallback(async () => {
+ console.log('params', search);
+
+ useEffect(() => {
try {
- const fromData = {
- denom: 'boot',
- address: addressTest,
- };
- const response = await axios({
- method: 'post',
- url: 'http://localhost:8000/credit',
- headers,
- data: JSON.stringify(fromData),
- });
- console.log('response', response);
- getAccount(addressTest);
+ const msgs = [];
+ const fromBase64Data = fromAscii(fromBase64(testData));
+ msgs.push(JSON.parse(fromBase64Data));
+ setMsgsData(msgs);
} catch (error) {
- console.log('getCredit', error);
+ console.log('error', error);
}
}, []);
- const getAccount = useCallback(
- async (address) => {
- if (jsCyber !== null) {
- // const response = await jsCyber.getAccount(address);
- const response = await jsCyber.getBalance(address, 'boot');
- console.log('response', response);
- }
- },
- [jsCyber]
- );
+ const sendTxSigner = useCallback(async () => {
+ if (cyberSigner !== null) {
+ console.log('msgsData', msgsData);
+ updateValueTxs(msgsData);
+ }
+ }, [msgsData, cyberSigner]);
return (
-
-
- {/* */}
- {/* */}
+
+
+
+ {hashTx}
);
}
diff --git a/src/containers/txs/ActionBarWalletTxs.jsx b/src/containers/txs/ActionBarWalletTxs.jsx
new file mode 100644
index 000000000..6fc5df424
--- /dev/null
+++ b/src/containers/txs/ActionBarWalletTxs.jsx
@@ -0,0 +1,203 @@
+import React, { useContext, useEffect, useCallback, useState } from 'react';
+import {
+ ActionBar as ActionBarContainer,
+ Button,
+} from '@cybercongress/gravity';
+import { AppContext, AppContextSigner } from '../../context';
+import { DEFAULT_GAS_LIMITS, CYBER } from '../../utils/config';
+import {
+ Dots,
+ ActionBarContentText,
+ TransactionSubmitted,
+ Confirmed,
+ TransactionError,
+} from '../../components';
+
+const STAGE_INIT = 0;
+const STAGE_APPROVE = 1;
+const STAGE_CONFIRMING = 2;
+const STAGE_CONFIRMED = 3;
+const STAGE_ERROR = 11;
+
+const fee = {
+ amount: [],
+ gas: DEFAULT_GAS_LIMITS.toString(),
+};
+
+function ActionBarWalletTxs({
+ msgsData,
+ addressActive,
+ updateFnc,
+ txsMsgData,
+}) {
+ const { keplr, jsCyber } = useContext(AppContext);
+ const { cyberSigner, updateValueTxs, updateCallbackSigner } =
+ useContext(AppContextSigner);
+
+ const [stage, setStage] = useState(STAGE_INIT);
+ const [txHash, setTxHash] = useState(null);
+ const [txHeight, setTxHeight] = useState(null);
+ const [errorMessage, setErrorMessage] = useState(null);
+
+ useEffect(() => {
+ const confirmTx = async () => {
+ if (jsCyber !== null && txHash !== null) {
+ setStage(STAGE_CONFIRMING);
+ const response = await jsCyber.getTx(txHash);
+
+ console.log('response :>> ', response);
+ if (response && response !== null) {
+ if (response.code === 0) {
+ setStage(STAGE_CONFIRMED);
+ setTxHeight(response.height);
+
+ if (updateFnc) {
+ updateFnc(response.hash);
+ }
+ return;
+ }
+ if (response.code) {
+ setStage(STAGE_ERROR);
+ setTxHeight(response.height);
+ setErrorMessage(response.rawLog);
+ return;
+ }
+ }
+ setTimeout(confirmTx, 1500);
+ }
+ };
+ confirmTx();
+ }, [jsCyber, txHash]);
+
+ const cleatState = () => {
+ setStage(STAGE_INIT);
+ setTxHash(null);
+ setTxHeight(null);
+ setErrorMessage(null);
+ };
+
+ const updateCallbackFnc = (result) => {
+ try {
+ if (result.code === 0) {
+ updateCallbackSigner(null);
+ setTxHash(result.transactionHash);
+ } else {
+ setTxHash(null);
+ setErrorMessage(result.rawLog.toString());
+ setStage(STAGE_ERROR);
+ }
+ } catch (error) {
+ console.log('error', error);
+ }
+ };
+
+ const sendTxSigner = useCallback(async () => {
+ if (cyberSigner !== null) {
+ updateCallbackSigner(updateCallbackFnc);
+ updateValueTxs(msgsData);
+ setStage(STAGE_APPROVE);
+ }
+ }, [cyberSigner, msgsData]);
+
+ const sendTxKeplr = useCallback(async () => {
+ try {
+ if (keplr !== null) {
+ setStage(STAGE_APPROVE);
+ const [{ address }] = await keplr.signer.getAccounts();
+ const result = await keplr.signAndBroadcast(
+ address,
+ msgsData,
+ fee,
+ CYBER.MEMO_KEPLR
+ );
+
+ if (result.code === 0) {
+ setTxHash(result.transactionHash);
+ } else {
+ setTxHash(null);
+ setErrorMessage(result.rawLog.toString());
+ setStage(STAGE_ERROR);
+ }
+ }
+ } catch (error) {
+ console.log('error', error);
+ setStage(STAGE_INIT);
+ }
+ }, [keplr, msgsData]);
+
+ const onClickSign = useCallback(() => {
+ if (addressActive !== null) {
+ if (addressActive.keys === 'keplr') {
+ sendTxKeplr();
+ }
+
+ if (addressActive.keys === 'cyberSigner') {
+ sendTxSigner();
+ }
+ }
+ }, [addressActive, msgsData, keplr]);
+
+ if (txsMsgData !== null) {
+ return null;
+ }
+
+ if (msgsData.length === 0 || addressActive === null) {
+ return (
+
+
+
+
+
+ );
+ }
+
+ if (stage === STAGE_INIT) {
+ return (
+
+
+
+ );
+ }
+
+ if (stage === STAGE_APPROVE) {
+ return (
+
+
+
+
+
+ );
+ }
+
+ if (stage === STAGE_CONFIRMING) {
+ return ;
+ }
+
+ if (stage === STAGE_CONFIRMED) {
+ return (
+ cleatState()}
+ />
+ );
+ }
+
+ if (stage === STAGE_ERROR && errorMessage !== null) {
+ return (
+ cleatState()}
+ />
+ );
+ }
+
+ return null;
+}
+
+export default ActionBarWalletTxs;
diff --git a/src/containers/txs/informationTxs.jsx b/src/containers/txs/informationTxs.jsx
index cf148d024..66bdb8b67 100644
--- a/src/containers/txs/informationTxs.jsx
+++ b/src/containers/txs/informationTxs.jsx
@@ -6,20 +6,52 @@ import { Link } from 'react-router-dom';
const dateFormat = require('dateformat');
const statusTrueImg = require('../../image/ionicons_svg_ios-checkmark-circle.svg');
const statusFalseImg = require('../../image/ionicons_svg_ios-close-circle.svg');
+const statusUnsignedImg = require('../../image/ionicons_svg_ios-warning.svg');
+
+const checkStatus = (status) => {
+ if (status === true) {
+ return 'Success';
+ }
+
+ if (status === false) {
+ return 'Fail';
+ }
+
+ if (status === 'Unsigned') {
+ return 'Unsigned';
+ }
+
+ return '';
+};
+
+const checkStatusImg = (status) => {
+ if (status === true) {
+ return statusTrueImg;
+ }
+
+ if (status === false) {
+ return statusFalseImg;
+ }
+
+ return statusUnsignedImg;
+};
const InformationTxs = ({ data, messageError, ...props }) => {
console.log(data);
- const value = Object.keys(data).map(key => {
+ const value = Object.keys(data).map((key) => {
let item = '';
switch (key) {
case 'height':
- item = formatNumber(data[key]);
+ item = data[key] > 0 ? formatNumber(data[key]) : '';
break;
case 'status':
- item = data[key] ? 'Success' : 'Fail';
+ item = checkStatus(data[key]);
break;
case 'timestamp':
- item = dateFormat(data[key], 'UTC: dd/mm/yyyy, hh:MM:ss tt "UTC"');
+ item =
+ data[key].length > 0
+ ? dateFormat(data[key], 'UTC: dd/mm/yyyy, hh:MM:ss tt "UTC"')
+ : '';
break;
default:
item = data[key];
@@ -58,7 +90,7 @@ const InformationTxs = ({ data, messageError, ...props }) => {
{key === 'status' && (
)}
diff --git a/src/containers/txs/msgType.jsx b/src/containers/txs/msgType.jsx
index f332f854f..e1f69d4f9 100644
--- a/src/containers/txs/msgType.jsx
+++ b/src/containers/txs/msgType.jsx
@@ -31,6 +31,9 @@ const MsgType = ({ type }) => {
case 'cyberd/Link':
return Link;
+ case 'cyber/Link':
+ return Link;
+
// bank
case 'cosmos-sdk/MsgSend':
return Send;
@@ -84,7 +87,7 @@ const MsgType = ({ type }) => {
return 'IBC Receive';
default:
- return { type };
+ return {type};
}
};
diff --git a/src/containers/txs/utils.js b/src/containers/txs/utils.js
new file mode 100644
index 000000000..bd71edd01
--- /dev/null
+++ b/src/containers/txs/utils.js
@@ -0,0 +1,74 @@
+export const checkAddress = (valueAddress, address) => {
+ if (valueAddress !== address) {
+ return address;
+ }
+
+ return valueAddress;
+};
+
+export const parseMsgs = (data, bech32 = '') => {
+ const tempData = [...data];
+ tempData.forEach((item) => {
+ const { typeUrl, value } = item;
+ if (typeUrl) {
+ if (
+ typeUrl.includes('/cyber.graph') ||
+ typeUrl.includes('/cyber.resources')
+ ) {
+ value.neuron = checkAddress(value.neuron, bech32);
+ }
+
+ if (typeUrl.includes('MsgSend')) {
+ value.fromAddress = checkAddress(value.fromAddress, bech32);
+ }
+
+ if (typeUrl.includes('staking') || typeUrl.includes('distribution')) {
+ value.delegatorAddress = checkAddress(value.delegatorAddress, bech32);
+ }
+
+ if (typeUrl.includes('wasm')) {
+ value.sender = checkAddress(value.sender, bech32);
+ }
+
+ if (typeUrl.includes('grid')) {
+ value.source = checkAddress(value.source, bech32);
+ }
+
+ if (typeUrl.includes('MsgVote')) {
+ value.voter = checkAddress(value.voter, bech32);
+ }
+
+ if (typeUrl.includes('MsgSubmitProposal')) {
+ value.proposer = checkAddress(value.proposer, bech32);
+ }
+
+ if (typeUrl.includes('MsgDeposit')) {
+ value.depositor = checkAddress(value.depositor, bech32);
+ }
+
+ if (typeUrl.includes('MsgSwapWithinBatch')) {
+ value.swapRequesterAddress = checkAddress(
+ value.swapRequesterAddress,
+ bech32
+ );
+ }
+
+ if (typeUrl.includes('MsgDepositWithinBatch')) {
+ value.depositorAddress = checkAddress(value.depositorAddress, bech32);
+ }
+
+ if (typeUrl.includes('MsgWithdrawWithinBatch')) {
+ value.withdrawerAddress = checkAddress(value.withdrawerAddress, bech32);
+ }
+
+ if (typeUrl.includes('MsgCreatePool')) {
+ value.poolCreatorAddress = checkAddress(
+ value.poolCreatorAddress,
+ bech32
+ );
+ }
+ }
+ });
+
+ return tempData;
+};
diff --git a/src/containers/txs/wallet.jsx b/src/containers/txs/wallet.jsx
new file mode 100644
index 000000000..9621e0fb1
--- /dev/null
+++ b/src/containers/txs/wallet.jsx
@@ -0,0 +1,106 @@
+import React, { useState, useEffect, useContext, useCallback } from 'react';
+import { useParams } from 'react-router-dom';
+import { connect } from 'react-redux';
+import { fromAscii, fromBase64 } from '@cosmjs/encoding';
+import { AppContext, AppContextSigner } from '../../context';
+import useSetActiveAddress from '../../hooks/useSetActiveAddress';
+import InformationTxs from './informationTxs';
+import Msgs from './msgs';
+import { JsonView } from '../wasm/ui/ui';
+import ActionBarWalletTxs from './ActionBarWalletTxs';
+import { getTxsV1beta1 } from '../../utils/search/utils';
+import { parseMsgs } from './utils';
+
+const initValueInformation = {
+ txHash: '',
+ height: '',
+ status: 'Unsigned',
+ timestamp: '',
+ memo: '',
+};
+
+function WalletTxs({ defaultAccount, mobile }) {
+ const param = useParams();
+ const { addressActive } = useSetActiveAddress(defaultAccount);
+ const [msgsData, setMsgsData] = useState([]);
+ const [information, setInformation] = useState(initValueInformation);
+ const [messageError, setMessageError] = useState('');
+ const [txsMsgData, setTxsMsgData] = useState(null);
+
+ useEffect(() => {
+ try {
+ if (param.dataMsg && addressActive !== null) {
+ const { dataMsg } = param;
+ const { bech32 } = addressActive;
+
+ const msgs = [];
+ const fromBase64Data = fromAscii(fromBase64(dataMsg));
+ msgs.push(JSON.parse(fromBase64Data));
+ const reduceMsgs = parseMsgs(msgs, bech32);
+ console.log('reduceMsgs', reduceMsgs);
+ setMsgsData(msgs);
+ }
+ } catch (error) {
+ console.log('error', error);
+ }
+ }, [param, addressActive]);
+
+ const updateFnc = async (hash) => {
+ const response = await getTxsV1beta1(hash);
+ console.log('response', response);
+ if (response !== null && response.tx_response) {
+ let status = false;
+ let rawLog = '';
+ const { code, raw_log, height, txhash, timestamp, tx } =
+ response.tx_response;
+ const { memo } = tx.body;
+ if (code !== undefined) {
+ if (code !== 0) {
+ status = false;
+ rawLog = raw_log;
+ } else {
+ status = true;
+ }
+ }
+ setInformation({ status, memo, height, timestamp, txHash: txhash });
+ setMessageError(rawLog);
+ }
+ if (response !== null && response.tx) {
+ const { messages } = response.tx.body;
+ setTxsMsgData(messages);
+ }
+ };
+
+ return (
+
+
+
+ {msgsData.length > 0 && txsMsgData === null && (
+
+ )}
+ {txsMsgData !== null && }
+
+ {!mobile && (
+
+ )}
+
+ );
+}
+
+const mapStateToProps = (store) => {
+ return {
+ defaultAccount: store.pocket.defaultAccount,
+ mobile: store.settings.mobile,
+ };
+};
+
+export default connect(mapStateToProps)(WalletTxs);
diff --git a/src/containers/wasm/ui/ui.jsx b/src/containers/wasm/ui/ui.jsx
index 6ca8f5460..24e5ed612 100644
--- a/src/containers/wasm/ui/ui.jsx
+++ b/src/containers/wasm/ui/ui.jsx
@@ -12,6 +12,7 @@ function JsonView({ src, strLength }) {
displayObjectSize={false}
collapseStringsAfterLength={strLength ?? 24}
theme="twilight"
+ style={{ overflow: 'auto' }}
/>
);
}
@@ -29,7 +30,9 @@ const FlexWrapCantainer = ({ children, ...props }) => (
);
const CardCantainer = ({ children, ...props }) => (
- {children}
+
+ {children}
+
);
const LinkTx = ({ children, txs }) => (
diff --git a/src/context.jsx b/src/context.jsx
index f55605e62..26aae6d94 100644
--- a/src/context.jsx
+++ b/src/context.jsx
@@ -1,10 +1,10 @@
import React, { useState, useEffect, useContext } from 'react';
-import { SigningCosmosClient, GasPrice } from '@cosmjs/launchpad';
+import { GasPrice } from '@cosmjs/launchpad';
import { SigningCyberClient, CyberClient } from '@cybercongress/cyber-js';
import { Decimal } from '@cosmjs/math';
import { Tendermint34Client } from '@cosmjs/tendermint-rpc';
-import { CYBER } from './utils/config';
+import { CYBER, CYBER_SIGNER } from './utils/config';
import { configKeplr } from './utils/keplrUtils';
export const getKeplr = async () => {
@@ -30,13 +30,20 @@ export const getKeplr = async () => {
const valueContext = {
keplr: null,
- ws: null,
jsCyber: null,
- updatejsCyber: () => {},
- initSigner: () => {},
+ ws: null,
+};
+
+const valueSignerContxt = {
+ tx: null,
+ isVisible: false,
+ cyberSigner: null,
+ callbackFnc: null,
+ stage: CYBER_SIGNER.STAGE_INIT,
};
export const AppContext = React.createContext(valueContext);
+export const AppContextSigner = React.createContext(valueSignerContxt);
export const useContextProvider = () => useContext(AppContext);
@@ -80,6 +87,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);
@@ -162,13 +171,44 @@ const AppContextProvider = ({ children }) => {
console.log('value', value);
+ const updateValueIsVisible = (isVisible) => {
+ setValueSigner((item) => ({ ...item, isVisible }));
+ };
+
+ const updateValueTxs = (tx) => {
+ setValueSigner((item) => ({ ...item, tx }));
+ };
+
+ const updateCyberSigner = (cyberSigner) => {
+ setValueSigner((item) => ({ ...item, cyberSigner }));
+ };
+
+ const updateCallbackSigner = (callbackFnc) => {
+ setValueSigner((item) => ({ ...item, callbackFnc }));
+ };
+
+ const updateStageSigner = (stage) => {
+ setValueSigner((item) => ({ ...item, stage }));
+ };
+
if (value.jsCyber && value.jsCyber === null) {
return ...
;
}
return (
- {children}
+
+ {children}
+
);
};
diff --git a/src/router.jsx b/src/router.jsx
index c1f4c11e3..300a7f049 100644
--- a/src/router.jsx
+++ b/src/router.jsx
@@ -60,10 +60,12 @@ import {
import Help from './containers/help';
import Assets from './containers/assets';
import MainPartal from './containers/portal/mainPortal';
+import WalletTxs from './containers/txs/wallet';
import useIpfsFactory from './useIpfsFactory';
import { TIME_START, CYBER } from './utils/config';
+import AppSign from './containers/signer/app';
export const history = createBrowserHistory({});
@@ -93,6 +95,7 @@ function AppRouter({
return (
+
@@ -153,6 +156,7 @@ function AppRouter({
+
diff --git a/src/style/main.css b/src/style/main.css
index c238db8de..184207ddb 100644
--- a/src/style/main.css
+++ b/src/style/main.css
@@ -12,4 +12,5 @@
@import './story.css';
-@import './components.css';
\ No newline at end of file
+@import './components.css';
+@import './signer.css';
\ No newline at end of file
diff --git a/src/style/signer.css b/src/style/signer.css
new file mode 100644
index 000000000..10e2a091a
--- /dev/null
+++ b/src/style/signer.css
@@ -0,0 +1,18 @@
+.signer-container {
+ width: 350px;
+ height: 500px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ border-radius: 5px;
+ box-shadow: 0 0 7px 1px #3ab793;
+ position: fixed;
+ background-color: #000;
+ top: 50%;
+ right: 10%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 9999;
+ margin-right: -50%;
+ padding: 10px;
+}
\ No newline at end of file
diff --git a/src/utils/config.js b/src/utils/config.js
index ff52b1980..a0fdc4b53 100644
--- a/src/utils/config.js
+++ b/src/utils/config.js
@@ -75,25 +75,26 @@ const CYBER = {
// CYBER_WEBSOCKET_URL: 'ws://localhost:26657/websocket',
// CYBER_NODE_URL_LCD: 'http://localhost:1317',
- CHAIN_ID: 'bostrom',
- CYBER_NODE_URL_API: 'https://rpc.bostrom.cybernode.ai',
- CYBER_WEBSOCKET_URL: 'wss://rpc.bostrom.cybernode.ai/websocket',
- CYBER_NODE_URL_LCD: 'https://lcd.bostrom.cybernode.ai',
- CYBER_INDEX_HTTPS: 'https://index.bostrom.cybernode.ai/v1/graphql',
- CYBER_INDEX_WEBSOCKET: 'wss://index.bostrom.cybernode.ai/v1/graphql',
+ // CHAIN_ID: 'bostrom',
+ // CYBER_NODE_URL_API: 'https://rpc.bostrom.cybernode.ai',
+ // CYBER_WEBSOCKET_URL: 'wss://rpc.bostrom.cybernode.ai/websocket',
+ // CYBER_NODE_URL_LCD: 'https://lcd.bostrom.cybernode.ai',
+ // CYBER_INDEX_HTTPS: 'https://index.bostrom.cybernode.ai/v1/graphql',
+ // CYBER_INDEX_WEBSOCKET: 'wss://index.bostrom.cybernode.ai/v1/graphql',
- // CHAIN_ID: 'space-pussy-1',
- // CYBER_NODE_URL_API: 'https://rpc.space-pussy-1.cybernode.ai',
- // CYBER_WEBSOCKET_URL: 'wss://rpc.space-pussy-1.cybernode.ai/websocket',
- // CYBER_NODE_URL_LCD: 'https://lcd.space-pussy-1.cybernode.ai',
- // CYBER_INDEX_HTTPS: 'https://index.space-pussy-1.cybernode.ai/v1/graphql',
- // CYBER_INDEX_WEBSOCKET: 'wss://index.space-pussy-1.cybernode.ai/v1/graphql',
+ CHAIN_ID: 'space-pussy-1',
+ CYBER_NODE_URL_API: 'https://rpc.space-pussy-1.cybernode.ai',
+ CYBER_WEBSOCKET_URL: 'wss://rpc.space-pussy-1.cybernode.ai/websocket',
+ CYBER_NODE_URL_LCD: 'https://lcd.space-pussy-1.cybernode.ai',
+ CYBER_INDEX_HTTPS: 'https://index.space-pussy-1.cybernode.ai/v1/graphql',
+ CYBER_INDEX_WEBSOCKET: 'wss://index.space-pussy-1.cybernode.ai/v1/graphql',
CYBER_GATEWAY: 'https://gateway.ipfs.cybernode.ai',
BECH32_PREFIX_ACC_ADDR_CYBER: 'bostrom',
BECH32_PREFIX_ACC_ADDR_CYBERVALOPER: 'bostromvaloper',
MEMO_KEPLR: '[bostrom] cyb.ai, using keplr',
+ MEMO_CYBER_SIGNER: 'cyber.page, using cyberSigner',
};
const DEFAULT_GAS_LIMITS = 200000;
@@ -160,6 +161,14 @@ const POCKET = {
},
};
+const CYBER_SIGNER = {
+ STAGE_INIT: 0,
+ STAGE_SIGN: 1,
+ STAGE_INIT_ACC: 2.1,
+ STAGE_CREATE_NEW_ACCOUNT: 2.2,
+ STAGE_RESTORE_PHARSE: 2.3,
+};
+
const PROPOSAL_STATUS = {
/** PROPOSAL_STATUS_UNSPECIFIED - PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status. */
PROPOSAL_STATUS_UNSPECIFIED: 0,
@@ -265,4 +274,5 @@ export {
VOTE_OPTION,
BOND_STATUS,
CID_AVATAR,
+ CYBER_SIGNER,
};
diff --git a/src/utils/msgs.js b/src/utils/msgs.js
new file mode 100644
index 000000000..624c7001e
--- /dev/null
+++ b/src/utils/msgs.js
@@ -0,0 +1,282 @@
+import { toUtf8 } from '@cosmjs/encoding';
+
+class Msgs {
+ cyberlink = (neuron, from, to) => {
+ const cyberlinkMsg = {
+ typeUrl: '/cyber.graph.v1beta1.MsgCyberlink',
+ value: {
+ neuron,
+ links: [{ from, to }],
+ },
+ };
+
+ return cyberlinkMsg;
+ };
+
+ // Resources module
+
+ investmint = async (senderAddress, amount, resource, length) => {
+ const investmintMsg = {
+ typeUrl: '/cyber.resources.v1beta1.MsgInvestmint',
+ value: {
+ neuron: senderAddress,
+ amount,
+ resource,
+ length: length.toString(),
+ },
+ };
+ return investmintMsg;
+ };
+
+ sendTokens = (senderAddress, recipientAddress, amount) => {
+ const sendMsg = {
+ typeUrl: '/cosmos.bank.v1beta1.MsgSend',
+ value: {
+ fromAddress: senderAddress,
+ toAddress: recipientAddress,
+ amount,
+ },
+ };
+ return sendMsg;
+ };
+
+ // Distribution module
+
+ delegateTokens = async (delegatorAddress, validatorAddress, amount) => {
+ const delegateMsg = {
+ typeUrl: '/cosmos.staking.v1beta1.MsgDelegate',
+ value: {
+ delegatorAddress,
+ validatorAddress,
+ amount,
+ },
+ };
+ return delegateMsg;
+ };
+
+ redelegateTokens = async (
+ delegatorAddress,
+ validatorSrcAddress,
+ validatorDstAddress,
+ amount
+ ) => {
+ const redelegateMsg = {
+ typeUrl: '/cosmos.staking.v1beta1.MsgBeginRedelegate',
+ value: {
+ delegatorAddress,
+ validatorSrcAddress,
+ validatorDstAddress,
+ amount,
+ },
+ };
+ return redelegateMsg;
+ };
+
+ undelegateTokens = async (delegatorAddress, validatorAddress, amount) => {
+ const undelegateMsg = {
+ typeUrl: '/cosmos.staking.v1beta1.MsgUndelegate',
+ value: {
+ delegatorAddress,
+ validatorAddress,
+ amount,
+ },
+ };
+ return undelegateMsg;
+ };
+
+ withdrawRewards = async (delegatorAddress, validatorAddress) => {
+ const withdrawDelegatorRewardMsg = {
+ typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward',
+ value: {
+ delegatorAddress,
+ validatorAddress,
+ },
+ };
+ return withdrawDelegatorRewardMsg;
+ };
+
+ withdrawAllRewards = async (delegatorAddress, validatorAddresses) => {
+ const msgs = validatorAddresses.map((validatorAddress) => {
+ return {
+ typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward',
+ value: {
+ delegatorAddress,
+ validatorAddress,
+ },
+ };
+ });
+
+ return msgs;
+ };
+
+ executeArray = async (senderAddress, contractAddress, msg, funds) => {
+ const msgs = msg.map((item) => ({
+ typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
+ value: {
+ sender: senderAddress,
+ contract: contractAddress,
+ msg: toUtf8(JSON.stringify(item)),
+ funds: [...(funds || [])],
+ },
+ }));
+
+ return msgs;
+ };
+
+ voteProposal = async (voter, proposalId, option) => {
+ const voteMsg = {
+ typeUrl: '/cosmos.gov.v1beta1.MsgVote',
+ value: {
+ proposalId,
+ voter,
+ option,
+ },
+ };
+ return voteMsg;
+ };
+
+ submitProposal = async (proposer, content, initialDeposit) => {
+ const sumbitProposalMsg = {
+ typeUrl: '/cosmos.gov.v1beta1.MsgSubmitProposal',
+ value: {
+ content: {
+ typeUrl: content.typeUrl,
+ value: Uint8Array.from(content.value),
+ },
+ initialDeposit,
+ proposer,
+ },
+ };
+ return sumbitProposalMsg;
+ };
+
+ depositProposal = async (depositor, proposalId, amount) => {
+ const depositMsg = {
+ typeUrl: '/cosmos.gov.v1beta1.MsgDeposit',
+ value: {
+ depositor,
+ proposalId,
+ amount,
+ },
+ };
+ return depositMsg;
+ };
+
+ // Liquidity module
+
+ swapWithinBatch = async (
+ swapRequesterAddress,
+ poolId,
+ swapTypeId,
+ offerCoin,
+ demandCoinDenom,
+ offerCoinFee,
+ orderPrice
+ ) => {
+ const swapWithinBatchMsg = {
+ typeUrl: '/tendermint.liquidity.v1beta1.MsgSwapWithinBatch',
+ value: {
+ swapRequesterAddress,
+ poolId,
+ swapTypeId,
+ offerCoin,
+ demandCoinDenom,
+ offerCoinFee,
+ orderPrice,
+ },
+ };
+ // console.log(swapWithinBatchMsg);
+ return swapWithinBatchMsg;
+ };
+
+ depositWithinBatch = async (depositorAddress, poolId, depositCoins) => {
+ const depositWithinBatchMsg = {
+ typeUrl: '/tendermint.liquidity.v1beta1.MsgDepositWithinBatch',
+ value: {
+ depositorAddress,
+ poolId,
+ depositCoins,
+ },
+ };
+ // console.log(depositWithinBatchMsg);
+ return depositWithinBatchMsg;
+ };
+
+ withdwawWithinBatch = async (withdrawerAddress, poolId, poolCoin) => {
+ const withdrawWithinBatchMsg = {
+ typeUrl: '/tendermint.liquidity.v1beta1.MsgWithdrawWithinBatch',
+ value: {
+ withdrawerAddress,
+ poolId,
+ poolCoin,
+ },
+ };
+ // console.log(withdrawWithinBatchMsg);
+ return withdrawWithinBatchMsg;
+ };
+
+ createPool = async (poolCreatorAddress, poolTypeId, depositCoins) => {
+ const createPoolMsg = {
+ typeUrl: '/tendermint.liquidity.v1beta1.MsgCreatePool',
+ value: {
+ poolCreatorAddress,
+ poolTypeId,
+ depositCoins,
+ },
+ };
+ // console.log(createPoolMsg);
+ return createPoolMsg;
+ };
+
+ // Energy module
+
+ createEnergyRoute = async (senderAddress, destination, name) => {
+ const createEnergyRouteMsg = {
+ typeUrl: '/cyber.grid.v1beta1.MsgCreateRoute',
+ value: {
+ source: senderAddress,
+ destination,
+ name,
+ },
+ };
+ return createEnergyRouteMsg;
+ };
+
+ editEnergyRoute = async (senderAddress, destination, value) => {
+ const editEnergyRouteMsg = {
+ typeUrl: '/cyber.grid.v1beta1.MsgEditRoute',
+ value: {
+ source: senderAddress,
+ destination,
+ value,
+ },
+ };
+ return editEnergyRouteMsg;
+ };
+
+ deleteEnergyRoute = async (senderAddress, destination) => {
+ const deleteEnergyRouteMsg = {
+ typeUrl: '/cyber.grid.v1beta1.MsgDeleteRoute',
+ value: {
+ source: senderAddress,
+ destination,
+ },
+ };
+ return deleteEnergyRouteMsg;
+ };
+
+ editEnergyRouteName = async (senderAddress, destination, name) => {
+ const editEnergyRouteNameMsg = {
+ typeUrl: '/cyber.grid.v1beta1.MsgEditRouteName',
+ value: {
+ source: senderAddress,
+ destination,
+ name,
+ },
+ };
+
+ return editEnergyRouteNameMsg;
+ };
+}
+
+export default Msgs;
diff --git a/src/utils/search/utils.js b/src/utils/search/utils.js
index 249c78cf0..d204e0726 100644
--- a/src/utils/search/utils.js
+++ b/src/utils/search/utils.js
@@ -607,6 +607,19 @@ export const getTxs = async (txs) => {
}
};
+export const getTxsV1beta1 = async (txs) => {
+ try {
+ const response = await axios({
+ method: 'get',
+ url: `${CYBER_NODE_URL_LCD}/cosmos/tx/v1beta1/txs/${txs}`,
+ });
+ return response.data;
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
+};
+
export const getValidatorsInfo = async (address) => {
try {
const response = await axios({