From 9b59d1a94ec6dbb52999ebeefc5f595e21a7ba06 Mon Sep 17 00:00:00 2001 From: Ben Kremer Date: Mon, 14 Mar 2022 17:48:46 +0100 Subject: [PATCH] refactor(with-solana): handle multiple pubKeys via mapping --- .../src/App.tsx | 46 +++++++++++-------- .../src/components/Blockchain.tsx | 6 +-- .../src/contexts/ClientContext.tsx | 35 +++++++------- .../src/helpers/types.ts | 2 +- 4 files changed, 50 insertions(+), 39 deletions(-) diff --git a/dapps/react-dapp-v2-with-solana-web3js/src/App.tsx b/dapps/react-dapp-v2-with-solana-web3js/src/App.tsx index 8a6ddcd..bc9c600 100644 --- a/dapps/react-dapp-v2-with-solana-web3js/src/App.tsx +++ b/dapps/react-dapp-v2-with-solana-web3js/src/App.tsx @@ -49,7 +49,7 @@ export default function App() { disconnect, chain, accounts, - publicKey, + publicKeys, balances, chainData, isInitializing, @@ -83,14 +83,22 @@ export default function App() { await ping(); }; - const testSignTransaction = async (): Promise => { - if (!client || !publicKey || !session) { + const testSignTransaction = async (account: string): Promise => { + if (!client || !publicKeys || !session) { throw new Error("WalletConnect Client not initialized properly."); } - const transaction = new Transaction({ feePayer: publicKey }).add( + const address = account.split(":").pop(); + + if (!address) { + throw new Error(`Could not derive Solana address from CAIP account: ${account}`); + } + + const senderPublicKey = publicKeys[address]; + + const transaction = new Transaction({ feePayer: senderPublicKey }).add( SystemProgram.transfer({ - fromPubkey: publicKey, + fromPubkey: senderPublicKey, toPubkey: Keypair.generate().publicKey, lamports: 1, }), @@ -132,19 +140,21 @@ export default function App() { }; const getSolanaActions = (): AccountAction[] => { - const wrapRpcRequest = (rpcRequest: () => Promise) => async () => { - openRequestModal(); - try { - setIsRpcRequestPending(true); - const result = await rpcRequest(); - setRpcResult(result); - } catch (error) { - console.error("RPC request failed:", error); - setRpcResult({ result: error as string }); - } finally { - setIsRpcRequestPending(false); - } - }; + const wrapRpcRequest = + (rpcRequest: (account: string) => Promise) => + async (account: string) => { + openRequestModal(); + try { + setIsRpcRequestPending(true); + const result = await rpcRequest(account); + setRpcResult(result); + } catch (error) { + console.error("RPC request failed:", error); + setRpcResult({ result: error as string }); + } finally { + setIsRpcRequestPending(false); + } + }; return [ { diff --git a/dapps/react-dapp-v2-with-solana-web3js/src/components/Blockchain.tsx b/dapps/react-dapp-v2-with-solana-web3js/src/components/Blockchain.tsx index 36a06b6..15c4c47 100644 --- a/dapps/react-dapp-v2-with-solana-web3js/src/components/Blockchain.tsx +++ b/dapps/react-dapp-v2-with-solana-web3js/src/components/Blockchain.tsx @@ -120,7 +120,7 @@ function getBlockchainDisplayData( const Blockchain: FC> = ( props: PropsWithChildren, ) => { - const { fetching, chainId, address, onClick, balances, active, actions, isTestnet } = props; + const { fetching, address, onClick, balances, active, actions, isTestnet } = props; // if (!Object.keys(chainData).length) return null; @@ -167,7 +167,7 @@ const Blockchain: FC> = ( ) : null} - {!!actions && actions.length ? ( + {address && !!actions && actions.length ? (
Methods
{actions.map(action => ( @@ -175,7 +175,7 @@ const Blockchain: FC> = ( key={action.method} left rgb={chain.meta.rgb} - onClick={() => action.callback(chainId)} + onClick={() => action.callback(address)} > {action.method} diff --git a/dapps/react-dapp-v2-with-solana-web3js/src/contexts/ClientContext.tsx b/dapps/react-dapp-v2-with-solana-web3js/src/contexts/ClientContext.tsx index 10a0461..42d60da 100644 --- a/dapps/react-dapp-v2-with-solana-web3js/src/contexts/ClientContext.tsx +++ b/dapps/react-dapp-v2-with-solana-web3js/src/contexts/ClientContext.tsx @@ -21,11 +21,6 @@ import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../help * Types */ -export enum SolanaChainId { - Mainnet = "solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ", - Devnet = "solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K", -} - export enum SolanaRpcMethod { SOL_SIGN_TRANSACTION = "sol_signTransaction", } @@ -36,7 +31,7 @@ interface IContext { isInitializing: boolean; chain: string; pairings: string[]; - publicKey?: PublicKey; + publicKeys?: Record; accounts: string[]; balances: AccountBalances; chainData: ChainNamespaces; @@ -61,7 +56,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac const [balances, setBalances] = useState({}); const [accounts, setAccounts] = useState([]); - const [publicKey, setPublicKey] = useState(); + const [publicKeys, setPublicKeys] = useState>(); const [chainData, setChainData] = useState({}); const [chain, setChain] = useState(""); @@ -69,7 +64,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac setPairings([]); setSession(undefined); setBalances({}); - setPublicKey(undefined); + setPublicKeys(undefined); setAccounts([]); setChain(""); }; @@ -94,17 +89,23 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac }; const onSessionConnected = useCallback(async (_session: SessionTypes.Settled) => { - const account = _session.state.accounts[0].split(":").pop(); - if (!account) { - throw new Error("Could not derive account address from `session.state.accounts`."); - } - - const _publicKey = new PublicKey(account); + // Create a map of Solana address -> publicKey. + const _publicKeys = _session.state.accounts.reduce( + (publicKeysMap: Record, account) => { + const address = account.split(":").pop(); + if (!address) { + throw new Error(`Could not derive Solana address from CAIP account: ${account}`); + } + publicKeysMap[address] = new PublicKey(address); + return publicKeysMap; + }, + {}, + ); setSession(_session); setChain(_session.permissions.blockchain.chains[0]); setAccounts(_session.state.accounts); - setPublicKey(_publicKey); + setPublicKeys(_publicKeys); }, []); const disconnect = useCallback(async () => { @@ -236,7 +237,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac pairings, isInitializing, balances, - publicKey, + publicKeys, accounts, chain, client, @@ -249,7 +250,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac pairings, isInitializing, balances, - publicKey, + publicKeys, accounts, chain, client, diff --git a/dapps/react-dapp-v2-with-solana-web3js/src/helpers/types.ts b/dapps/react-dapp-v2-with-solana-web3js/src/helpers/types.ts index 71fc62b..ab9ccca 100644 --- a/dapps/react-dapp-v2-with-solana-web3js/src/helpers/types.ts +++ b/dapps/react-dapp-v2-with-solana-web3js/src/helpers/types.ts @@ -150,7 +150,7 @@ export interface ChainNamespaces { export interface AccountAction { method: string; - callback: (chainId: string) => Promise; + callback: (account: string) => Promise; } export interface AccountBalances {