fix(cosmos-provider): ensures proper multi-account request handling

This commit is contained in:
Ben Kremer 2022-03-14 16:24:29 +01:00
parent cb648ace48
commit 081ae11986
4 changed files with 59 additions and 46 deletions

View File

@ -87,7 +87,7 @@ export default function App() {
await ping(); await ping();
}; };
const testSignDirect: () => Promise<IFormattedRpcResponse> = async () => { const testSignDirect: (account: string) => Promise<IFormattedRpcResponse> = async account => {
if (!cosmosProvider) { if (!cosmosProvider) {
throw new Error("cosmosProvider not connected"); throw new Error("cosmosProvider not connected");
} }
@ -116,7 +116,7 @@ export default function App() {
"cosmoshub-4", "cosmoshub-4",
); );
const [address] = cosmosProvider.accounts; const address = account.split(":").pop();
// cosmos_signDirect params // cosmos_signDirect params
const params = { const params = {
@ -137,7 +137,7 @@ export default function App() {
}; };
}; };
const testSignAmino: () => Promise<IFormattedRpcResponse> = async () => { const testSignAmino: (account: string) => Promise<IFormattedRpcResponse> = async account => {
if (!cosmosProvider) { if (!cosmosProvider) {
throw new Error("cosmosProvider not connected"); throw new Error("cosmosProvider not connected");
} }
@ -152,7 +152,7 @@ export default function App() {
sequence: "54", sequence: "54",
}; };
const [address] = cosmosProvider.accounts; const address = account.split(":").pop();
// cosmos_signAmino params // cosmos_signAmino params
const params = { signerAddress: address, signDoc }; const params = { signerAddress: address, signDoc };
@ -171,19 +171,21 @@ export default function App() {
}; };
const getCosmosActions = (): AccountAction[] => { const getCosmosActions = (): 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 [
{ method: "cosmos_signDirect", callback: wrapRpcRequest(testSignDirect) }, { method: "cosmos_signDirect", callback: wrapRpcRequest(testSignDirect) },

View File

@ -155,7 +155,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 => (
@ -163,7 +163,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

@ -89,29 +89,43 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
await cosmosProvider.disconnect(); await cosmosProvider.disconnect();
}, [cosmosProvider]); }, [cosmosProvider]);
const _subscribeToClientEvents = useCallback(async (_client: Client) => { const onSessionConnected = useCallback(async (_session: SessionTypes.Settled) => {
if (typeof _client === "undefined") { setSession(_session);
throw new Error("WalletConnect is not initialized"); setChain(_session.permissions.blockchain.chains[0]);
} setAccounts(_session.state.accounts);
_client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: PairingTypes.Proposal) => {
const { uri } = proposal.signal.params;
console.log("EVENT", "QR Code Modal open");
QRCodeModal.open(uri, () => {
console.log("EVENT", "QR Code Modal closed");
});
});
_client.on(CLIENT_EVENTS.pairing.created, async () => {
setPairings(_client.pairing.topics);
});
_client.on(CLIENT_EVENTS.session.deleted, () => {
console.log("EVENT", "session_deleted");
resetApp();
});
}, []); }, []);
const _subscribeToClientEvents = useCallback(
async (_client: Client) => {
if (typeof _client === "undefined") {
throw new Error("WalletConnect is not initialized");
}
_client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: PairingTypes.Proposal) => {
const { uri } = proposal.signal.params;
console.log("EVENT", "QR Code Modal open");
QRCodeModal.open(uri, () => {
console.log("EVENT", "QR Code Modal closed");
});
});
_client.on(CLIENT_EVENTS.pairing.created, async () => {
setPairings(_client.pairing.topics);
});
_client.on(CLIENT_EVENTS.session.updated, (updatedSession: SessionTypes.Settled) => {
console.log("EVENT", "session_updated");
onSessionConnected(updatedSession);
});
_client.on(CLIENT_EVENTS.session.deleted, () => {
console.log("EVENT", "session_deleted");
resetApp();
});
},
[onSessionConnected],
);
const createClient = useCallback(async () => { const createClient = useCallback(async () => {
try { try {
setIsInitializing(true); setIsInitializing(true);
@ -161,16 +175,13 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
return; return;
} }
const _accounts = cosmosProvider.accounts;
const _session = await client.session.get(client.session.topics[0]); const _session = await client.session.get(client.session.topics[0]);
setAccounts(_accounts); onSessionConnected(_session);
setSession(_session);
setChain(caipChainId);
QRCodeModal.close(); QRCodeModal.close();
}, },
[client], [client, onSessionConnected],
); );
const _checkForPersistedSession = useCallback( const _checkForPersistedSession = useCallback(

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 {