refactor(with-solana): handle multiple pubKeys via mapping

This commit is contained in:
Ben Kremer 2022-03-14 17:48:46 +01:00
parent 081ae11986
commit 9b59d1a94e
4 changed files with 50 additions and 39 deletions

View File

@ -49,7 +49,7 @@ export default function App() {
disconnect, disconnect,
chain, chain,
accounts, accounts,
publicKey, publicKeys,
balances, balances,
chainData, chainData,
isInitializing, isInitializing,
@ -83,14 +83,22 @@ export default function App() {
await ping(); await ping();
}; };
const testSignTransaction = async (): Promise<IFormattedRpcResponse> => { const testSignTransaction = async (account: string): Promise<IFormattedRpcResponse> => {
if (!client || !publicKey || !session) { if (!client || !publicKeys || !session) {
throw new Error("WalletConnect Client not initialized properly."); 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({ SystemProgram.transfer({
fromPubkey: publicKey, fromPubkey: senderPublicKey,
toPubkey: Keypair.generate().publicKey, toPubkey: Keypair.generate().publicKey,
lamports: 1, lamports: 1,
}), }),
@ -132,19 +140,21 @@ export default function App() {
}; };
const getSolanaActions = (): AccountAction[] => { const getSolanaActions = (): AccountAction[] => {
const wrapRpcRequest = (rpcRequest: () => Promise<IFormattedRpcResponse>) => async () => { const wrapRpcRequest =
openRequestModal(); (rpcRequest: (account: string) => Promise<IFormattedRpcResponse>) =>
try { async (account: string) => {
setIsRpcRequestPending(true); openRequestModal();
const result = await rpcRequest(); try {
setRpcResult(result); setIsRpcRequestPending(true);
} catch (error) { const result = await rpcRequest(account);
console.error("RPC request failed:", error); setRpcResult(result);
setRpcResult({ result: error as string }); } catch (error) {
} finally { console.error("RPC request failed:", error);
setIsRpcRequestPending(false); setRpcResult({ result: error as string });
} } finally {
}; setIsRpcRequestPending(false);
}
};
return [ return [
{ {

View File

@ -120,7 +120,7 @@ function getBlockchainDisplayData(
const Blockchain: FC<PropsWithChildren<BlockchainProps>> = ( const Blockchain: FC<PropsWithChildren<BlockchainProps>> = (
props: PropsWithChildren<BlockchainProps>, props: PropsWithChildren<BlockchainProps>,
) => { ) => {
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; // if (!Object.keys(chainData).length) return null;
@ -167,7 +167,7 @@ const Blockchain: FC<PropsWithChildren<BlockchainProps>> = (
</Column> </Column>
</SFullWidthContainer> </SFullWidthContainer>
) : null} ) : null}
{!!actions && actions.length ? ( {address && !!actions && actions.length ? (
<SFullWidthContainer> <SFullWidthContainer>
<h6>Methods</h6> <h6>Methods</h6>
{actions.map(action => ( {actions.map(action => (
@ -175,7 +175,7 @@ const Blockchain: FC<PropsWithChildren<BlockchainProps>> = (
key={action.method} key={action.method}
left left
rgb={chain.meta.rgb} rgb={chain.meta.rgb}
onClick={() => action.callback(chainId)} onClick={() => action.callback(address)}
> >
{action.method} {action.method}
</SAction> </SAction>

View File

@ -21,11 +21,6 @@ import { AccountBalances, ChainNamespaces, getAllChainNamespaces } from "../help
* Types * Types
*/ */
export enum SolanaChainId {
Mainnet = "solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ",
Devnet = "solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K",
}
export enum SolanaRpcMethod { export enum SolanaRpcMethod {
SOL_SIGN_TRANSACTION = "sol_signTransaction", SOL_SIGN_TRANSACTION = "sol_signTransaction",
} }
@ -36,7 +31,7 @@ interface IContext {
isInitializing: boolean; isInitializing: boolean;
chain: string; chain: string;
pairings: string[]; pairings: string[];
publicKey?: PublicKey; publicKeys?: Record<string, PublicKey>;
accounts: string[]; accounts: string[];
balances: AccountBalances; balances: AccountBalances;
chainData: ChainNamespaces; chainData: ChainNamespaces;
@ -61,7 +56,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
const [balances, setBalances] = useState<AccountBalances>({}); const [balances, setBalances] = useState<AccountBalances>({});
const [accounts, setAccounts] = useState<string[]>([]); const [accounts, setAccounts] = useState<string[]>([]);
const [publicKey, setPublicKey] = useState<PublicKey>(); const [publicKeys, setPublicKeys] = useState<Record<string, PublicKey>>();
const [chainData, setChainData] = useState<ChainNamespaces>({}); const [chainData, setChainData] = useState<ChainNamespaces>({});
const [chain, setChain] = useState<string>(""); const [chain, setChain] = useState<string>("");
@ -69,7 +64,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
setPairings([]); setPairings([]);
setSession(undefined); setSession(undefined);
setBalances({}); setBalances({});
setPublicKey(undefined); setPublicKeys(undefined);
setAccounts([]); setAccounts([]);
setChain(""); setChain("");
}; };
@ -94,17 +89,23 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
}; };
const onSessionConnected = useCallback(async (_session: SessionTypes.Settled) => { const onSessionConnected = useCallback(async (_session: SessionTypes.Settled) => {
const account = _session.state.accounts[0].split(":").pop(); // Create a map of Solana address -> publicKey.
if (!account) { const _publicKeys = _session.state.accounts.reduce(
throw new Error("Could not derive account address from `session.state.accounts`."); (publicKeysMap: Record<string, PublicKey>, account) => {
} const address = account.split(":").pop();
if (!address) {
const _publicKey = new PublicKey(account); throw new Error(`Could not derive Solana address from CAIP account: ${account}`);
}
publicKeysMap[address] = new PublicKey(address);
return publicKeysMap;
},
{},
);
setSession(_session); setSession(_session);
setChain(_session.permissions.blockchain.chains[0]); setChain(_session.permissions.blockchain.chains[0]);
setAccounts(_session.state.accounts); setAccounts(_session.state.accounts);
setPublicKey(_publicKey); setPublicKeys(_publicKeys);
}, []); }, []);
const disconnect = useCallback(async () => { const disconnect = useCallback(async () => {
@ -236,7 +237,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
pairings, pairings,
isInitializing, isInitializing,
balances, balances,
publicKey, publicKeys,
accounts, accounts,
chain, chain,
client, client,
@ -249,7 +250,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
pairings, pairings,
isInitializing, isInitializing,
balances, balances,
publicKey, publicKeys,
accounts, accounts,
chain, chain,
client, client,

View File

@ -150,7 +150,7 @@ export interface ChainNamespaces {
export interface AccountAction { export interface AccountAction {
method: string; method: string;
callback: (chainId: string) => Promise<void>; callback: (account: string) => Promise<void>;
} }
export interface AccountBalances { export interface AccountBalances {