Skip to content

Provider API

Use the provider Morsel injects into web pages to connect, sign messages and send transactions on Cookie Chain and Solana, without any library.

Morsel injects a provider into every page, both in Chrome with the Morsel extension and inside the Morsel app's browser on iPhone and Android. It follows the familiar Solana provider shape, so code written for other Solana wallets works with small changes.

Namespaces

ObjectWhat it is
window.morselThe Morsel provider. Prefer this. It works as the Solana provider and also exposes .solana and .cookie.
window.morsel.cookie, window.cookieThe Cookie Chain provider.
window.solanaThe Solana provider, only if no other wallet has claimed it.
window.phantom.solanaA compatibility alias, only if no other wallet has claimed it.

The Solana and Cookie Chain providers share one connection: connecting one connects the other.

For compatibility with dApps that only look for Phantom, the providers also set isPhantom: true. To detect Morsel specifically, check isMorsel.

Detect the provider

detect.js
function getMorsel() {
  if (window.morsel?.isMorsel) return window.morsel;
  if (window.solana?.isMorsel) return window.solana;
  return null;
}

function onMorselReady(callback) {
  const provider = getMorsel();
  if (provider) return callback(provider);
  window.addEventListener('morsel#initialized', () => callback(getMorsel()), { once: true });
}

Morsel dispatches morsel#initialized, solana#initialized and cookie#initialized on window once. In a framework, run detection in onMount or useEffect, not at module load.

Connect and disconnect

connect.js
const provider = window.morsel;

try {
  const { publicKey } = await provider.connect();
  console.log('Connected', publicKey.toBase58());
} catch (err) {
  if (err.code === 4001) console.log('The user said no');
}

await provider.disconnect();

Call connect() from a user action. To reconnect without a prompt, only for a site the user already approved:

JS
await provider.connect({ onlyIfTrusted: true });

If the site isn't trusted yet, this fails with 4100. The extension reconnects trusted sites by itself.

Sign a message

sign-message.js
const message = new TextEncoder().encode('Sign in to MyDapp');
const { signature, publicKey } = await provider.signMessage(message, 'utf8');

Morsel shows readable text to the user, or warns them when it isn't readable. Never ask users to sign a serialized transaction as a message: Morsel treats that as an attack and refuses.

Sign in with Solana

sign-in.js
const { address, signedMessage, signature } = await provider.signIn({
  domain: window.location.host,
  statement: 'Sign in to MyDapp',
});

Sign and send transactions

send.js
import { Connection, Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

const connection = new Connection('https://rpc.cookiescan.io'); // a Cookie Chain RPC
const tx = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: provider.publicKey,
    toPubkey: new PublicKey('RECIPIENT'),
    lamports: 1_000_000,
  })
);
tx.feePayer = provider.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;

const { signature } = await provider.cookie.signAndSendTransaction(tx);

Use window.morsel.cookie with a Cookie Chain connection, and window.morsel with a Solana connection. Legacy and version 0 transactions are supported.

Other methods: signTransaction(tx), signAllTransactions(txs) and signAndSendAllTransactions(txs).

State and events

events.js
provider.publicKey;   // PublicKey or null
provider.isConnected; // boolean

provider.on('connect', (publicKey) => {});
provider.on('disconnect', () => {});
provider.on('accountChanged', (publicKey) => {});

In the Morsel app, switching wallets reloads your page, so read publicKey again on load.

request()

Every method is also available through request:

JS
const { publicKey } = await provider.request({ method: 'connect', params: { onlyIfTrusted: false } });

Unknown methods fail with 4200.

Errors

CodeMeaning
4001The user rejected the request.
4100Not authorized. Connect first.
4200Method not supported.
4900Disconnected.
-32602Invalid parameters.
-32603Internal error. Also returned when Morsel blocks a request for safety.
-32000Transaction failed.
-32001Timed out.

In the Morsel app, a request the user doesn't answer within 3 minutes is rejected.

Try one of these