diff --git a/src/components/Body.tsx b/src/components/Body.tsx index a953832..ddddd2a 100644 --- a/src/components/Body.tsx +++ b/src/components/Body.tsx @@ -10,10 +10,10 @@ import { FourthRow } from './Rows/FourthRow'; export const Body = () => (
- + {/* */} - - + {/* */} + {/* */}
diff --git a/src/components/Buttons/Button.tsx b/src/components/Buttons/Button.tsx index 683ef7e..55db331 100644 --- a/src/components/Buttons/Button.tsx +++ b/src/components/Buttons/Button.tsx @@ -33,12 +33,18 @@ export const PrimaryButton: React.FC = ({ interface IInput { placeholder: string; disabled?: boolean; + onChange?: (e: any) => void; } -export const Input: React.FC = ({ disabled = false, placeholder }) => ( +export const Input: React.FC = ({ + disabled = false, + placeholder, + onChange, +}) => ( ); diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 4ae98d6..9686af0 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -6,7 +6,9 @@ import { useProviderContext } from '../contexts/provider'; export const Header = () => { const { setPrefix, prefix } = useProviderContext(); - const { state: { account, network } } = usePaliMethods(); + const { + state: { account, network }, + } = usePaliMethods(); const options = { sys: { @@ -16,13 +18,13 @@ export const Header = () => { eth: { label: 'Provider - Ethereum', value: 'eth', - } + }, }; - const stored = window.localStorage.getItem('pali_provider'); + const storedPrefix = window.localStorage.getItem('pali_prefix'); useEffect(() => { - if (stored !== options[prefix]) setPrefix(stored); + if (storedPrefix !== options[prefix]) setPrefix(storedPrefix); }, []); return ( @@ -42,9 +44,19 @@ export const Header = () => { Chain ID: {network.chainId || ''}
- setPrefix(event.target.value)} + className="cursor-pointer w-64 bg-alert-darkwarning px-4 py-1 rounded-full text-sm font-poppins flex items-center" + > {Object.values(options).map((option) => ( - + ))}
diff --git a/src/components/Rows/FirstRow.tsx b/src/components/Rows/FirstRow.tsx index fa3ade2..4913420 100644 --- a/src/components/Rows/FirstRow.tsx +++ b/src/components/Rows/FirstRow.tsx @@ -8,9 +8,7 @@ import { useProviderContext } from '../../contexts/provider'; import { usePaliMethods } from '../../contexts/requests'; export const FirstRow = () => { - const { - request, - } = usePaliMethods(); + const { request } = usePaliMethods(); const { prefix } = useProviderContext(); const [output, setOutput] = useState(''); @@ -29,14 +27,14 @@ export const FirstRow = () => {
- + {/*
onSubmit('signAndSend')} text="Sign PSBT" type="button" /> - onSubmit('getSignedPsbt')} text="Get signed PSBT" type="button" @@ -49,23 +47,22 @@ export const FirstRow = () => {
-
+
*/}
); }; const BasicActionsCard = () => { - const { - changeAccount, - connect, - disconnect, - getAccount, - } = usePaliMethods(); + const { changeAccount, connect, disconnect, getAccount } = usePaliMethods(); const [output, setOutput] = useState(''); const handleExecution = async (fn: () => any) => { - const data = await fn(); - setOutput(JSON.stringify(data)); + try { + const data = await fn(); + setOutput(JSON.stringify(data)); + } catch (err) { + setOutput(JSON.stringify(err)); + } }; return ( @@ -95,4 +92,4 @@ const BasicActionsCard = () => { ); -}; \ No newline at end of file +}; diff --git a/src/components/Rows/SecondRow.tsx b/src/components/Rows/SecondRow.tsx index ef85422..879e88d 100644 --- a/src/components/Rows/SecondRow.tsx +++ b/src/components/Rows/SecondRow.tsx @@ -14,13 +14,17 @@ export const SecondRow = () => { const [output, setOutput] = useState(''); const onSubmit = (type: string) => { - const tx = data[type]; + try { + const tx = data[type]; - const method = `${prefix}_${type}`; + const method = `${prefix}_${type}`; - request(method, [tx]).then((response) => - setOutput(JSON.stringify(response)) - ); + request(method, [tx]).then((response) => + setOutput(JSON.stringify(response)) + ); + } catch (err) { + setOutput(JSON.stringify(err)); + } }; return ( diff --git a/src/components/Rows/ThirdRow.tsx b/src/components/Rows/ThirdRow.tsx index 1c7f8ef..dfe90d0 100644 --- a/src/components/Rows/ThirdRow.tsx +++ b/src/components/Rows/ThirdRow.tsx @@ -1,34 +1,92 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Card } from '../Card'; import { Output } from '../Output'; import { PrimaryButton, Input } from '../Buttons/Button'; +// import { +// isValidEthereumAddress, +// isValidSYSAddress, +// } from '@pollum-io/sysweb3-utils'; +// import { validateEthRpc, validateSysRpc } from '@pollum-io/sysweb3-network'; -export const ThirdRow = () => ( -
- -
- - - -
-
+export const ThirdRow = () => { + const [currentInputValue, setCurrentInputValue] = useState(''); + const [output, setOutput] = useState(''); - -
- - - -
-
+ const handleMethods = (method: string) => { + switch (method) { + // case 'validateEthAddress': + // const isValidEthAddress = isValidEthereumAddress(currentInputValue); + // setOutput(JSON.stringify({ isValidEthAddress })); + // break; + // case 'validateSysAddress': + // const isValidSysAddress = isValidSYSAddress(currentInputValue, 57); + // setOutput(JSON.stringify({ isValidSysAddress })); + // break; + // case 'validateSysRpc': + // const isValidSysRpc = validateSysRpc(currentInputValue); + // setOutput(JSON.stringify({ isValidSysRpc })); + // break; + // case 'validateEthRpc': + // const isValidEthRpc = validateEthRpc(currentInputValue); + // setOutput(JSON.stringify({ isValidEthRpc })); + // break; + } + }; + return ( +
+ +
+ setCurrentInputValue(e.target.value)} + /> + handleMethods('validateEthAddress')} + /> + +
+
- -
- - + +
+ setCurrentInputValue(e.target.value)} + /> + handleMethods('validateSysAddress')} + /> + +
+
- -
-
-
-); + +
+ setCurrentInputValue(e.target.value)} + /> + + + +
+
+ +
+ setCurrentInputValue(e.target.value)} + /> + + + +
+
+
+ ); +}; diff --git a/src/components/SendForm.tsx b/src/components/SendForm.tsx index d844bd5..1705eca 100644 --- a/src/components/SendForm.tsx +++ b/src/components/SendForm.tsx @@ -16,16 +16,6 @@ export const SendForm = () => { const [form] = Form.useForm(); - useEffect(() => { - const estimateFee = async () => { - const fee_ = await request('wallet_estimateFee'); - - form.setFieldsValue({ fee: fee_ }); - }; - - estimateFee(); - }, []); - const onSubmit = (data: any) => { const tx = { amount: Number(data.amount), diff --git a/src/contexts/provider.tsx b/src/contexts/provider.tsx index bb5e1ac..bcb017e 100644 --- a/src/contexts/provider.tsx +++ b/src/contexts/provider.tsx @@ -1,27 +1,31 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; -const storedPrefix = window.localStorage && window.localStorage.getItem('pali_provider'); - -const defaultValue = { provider: window.pali ?? undefined, setProvider: ((state: any) => (state)) as any, setPrefix: ((state: any) => (state)) as any, prefix: storedPrefix || 'sys' }; +const storedPrefix = + window.localStorage && window.localStorage.getItem('pali_prefix'); + +const defaultValue = { + provider: window.pali ?? undefined, + setProvider: ((state: any) => state) as any, + setPrefix: ((state: any) => state) as any, + prefix: storedPrefix || 'sys', +}; const ProviderContext = createContext(defaultValue); -export const PaliWalletProvider = ({ children }: { children: any; }) => { +export const PaliWalletProvider = ({ children }: { children: any }) => { const { pali } = window; - + const [prefix, setPrefix] = useState('sys'); const [provider, setProvider] = useState(pali ?? undefined); const [hydrated, setHydrated] = useState(false); - const network = provider.request({ method: 'wallet_getNetwork', args: [] }); - useEffect(() => { const _provider = prefix === 'sys' ? window.pali : window.ethereum; setProvider(_provider); - window.localStorage.setItem('pali_provider', prefix); - }, [prefix, network]); + window.localStorage.setItem('pali_prefix', prefix); + }, [prefix]); useEffect(() => { setPrefix(storedPrefix); @@ -34,7 +38,9 @@ export const PaliWalletProvider = ({ children }: { children: any; }) => { } return ( - + {children} ); diff --git a/src/contexts/requests.tsx b/src/contexts/requests.tsx index 09b0c0b..304189e 100644 --- a/src/contexts/requests.tsx +++ b/src/contexts/requests.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useState } from 'react'; +import React, { createContext, useContext, useEffect, useState } from 'react'; import { initialNetworksState } from '../data'; import { useProviderContext } from './provider'; @@ -7,31 +7,80 @@ const defaultValue: any = {}; const PaliMethodsContext = createContext(defaultValue); -export const PaliMethodsProvider = ({ children }: { children: any; }) => { +export const PaliMethodsProvider = ({ children }: { children: any }) => { const [account, setAccount] = useState(null); const [network, setNetwork] = useState(initialNetworksState); - + const prefix = localStorage.getItem('pali_prefix'); const { provider } = useProviderContext(); + const state = prefix === 'sys' ? '_sysState' : '_state'; + + const isInstalled = provider !== undefined; + const isConnectedInDapp = + prefix === 'sys' + ? provider[state].xpub !== null + : provider[state].isConnected; + + const setupState = async () => { + const { isBitcoinBased, isUnlocked } = await provider[state]; - const isInstalled = () => provider !== undefined; + const shouldSwitchNetwork = + (isBitcoinBased && prefix === 'eth') || + (!isBitcoinBased && prefix === 'sys'); - const setConnectedAccount = () => getAccount().then((response: any) => setAccount(response)); + switch (shouldSwitchNetwork) { + case true: + if (account && isUnlocked) { + await provider.request({ + method: `${prefix}_changeUTXOEVM`, + params: [{ chainId: 57 }], + }); + } + break; + case false: + if (isUnlocked) { + provider + .request({ method: 'wallet_getAccount', params: [] }) + .then((account) => { + setAccount(account); + }); + } + break; + } + provider + .request({ method: 'wallet_getNetwork', params: [] }) + .then((currentNetwork) => { + if (currentNetwork) { + if (isUnlocked) { + setNetwork(currentNetwork); + return; + } + } + }); + }; //* Event listeners - if (isInstalled()) { - provider.on('connect', () => setConnectedAccount()); - provider.on('disconnect', () => setAccount(null)); - provider.on('accountChange', () => setConnectedAccount()); - provider.on('chainChange', () => { - getNetwork().then((response: any) => setNetwork(response)); - setConnectedAccount(); - }); - } + + useEffect(() => { + if (isInstalled && isConnectedInDapp) { + setupState(); + } + }, [prefix, provider]); //* Default methods const isConnected = () => provider.isConnected(); - const connect = () => provider.enable(); - const disconnect = () => provider.disable(); + const connect = async () => { + const account = await provider.request({ + method: `${prefix}_requestAccounts`, + params: [], + }); + setupState(); + return account; + }; + const disconnect = () => { + setAccount(null); + setNetwork(initialNetworksState); + return provider.disable(); + }; //* Requests const request = (method: string, args?: any[]) => @@ -54,11 +103,15 @@ export const PaliMethodsProvider = ({ children }: { children: any; }) => { getAccount, getNetwork, signTypedDataV4, - } + }; return ( - + {children} );