wallet-adapter: Vue: WalletSignTransactionError: Blocked a frame with origin "https://domain.xyz" from accessing a cross-origin frame.

After integrating the sol wallet adapter, some of the wallets work fine (phantom, sollet extensions) but with others (sollet in particular) I’m getting this error:

Transaction failed, WalletSignTransactionError: Blocked a frame with origin "https://domain.xyz" from accessing a cross-origin frame.
Some transactions failed. Please re-run or see browser console to debug.

Connecting to the wallet works fine - the issue arises only when actually trying to sign the transction.

Test both on localhost (http) and in prod (https) - same result.

Any ideas?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (3 by maintainers)

Most upvoted comments

Just in case others are finding this thread and want the TLDR solution it’s:

Wherever you store you WalletAdapter (not just Wallet!) variable, change it from this:

wallet: null; //options api
const walletAdapter = ref(null); //composition api

to this:

import {shallowRef} from 'vue'

wallet: shallowRef(null); //options api
const walletAdapter = ref(shallowRef(null)); //composition api

At first I thought it wouldn’t work coz we’re overwriting the adapter when we assign it, but it does work and solve the issue. Vue magic ¯_(ツ)_/¯

See this PR for an example.

@steveluscher @2501babe @lorisleiva absolute legends you all, thank you so much for saving the day ❤️

PS I also updated the title to be more descriptive that i’s a Vue-specific issue.

That’s an interesting one haha. I’d love to know if this also happens when using the https://www.npmjs.com/package/@solana/wallet-adapter-vue package.

For this particular example, the wallet object is declared in the data() method which automatically makes it reactive.

Reactivity is recursive in objects and therefore, any sub-objects such as _popup would also be reactive, causing the CORS issue.

Alternatively, you can use Refs in Vue 3 which only wraps the root object (or the primitive) into a reactive reference that you have to access using wallet.value. By using a Ref, nested objects are not recursively reactive and so I believe this would prevent the CORS issue.

Note that the https://www.npmjs.com/package/@solana/wallet-adapter-vue package uses the ref method instead of the reactive method so I’m hopeful the problem doesn’t exist there. 🤞

WOOF

@laurensV Vue 2 is not supported. Vue 3 is required by the related packages in WalletAdapter.

I’m gonna page the Vue master for this one: @lorisleiva

this absolute hero not only isolated the problem without my asking but posted videos showing whats happening. in short: a very ugly interaction between strict cross-origin policies and vue (possibly only vue 3?) reactivity plumbing https://twitter.com/steveluscher/status/1453983387648073732

Thanks for the details, I’ll work on isolating the cause. No worries about not using vue-ui, I doubt it’s related to that.

@jordansexton chiming in here to say that ive had the same issue with both sol-wallet-adapter and wallet-adapter in vue

wallet setup here: https://github.com/2501babe/revoken/blob/master/src/components/Main.vue#L175-L202

usage here: https://github.com/2501babe/revoken/blob/master/src/components/Main.vue#L266-L287

reproduce here: https://2501babe.github.io/tools/revoken.html. you need to have a delegate on some token account. flow is: optionally select a network, select sollet, “connect,” “lets go,” “revoke” (if you see a picture of makima you have no open approvals with that wallet on that network). in the console you should see WalletSignTransactionError: Blocked a frame with origin "https://2501babe.github.io" from accessing a cross-origin frame.

sorry i didnt use the vue ui thing i ran into some trouble due to being a vue brainlet but this should be basically equivalent. i could try again if it would be helpful tho

At a glance, it doesn’t look like you are using https://www.npmjs.com/package/@solana/wallet-adapter-vue which was recently published. Can you try that? At least then we’ll be looking at the same code to test.

We’re using vue, so couldn’t use the react stuff out of the box. The code is:

Integrating the wallet:

const network = WalletAdapterNetwork.Mainnet;
const connectedAdapter = getSolletWallet({network}).adapter();
await connectedAdapter.connect();

Signing the transaction:

const sig = await connectedAdapter.sendTransaction(transaction, this.connection, {
  signers: additionalSigners,
});
await this.connection.confirmTransaction(sig, 'processed');

The repo is oss here, but I realize you probably have better things to do with your time:)

I would have easily assumed it’s a general cors/vue issue - but what’s weird is that only this wallet is throwing the error.

I’ll keep digging and revert if I find a solution.