Skip to content

Commit

Permalink
Merge pull request #88 from nerdvibe/fix/zkapp-change-network
Browse files Browse the repository at this point in the history
Fix/zkapp change network
  • Loading branch information
nerdvibe authored Sep 18, 2024
2 parents 5c1fed6 + c48208e commit d9e6fd2
Show file tree
Hide file tree
Showing 12 changed files with 2,521 additions and 2,231 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "clorio-wallet",
"description": "Clorio wallet",
"version": "2.1.2",
"version": "2.1.3",
"private": true,
"main": "packages/main/dist/index.cjs",
"author": {
Expand Down Expand Up @@ -100,7 +100,7 @@
"jspdf": "^2.5.1",
"lottie-react": "^2.4.0",
"mina-ledger-js": "^1.0.6",
"mina-signer": "^2.1.1",
"mina-signer": "3.0.7",
"nedb": "1.8.0",
"nedb-promises": "^6.2.3",
"pretty-print-json": "^3.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/preload/src/zkapp-mina-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ const zkappIntegration = {
},
requestNetwork: () => sendIpcRequest('get-network-config', 'set-network-config', null),
addChain: (data: AddChainArgs) => sendIpcRequest('add-chain', 'added-chain', data),
switchChain: ({chainId}: {chainId: string}) =>
sendIpcRequest('switch-chain', 'switched-chain', chainId),
switchChain: ({networkID, chainId}: {networkID: string; chainId: string}) =>
sendIpcRequest('switch-chain', 'switched-chain', networkID || chainId),
getAccounts: () => sendIpcRequest('get-accounts', 'set-accounts'),
requestAccounts: () => sendIpcRequest('get-address', 'set-address'),
sendTransaction: (data: any) => sendIpcRequest('sign-tx', 'signed-tx', data),
Expand Down
22 changes: 12 additions & 10 deletions packages/renderer/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {LedgerContextProvider} from './contexts/ledger/LedgerContext';
import {apolloClient} from './graphql/api';
import 'react-loading-skeleton/dist/skeleton.css';
import './App.scss';
import {useNetworkSettingsContext} from './contexts/NetworkContext';
import {formatNetworks, useNetworkSettingsContext} from './contexts/NetworkContext';
import {BalanceContextProvider} from './contexts/balance/BalanceContext';
import {useEffect} from 'react';
import {WalletProvider} from './contexts/WalletContext';
Expand Down Expand Up @@ -44,32 +44,34 @@ function App() {
.then(response => response.json())
.then(data => data);
if (data) {
const newAvailableNetworks = Object.values(data).map(
const formattedNetworks = formatNetworks(data);
const newAvailableNetworks = Object.values(formattedNetworks).map(
({network, name}: {network: string; name: string}) => {
return {chainId: network, name: name};
return {chainId: network, name: name, networkID: `mina:${network}`};
},
);
setNetworkState(prev => ({
...prev,
availableNetworks: newAvailableNetworks,
showChangeNetworkModal: false,
}));
setAvailableNetworks(data);
setAvailableNetworks(formattedNetworks);

if (!selectedNetwork) {
const defaultNetwork = selectDefaultNetwork(Object.keys(data));
const defaultNetwork = selectDefaultNetwork(Object.keys(formattedNetworks));
setNetworkState(prev => ({
...prev,
selectedNetwork: {
chainId: data[defaultNetwork].network,
name: data[defaultNetwork].name,
chainId: formattedNetworks[defaultNetwork].network,
name: formattedNetworks[defaultNetwork].name,
networkID: formattedNetworks[defaultNetwork].networkID,
},
}));
}
if (!hasInitialSettings) {
const network = selectDefaultNetwork(Object.keys(data));
saveSettings(data[network]);
setNetworkState(prev => ({...prev, selectedNode: data[network]}));
const network = selectDefaultNetwork(Object.keys(formattedNetworks));
saveSettings(formattedNetworks[network]);
setNetworkState(prev => ({...prev, selectedNode: formattedNetworks[network]}));
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,28 @@ export default function ChangeNetwork() {
isAddingChain: false,
}));
};
const networksFound =
(switchNetwork &&
availableNetworks.filter(network => network.networkID === switchNetwork)[0]) ||
'Network not found';

const networkName =
switchNetwork && availableNetworks[switchNetwork]
? availableNetworks[switchNetwork].name
switchNetwork && availableNetworks[switchNetwork.split(':')[1]]
? availableNetworks[switchNetwork.split(':')[1]].name
: 'Network not found';

const onConfirm = async () => {
networkSelectHandler();
};

const getNetworkData = () => {
let networkToSwitch = {};
availableNetworksFromStore.forEach(network => {
if (network.chainId === switchNetwork) {
networkToSwitch = network;
}
});
if (!networkToSwitch) {
const networksFound =
switchNetwork && availableNetworks.filter(network => network.networkID === switchNetwork)[0];
if (!networksFound) {
toast.error('Network not found');
return;
}
return networkToSwitch;
return networksFound;
};

const networkSelectHandler = async () => {
Expand All @@ -58,18 +58,19 @@ export default function ChangeNetwork() {
return;
}
try {
await saveSettings(availableNetworks[switchNetwork]);
const networksFound =
switchNetwork &&
availableNetworks.filter(network => network.networkID === switchNetwork)[0];
await saveSettings(networksFound);
setNetworkState(prev => ({
...prev,
selectedNetwork: network,
switchNetwork: undefined,
showChangeNetworkModal: false,
isAddingChain: false,
selectedNode: availableNetworks[switchNetwork],
selectedNode: networksFound,
}));
sendResponse('clorio-switched-chain', {
...network,
});
sendResponse('clorio-switched-chain', {newtorkID: `mina:${switchNetwork}`});
navigate('/overview');
toast.success('Network switched successfully');
} catch (error) {
Expand All @@ -92,11 +93,11 @@ export default function ChangeNetwork() {
<div className="flex gap-4 confirm-transaction-data">
<div className="w-100">
<h4>Current</h4>
<p className='data-field'>{selectedNetwork?.name}</p>
<p className="data-field">{selectedNetwork?.name}</p>
</div>
<div className="w-100">
<h4>Target</h4>
<p className='data-field'>{networkName}</p>
<p className="data-field">{networksFound.name || 'Network not found'}</p>
</div>
</div>
<div className="flex mt-4 gap-4 confirm-transaction-data sm-flex-reverse">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import {useRecoilState, useRecoilValue} from 'recoil';
import {ModalContainer} from '..';
import {walletState, zkappState} from '../../../../store';
import {useEffect, useRef, useState} from 'react';
import Truncate from 'react-truncate-inside/es';
import {useCallback, useEffect, useRef, useState} from 'react';
import Button from '../../Button';
import {getAccountAddress, sendResponse} from '../../../../tools/mina-zkapp-bridge';
import {useLazyQuery} from '@apollo/client';
import {INonceQueryResult} from '../../../../pages/sendTX/SendTXHelper';
import {GET_NONCE} from '../../../../graphql/query';
import PasswordDecrypt from '../../../PasswordDecrypt';
import {toast} from 'react-toastify';
import {client} from '/@/tools';
import {client, toMINA, toNanoMINA} from '/@/tools';
import {mnemonicToPrivateKey} from '../../../../../../preload/src/bip';
import {ERROR_CODES} from '/@/tools/zkapp';
import TransactionData from './TransactionData';

export default function ConfirmZkappTransaction() {
const wallet = useRecoilValue(walletState);
Expand Down Expand Up @@ -71,23 +71,35 @@ export default function ConfirmZkappTransaction() {
privateKey = (await mnemonicToPrivateKey(mnemonic, wallet.accountNumber)) || mnemonic;
}

// const address = getAccountAddress();
// await fetchNonce({variables: {publicKey: address[0]}});
if (nonceError) {
console.error('Error in send-payment:', nonceError);
sendResponse('error', {error: nonceError});
return;
}
// const nonce = nonceData?.accountByKey?.usableNonce;
const feePayer = {
...transactionData?.transaction?.feePayer?.body,
publicKey: undefined,
feePayer: transactionData?.from,
fee: 1,
};
const payload = {zkappCommand: transactionData?.transaction, feePayer};
await (await client()).signZkappCommand(payload, privateKey);
toast.success('Transaction signed successfully');

let signResult;
try {
const signClient = await client();
let signBody: ZkappCommand = {};
const sendFee = toNanoMINA(transactionData.feePayer.fee || transactionData.fee);
signBody = {
zkappCommand: transactionData.transaction,
feePayer: {
feePayer: transactionData.from,
fee: transactionData.feePayer.fee || sendFee,
nonce: `${transactionData?.nonce || nonceData?.accountByKey?.usableNonce || 0}`,
memo: transactionData.feePayer.memo || '',
},
};
signResult = await signClient.signTransaction(signBody, privateKey);
sendResponse('clorio-signed-tx', {signedData: JSON.stringify(signResult.data)});
toast.success('Transaction signed successfully');
} catch (error) {
console.error('Error in signTransaction:', error);
sendResponse('error', {error});
return;
}

setZkappState(state => ({
...state,
isPendingConfirmation: true,
Expand All @@ -107,6 +119,45 @@ export default function ConfirmZkappTransaction() {
setShowPassword(false);
};

const onFeeEdit = (fee: number) => {
setZkappState(state => ({
...state,
transactionData: {
...state.transactionData,
fee,
feePayer: {
...state.transactionData.feePayer,
fee: toNanoMINA(fee),
},
},
}));
};

const onNonceEdit = (nonce: number) => {
setZkappState(state => ({
...state,
transactionData: {
...state.transactionData,
nonce,
},
}));
};

const formatData = useCallback(
data => {
if (!data) return {};
const {feePayer, transaction, fee, from} = data;
return {
from,
fee: feePayer?.fee ? toMINA(feePayer?.fee) : fee,
to: transaction?.accountUpdates?.[0]?.body?.publicKey,
memo: JSON.stringify(shortTransactionData(), null, 2),
nonce: nonceData?.accountByKey?.usableNonce,
};
},
[transactionData],
);

return (
<ModalContainer
show={showTransactionConfirmation}
Expand All @@ -124,47 +175,13 @@ export default function ConfirmZkappTransaction() {
onSuccess={onConfirm}
/>
) : (
<div className="flex flex-col gap-4">
<div className="flex gap-4 confirm-transaction-data">
{transactionData?.from && (
<div ref={fromRef}>
<h4>From</h4>
<Truncate
text={transactionData?.from || ''}
width={fromTextWidth || 250}
/>
</div>
)}
{transactionData?.to && (
<div>
<h4>To</h4>
<Truncate
text={transactionData?.to || ''}
width={fromTextWidth || 250}
/>
</div>
)}
</div>
<div className="flex flex-col justify-start">
<div className="flex w-100">
<div className="w-100">
<h4>Amount</h4>
<p className='data-field'>{transactionData.amount} MINA</p>
</div>
<div className="w-100">
<h4>Transaction fee</h4>
<p className='data-field'>{transactionData.fee || 0.0101} MINA</p>
</div>
</div>
{isZkappCommand && (
<div className="flex flex-col w-100">
<h4>Content</h4>
<pre className="w-100 overflow-x-auto text-start message-box">
{JSON.stringify(shortTransactionData(), null, 2)}
</pre>
</div>
)}
</div>
<>
<TransactionData
transactionData={formatData(transactionData)}
onFeeEdit={onFeeEdit}
onNonceEdit={onNonceEdit}
isZkappCommand
/>
<div className="flex mt-2 gap-4 confirm-transaction-data sm-flex-reverse">
<Button
className="w-100"
Expand All @@ -180,7 +197,7 @@ export default function ConfirmZkappTransaction() {
onClick={() => setShowPassword(true)}
/>
</div>
</div>
</>
)}
</ModalContainer>
);
Expand Down
Loading

0 comments on commit d9e6fd2

Please sign in to comment.