magiclabs / magic-js

Magic browser/React Native JavaScript SDK is your entry-point to integrating passwordless authentication inside your application.
https://magic.link/docs/api-reference/client-side-sdks/web
Apache License 2.0
462 stars 86 forks source link

@magic-ext/solana signTransaction gets stuck on react native #613

Closed bendgk closed 1 year ago

bendgk commented 1 year ago

✅ Prerequisites

🐛 Description

When following the Solana blockchain integration docs on react-native, I seem to have stumbled upon a nasty bug.

upon calling signTransaction with a valid magic transaction and config (tested my setup in a Vuejs environment perfectly fine) The function call to signTransaction seems to hang and only gets resolved upon multiple repeated calls to signTransaction again.

🧩 Steps to Reproduce

  1. const signedTransaction = await magic.solana.signTransaction(transactionMagic, serializeConfig)
  2. expect the json rpc call to execute (it doesnt)
  3. call signTransaction again
  4. notice the transaction go through

    🤔 Expected behavior

signTransaction to only need to be called once correctly.

😮 Actual behavior

There is also a warning that shows up "No instructions provided." However, this warning also shows up on my vuejs environment where the signTransaction function works perfectly fine.

💻 Code Sample

async function send(
    destinationAddress: string,
    sol: number,
  ): Promise<string | null> {
    const lamports = sol * LAMPORTS_PER_SOL;
    if (!connection || !pubKey || !balance) return null;

    const recipientPubKey = new PublicKey(destinationAddress);
    const hash = await connection.getLatestBlockhash()
    let transactionMagic = new Transaction({
      feePayer: pubKey,
      recentBlockhash: hash.blockhash,
    })

    SystemProgram.transfer({
        fromPubkey: pubKey,
        toPubkey: recipientPubKey,
        lamports,
      })

    transactionMagic.add(...([transaction]))

    const serializeConfig = {
      requireAllSignatures: false,
      verifySignatures: true,
    }
    const signedTransaction = await magic.solana.signTransaction(transactionMagic, serializeConfig)
    const tx = Transaction.from(signedTransaction.rawTransaction);
    return connection.sendRawTransaction(tx.serialize());
  }

where connection is a web3.js Connection pubKey is a web3.js PublicKey balance is a number

🌎 Environment

{
  "name": "quip-app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@ethersproject/shims": "^5.7.0",
    "@expo/metro-config": "^0.10.7",
    "@expo/vector-icons": "^13.0.0",
    "@magic-ext/auth": "^2.3.0",
    "@magic-ext/solana": "^15.3.0",
    "@magic-sdk/provider": "^19.3.0",
    "@magic-sdk/react-native-expo": "^20.3.0",
    "@magic-sdk/types": "^16.3.0",
    "@react-native-async-storage/async-storage": "1.18.2",
    "@solana/web3.js": "^1.78.4",
    "base-64": "^1.0.0",
    "expo": "~49.0.7",
    "expo-dev-client": "~2.4.6",
    "expo-splash-screen": "~0.20.5",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.3",
    "react-native-get-random-values": "~1.9.0",
    "react-native-safe-area-context": "4.6.3",
    "react-native-url-polyfill": "^2.0.0",
    "react-native-webview": "13.2.2",
  },
}
bendgk commented 1 year ago

I'm testing on iphone 12 pro ios: 16.6

The app is being tested on a dev client

bendgk commented 1 year ago

I wasn't following the docs properly. I needed to wrap the m.Relayer component in a SafeAreaProvider from react-native-safe-area-context in the root of my application.