Flutter web-hosted app doesn't recognize external functions

329

After reading your original post on connecting a Phantom wallet with Flutter, I decided to try it out myself, and I eventually ran into the same issue as you, down the to exact function call!

The solution (workaround) for me was to use standalone functions instead of methods.

I do not know why, but for some reason the Dart-JS interop stopped working on class instances after flutter build web. My minified JS code with class instances played nice with flutter run -d chrome.

Edit:

This is the phantom.ts I got working.

const solanaWeb3 = require('@solana/web3.js');

export async function connect(): solanaWeb3.PublicKey {
  const resp = await window.solana.connect();
  return new solanaWeb3.PublicKey(resp.publicKey.toString());
}

export function disconnect() {
  window.solana.disconnect();
}

export function isPhantomInstalled(): bool {
  return window.solana && window.solana.isPhantom;
}

export async function signTransaction(tx: solanaWeb3.Transaction): solanaWeb3.Transaction {
  return await window.solana.signTransaction(tx);
}

Then Dart-side, the interop is the same, just no class definition. I'm going to write a Medium post / release a GitHub repo with an example soon.

Edit 2: Medium post / repo can be found here

Share:
329
ggiurca
Author by

ggiurca

Updated on December 01, 2022

Comments

  • ggiurca
    ggiurca over 1 year

    I'm hosting a web made on Flutter on GitHub pages and I'm using Dart-JS interop for connecting a Solana wallet. When I test locally I can connect to it and works fine but once I host the web on GitHub Pages I get the following error: Uncaught TypeError: p.isPhantomInstalled is not a function

    This is my Dart code:

        @JS('walletModule.ClientWallet')
        class ClientWallet {
          external Future<void> connect();
          external void disconnect();
          external String get address;
          external Future<void> signTransaction();
          external bool isPhantomInstalled();
        }
        
        class WalletController extends GetxController {
        
          Future<void> connectWallet(context) async {
            ClientWallet wallet = ClientWallet();
            if (wallet.isPhantomInstalled()) {
              await promiseToFuture(wallet.connect());
              createSnackbar('success', 'Wallet Connected');
            } else {
              createSnackbar('error', 'No Phantom wallet detected');
            }
          }
    

    This is my JS code:

    class ClientWallet {
    
        constructor() {
            this.address = '';
        }
    
        async connect() {
            const resp = await window.solana.connect();
            this.address = resp.publicKey.toString();
        }
    
        address() {
            return this.address;
        }
    
        isPhantomInstalled() {
            return window.solana && window.solana.isPhantom;
        }
    
        disconnect() {
            window.solana.disconnect();
        }
    }
    
    var walletModule = { ClientWallet: ClientWallet };
    

    It seems that when hosted, the app doesn't recognize the external functions? I have no clue why or how to solve it.

  • ggiurca
    ggiurca over 2 years
    Glad to know that code was useful to someone! Can you share a code snippet on how you made it work? I was able to use standalone functions instead of methods and it works locally but it still doesn't work when served.
  • HelmetFace
    HelmetFace over 2 years
    I edited my original example to show what I got working. It sounds like your problem is more related to paths and namespaces than anything else. How are you injecting the JS into your Flutter build / HTML?
  • ggiurca
    ggiurca over 2 years
    Thanks @HelmetFace, worked like a charm. Please, do not hesitate to link here the Medium article, I'll be waiting to read it!
  • murock
    murock over 2 years
    I'm also very interested in this. I've been struggling to work out how to get the metadata json for an NFT in Flutter. I think your article may help me!
  • HelmetFace
    HelmetFace over 2 years
    Here's the article and accompanying GitHub repo for those interested. blog.auguron.com/flutter-dapps-on-solana-364e81fe73ca