Skip to content

Commit

Permalink
WC migration to WalletKit (#6163)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunobar79 authored and greg-schrammel committed Oct 16, 2024
1 parent 78d9d96 commit 2fe9933
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 223 deletions.
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ PODS:
- React-Core
- react-native-cloud-fs (2.6.2):
- React
- react-native-compat (2.15.1):
- react-native-compat (2.17.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -2352,7 +2352,7 @@ SPEC CHECKSUMS:
react-native-cameraroll: b5ce04a1ee4081d7eea921918de979f0b41d8e22
react-native-change-icon: ea9bb7255b09e89f41cbf282df16eade91ab1833
react-native-cloud-fs: c90379f513b8d7ad5cfed610ccf50f27d837016e
react-native-compat: 408a4b320fa4426f2c25ab74ed5764be6b3eb5aa
react-native-compat: 4e82fe33d1af54feba2f25d3d88f2b4d8e5c2b78
react-native-get-random-values: 1404bd5cc0ab0e287f75ee1c489555688fc65f89
react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5
react-native-mail: a864fb211feaa5845c6c478a3266de725afdce89
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
"@react-navigation/material-top-tabs": "6.6.2",
"@react-navigation/native": "6.1.17",
"@react-navigation/stack": "6.3.29",
"@reown/walletkit": "^1.0.0",
"@reservoir0x/reservoir-sdk": "2.3.0",
"@rudderstack/rudder-sdk-react-native": "1.12.1",
"@sentry/react-native": "5.31.1",
Expand All @@ -140,12 +141,11 @@
"@unstoppabledomains/resolution": "7.1.4",
"@wagmi/chains": "1.8.0",
"@walletconnect/client": "1.8.0",
"@walletconnect/core": "2.15.1",
"@walletconnect/core": "2.17.0",
"@walletconnect/legacy-utils": "2.0.0",
"@walletconnect/react-native-compat": "2.15.1",
"@walletconnect/types": "2.15.1",
"@walletconnect/utils": "2.15.1",
"@walletconnect/web3wallet": "1.14.1",
"@walletconnect/react-native-compat": "2.17.0",
"@walletconnect/types": "2.17.0",
"@walletconnect/utils": "2.17.0",
"assert": "1.5.0",
"async-mutex": "0.3.2",
"asyncstorage-down": "4.2.0",
Expand Down
115 changes: 60 additions & 55 deletions src/walletConnect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { formatJsonRpcResult, formatJsonRpcError } from '@json-rpc-tools/utils';
import { gretch } from 'gretchen';
import messaging from '@react-native-firebase/messaging';
import WalletConnectCore, { Core } from '@walletconnect/core';
import Client, { Web3Wallet, Web3WalletTypes } from '@walletconnect/web3wallet';
import { WalletKit, WalletKitTypes, IWalletKit } from '@reown/walletkit';
import { isHexString } from '@ethersproject/bytes';
import { toUtf8String } from '@ethersproject/strings';

Expand Down Expand Up @@ -96,20 +96,20 @@ let lastConnector: string | undefined = undefined;

let walletConnectCore: WalletConnectCore | undefined;

let web3WalletClient: ReturnType<(typeof Web3Wallet)['init']> | undefined;
let walletKitClient: ReturnType<(typeof WalletKit)['init']> | undefined;

let initPromise: Promise<Client> | undefined = undefined;
let initPromise: Promise<IWalletKit> | undefined = undefined;

let syncWeb3WalletClient: Client | undefined = undefined;
let syncWalletKitClient: IWalletKit | undefined = undefined;

export const initializeWCv2 = async () => {
if (!walletConnectCore) {
walletConnectCore = new Core({ projectId: WC_PROJECT_ID });
}

if (!web3WalletClient) {
if (!walletKitClient) {
// eslint-disable-next-line require-atomic-updates
web3WalletClient = Web3Wallet.init({
walletKitClient = WalletKit.init({
core: walletConnectCore,
metadata: {
name: '🌈 Rainbow',
Expand All @@ -124,10 +124,10 @@ export const initializeWCv2 = async () => {
});
}

return web3WalletClient;
return walletKitClient;
};

export async function getWeb3WalletClient() {
export async function getWalletKitClient() {
if (!initPromise) {
initPromise = initializeWCv2();
}
Expand Down Expand Up @@ -196,7 +196,7 @@ export function parseRPCParams({ method, params }: RPCPayload): {
/**
* Better signature for this type of function
*
* @see https://docs.walletconnect.com/2.0/web/web3wallet/wallet-usage#-namespaces-builder-util
* @see https://docs.walletconnect.com/2.0/web/walletKit/wallet-usage#-namespaces-builder-util
*/
export function getApprovedNamespaces(props: Parameters<typeof buildApprovedNamespaces>[0]):
| {
Expand Down Expand Up @@ -303,15 +303,15 @@ async function rejectProposal({
proposal,
reason,
}: {
proposal: Web3WalletTypes.SessionProposal;
proposal: WalletKitTypes.SessionProposal;
reason: Parameters<typeof getSdkError>[0];
}) {
logger.warn(`[walletConnect]: session approval denied`, {
reason,
proposal,
});

const client = await getWeb3WalletClient();
const client = await getWalletKitClient();
const { id, proposer } = proposal.params;

await client.rejectSession({ id, reason: getSdkError(reason) });
Expand All @@ -323,11 +323,10 @@ async function rejectProposal({
}

// listen for THIS topic pairing, and clear timeout if received
function trackTopicHandler(proposal: Web3WalletTypes.SessionProposal | Web3WalletTypes.AuthRequest) {
function trackTopicHandler(proposal: WalletKitTypes.SessionProposal | WalletKitTypes.SessionAuthenticate) {
logger.debug(`[walletConnect]: pair: handler`, { proposal });

const { metadata } =
(proposal as Web3WalletTypes.SessionProposal).params.proposer || (proposal as Web3WalletTypes.AuthRequest).params.requester;
const { metadata } = 'proposer' in proposal.params ? proposal.params.proposer : proposal.params.requester;

analytics.track(analytics.event.wcNewPairing, {
dappName: metadata.name,
Expand All @@ -344,7 +343,7 @@ export async function pair({ uri, connector }: { uri: string; connector?: string
*/

const { topic, ...rest } = parseUri(uri);
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

logger.debug(`[walletConnect]: pair: parsed uri`, { topic, rest });

Expand All @@ -355,16 +354,16 @@ export async function pair({ uri, connector }: { uri: string; connector?: string
export async function initListeners() {
PerformanceTracking.startMeasuring(PerformanceMetrics.initializeWalletconnect);

const client = await getWeb3WalletClient();
const client = await getWalletKitClient();
PerformanceTracking.finishMeasuring(PerformanceMetrics.initializeWalletconnect);

syncWeb3WalletClient = client;
syncWalletKitClient = client;

logger.debug(`[walletConnect]: web3WalletClient initialized, initListeners`, {}, logger.DebugContext.walletconnect);
logger.debug(`[walletConnect]: walletKitClient initialized, initListeners`, {}, logger.DebugContext.walletconnect);

client.on('session_proposal', onSessionProposal);
client.on('session_request', onSessionRequest);
client.on('auth_request', onAuthRequest);
client.on('session_authenticate', onSessionAuthenticate);
client.on('session_delete', () => {
logger.debug(`[walletConnect]: session_delete`, {}, logger.DebugContext.walletconnect);

Expand All @@ -379,7 +378,7 @@ export async function initWalletConnectPushNotifications() {
const token = await getFCMToken();

if (token) {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();
const client_id = await client.core.crypto.getClientId();

// initial subscription
Expand Down Expand Up @@ -429,7 +428,7 @@ async function subscribeToEchoServer({ client_id, token }: { client_id: string;
}
}

export async function onSessionProposal(proposal: Web3WalletTypes.SessionProposal) {
export async function onSessionProposal(proposal: WalletKitTypes.SessionProposal) {
try {
trackTopicHandler(proposal);

Expand Down Expand Up @@ -468,7 +467,8 @@ export async function onSessionProposal(proposal: Web3WalletTypes.SessionProposa
verifiedData,
timedOut: false,
callback: async (approved, approvedChainId, accountAddress) => {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

const { id, proposer, requiredNamespaces } = proposal.params;

if (approved) {
Expand Down Expand Up @@ -592,12 +592,14 @@ export async function onSessionProposal(proposal: Web3WalletTypes.SessionProposa
// For WC v2
export async function onSessionRequest(event: SignClientTypes.EventArguments['session_request']) {
setHasPendingDeeplinkPendingRedirect(true);
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

logger.debug(`[walletConnect]: session_request`, {}, logger.DebugContext.walletconnect);

const { id, topic } = event;
const { method, params } = event.params.request;
const { method: _method, params } = event.params.request;

const method = _method as RPCMethod;

logger.debug(`[walletConnect]: session_request method`, { method, params }, logger.DebugContext.walletconnect);

Expand All @@ -615,10 +617,10 @@ export async function onSessionRequest(event: SignClientTypes.EventArguments['se
});
return;
}
if (isSupportedMethod(method as RPCMethod)) {
const isSigningMethod = isSupportedSigningMethod(method as RPCMethod);
if (isSupportedMethod(method)) {
const isSigningMethod = isSupportedSigningMethod(method);
const { address, message } = parseRPCParams({
method: method as RPCMethod,
method,
params,
});
if (!address) {
Expand Down Expand Up @@ -808,7 +810,7 @@ export async function handleSessionRequestResponse(
success: Boolean(result),
});

const client = await getWeb3WalletClient();
const client = await getWalletKitClient();
const { topic, id } = sessionRequestEvent;
if (result) {
const payload = {
Expand All @@ -829,32 +831,33 @@ export async function handleSessionRequestResponse(
store.dispatch(removeRequest(sessionRequestEvent.id));
}

export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {
export async function onSessionAuthenticate(event: WalletKitTypes.SessionAuthenticate) {
trackTopicHandler(event);

const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

logger.debug(`[walletConnect]: auth_request`, { event }, logger.DebugContext.walletconnect);

const authenticate: AuthRequestAuthenticateSignature = async ({ address }) => {
try {
const { wallets } = store.getState().wallets;
const selectedWallet = findWalletWithAccount(wallets!, address);
const selectedWallet = findWalletWithAccount(wallets || {}, address);
const isHardwareWallet = selectedWallet?.type === WalletTypes.bluetooth;
const iss = `did:pkh:eip155:1:${address}`;

// exit early if possible
if (selectedWallet?.type === WalletTypes.readOnly) {
await client.respondAuthRequest(
{
await client.respondSessionRequest({
topic: event.topic,
response: {
id: event.id,
error: {
code: 0,
message: `Wallet is read-only`,
},
jsonrpc: '2.0',
},
iss
);
});

return {
success: false,
Expand All @@ -875,8 +878,10 @@ export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {

return undefined;
}

const message = client.formatMessage(event.params.cacaoPayload, iss);
const message = client.formatAuthMessage({
iss,
request: event.params.authPayload,
});
// prompt the user to sign the message
return wallet.signMessage(message);
};
Expand Down Expand Up @@ -904,16 +909,19 @@ export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {
}

// respond to WC
await client.respondAuthRequest(
{
await client.respondSessionRequest({
topic: event.topic,
response: {
id: event.id,
signature: {
s: signature,
t: 'eip191',
},
result: JSON.stringify({
signature: {
s: signature,
t: 'eip191',
},
}),
jsonrpc: '2.0',
},
iss
);
});

// only handled on success
maybeGoBackAndClearHasPendingRedirect({ delay: 300 });
Expand All @@ -928,9 +936,7 @@ export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {
};

// need to prefetch dapp metadata since portal is static
const url =
// @ts-ignore Web3WalletTypes.AuthRequest type is missing VerifyContext
event?.verifyContext?.origin || event.params.requester.metadata.url;
const url = event?.verifyContext?.verified?.origin || event.params.requester.metadata.url;
const metadata = await fetchDappMetadata({ url, status: true });

const isScam = metadata.status === DAppStatus.Scam;
Expand All @@ -939,8 +945,7 @@ export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {
AuthRequest({
authenticate,
requesterMeta: event.params.requester.metadata,
// @ts-ignore Web3WalletTypes.AuthRequest type is missing VerifyContext
verifiedData: event?.verifyContext,
verifiedData: event?.verifyContext.verified,
}),
{ sheetHeight: IS_ANDROID ? 560 : 520 + (isScam ? 40 : 0) }
);
Expand All @@ -950,7 +955,7 @@ export async function onAuthRequest(event: Web3WalletTypes.AuthRequest) {
* Returns all active settings in a type-safe manner.
*/
export async function getAllActiveSessions() {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();
return Object.values(client?.getActiveSessions() || {}) || [];
}

Expand All @@ -959,15 +964,15 @@ export async function getAllActiveSessions() {
* in a type-safe manner.
*/
export function getAllActiveSessionsSync() {
return Object.values(syncWeb3WalletClient?.getActiveSessions() || {}) || [];
return Object.values(syncWalletKitClient?.getActiveSessions() || {}) || [];
}

/**
* Adds an account to an existing session
*/
export async function addAccountToSession(session: SessionTypes.Struct, { address }: { address?: string }) {
try {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

const namespaces: Parameters<typeof client.updateSession>[0]['namespaces'] = {};
for (const [key, value] of Object.entries(session.namespaces)) {
Expand Down Expand Up @@ -1028,7 +1033,7 @@ export async function addAccountToSession(session: SessionTypes.Struct, { addres

export async function changeAccount(session: SessionTypes.Struct, { address }: { address?: string }) {
try {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

/*
* Before we can effectively switch accounts, we need to add the account to
Expand Down Expand Up @@ -1078,7 +1083,7 @@ export async function changeAccount(session: SessionTypes.Struct, { address }: {
* within a dapp is handled internally by WC v2.
*/
export async function disconnectSession(session: SessionTypes.Struct) {
const client = await getWeb3WalletClient();
const client = await getWalletKitClient();

await client.disconnectSession({
topic: session.topic,
Expand Down
Loading

0 comments on commit 2fe9933

Please sign in to comment.