Ready Mobile for your react native app

You can connect your mobile native application to Ready with Wallet Connect.

Step 1: Install packages

First, install the required packages from WalletConnect (now Reown):

pnpm install @walletconnect/universal-provider @walletconnect/types @walletconnect/core @walletconnect/react-native-compat

Step 2: Configure URL Schemes

For an EXPO project, update your app.json:

{
  "expo": {
    "scheme": "yourappscheme",
    "ios": {
      "infoPlist": {
        "LSApplicationQueriesSchemes": [
          "argent",
          "argentx",
          "argentmobile"
        ]
      }
    }
  }
}

Step 3: Initialize the WalletConnect Provider

const initializeProvider = async () => {
  try {
    console.log('Initializing provider...');

    const projectId = 'your wallet connect project id';

    const metadata = {
      name: 'Wallet connect Test',
      description: 'Test app for connecting to Ready',
      url: 'https://walletconnect.com/',
      icons: ['https://avatars.githubusercontent.com/u/37784886'],
    };

    const providerInstance = await UniversalProvider.init({
      projectId,
      metadata,
      relayUrl: 'wss://relay.walletconnect.com',
    });

    console.log('Provider initialized successfully');
    return providerInstance;
  } catch (err: any) {
    console.error('Error initializing provider:', err);
    throw err;
  }
};

Step 4: Initialize the Provider on Component Mount

Add a useEffect hook to initialize the provider when the component mounts:

useEffect(() => {
  initializeProvider()
    .then((prov) => {
      console.log('Provider initialized successfully');
      setProvider(prov);

      // Check if we already have an active session
      const activeSessions = Object.values(prov.session || {});
      if (activeSessions.length > 0) {
        console.log('Found active session:', activeSessions[0]);
        setSession(activeSessions[0] as SessionTypes.Struct);

        // Extract account if available
        const starknetAccounts =
          activeSessions[0]?.namespaces?.starknet?.accounts;
        if (starknetAccounts && starknetAccounts.length > 0) {
          const accountAddress = starknetAccounts[0].split(':')[2];
          setAccount(accountAddress);
        }
      }
    })
    .catch((err) => {
      console.error('Provider initialization failed:', err);
      setError('Setup failed: ' + (err?.message || 'Unknown error'));
    });
}, []);

Step 5: Implement Deep Linking to Ready Mobile

Add a function to open the Ready Mobile wallet:

const openWallet = async (uri: string) => {
  const encodedUri = encodeURIComponent(uri);

  // Use Argent's deep link scheme
  const argentScheme = `ready://wc?uri=${encodedUri}`;
  console.log('Opening Ready with scheme:', argentScheme);

  try {
    await Linking.openURL(argentScheme);
    console.log('Successfully opened Ready');
  } catch (err) {
    console.error('Failed to open Ready:', err);
    setError(
      'Failed to open Ready. Please make sure it is installed.'
    );
  }
};

Step 6: Connect to Ready Mobile

const connect = async () => {
  if (!provider) return;
  
  try {
    // Request connection
    const { uri, approval } = await provider.client.connect({
      requiredNamespaces: {
        starknet: {
          chains: ['starknet:SNMAIN'], // Use SNSEPOLIA for Sepolia testnet
          methods: ['starknet_account', 'starknet_requestAddInvokeTransaction'],
          events: ['accountsChanged', 'chainChanged']
        }
      }
    });
    
    // Open wallet with URI
    if (uri) {
      const encodedUri = encodeURIComponent(uri);
      await Linking.openURL(`ready://wc?uri=${encodedUri}`);
    }
    
    // Wait for approval
    const newSession = await approval();
    setSession(newSession);
    
    // Extract account
    if (newSession?.namespaces?.starknet?.accounts?.length > 0) {
      setAccount(newSession.namespaces.starknet.accounts[0].split(':')[2]);
    }
  } catch (err) {
    setError(err.message);
  }
};

Step 7: Disconnect from the wallet

const disconnect = async () => {
  if (!provider || !session) return;
  
  try {
    await provider.disconnect();
    setSession(null);
    setAccount(null);
    setTxHash(null);
  } catch (err) {
    setError(err.message);
  }
};

Step 8: Send a Transaction

To send requests to the client, the chainId is required.

Use the following chainID:

  • Starknet mainnet: starknet:SNMAIN

  • Starknet Sepolia: starknet:SNSEPOLIA

const sendTransaction = async () => {
  if (!provider || !session || !account) return;
  
  try {
    // Try to open Ready
    await Linking.openURL('ready://');
    
    // Create transaction
    const transaction = {
      accountAddress: account,
      executionRequest: {
        calls: [
          {
            contractAddress: '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', // ETH token
            entrypoint: 'transfer',
            calldata: [
              account, // to (self)
              amount, // u256.low
              '0x0' // u256.high
            ]
          }
        ]
      }
    };
    
    // Send transaction request
    const result = await provider.client.request({
      topic: session.topic,
      chainId: 'starknet:SNMAIN', // Or starknet:SNSEPOLIA
      request: {
        method: 'starknet_requestAddInvokeTransaction',
        params: {
          accountAddress: transaction.accountAddress,
          executionRequest: transaction.executionRequest
        }
      }
    });
    
    if (result?.transaction_hash) {
      setTxHash(result.transaction_hash);
    }
  } catch (err) {
    setError(err.message);
  }
};

The full example is in this repo: demo-walletconnect-rn-mobile

You will also need the specific Wallet Connect RPC reference for Starknet.

Last updated

Was this helpful?