Skip to content

firnprotocol/snap

Repository files navigation

Firn Protocol's Snap

Firn's Snap allows websites to securely invoke Firn Protocol on behalf of users.

An end-to-end, open-source working example exhibiting the below methods is available, and hosted, at Tome; see also firnprotocol/tome for the source.

API

Connecting

Connect to the Firn Snap in the standard way; that is:

await provider.request({
  method: "wallet_requestSnaps",
  params: { "npm:@firnprotocol/snap": {} },
});

Initialize

The initialize method prompts the user to "log into" his Firn account, on behalf of his currently logged-in Ethereum account (in practice, this entails signing a special message). As a side effect, it caches the user's secret Firn key in secure, encrypted storage (visible only within the Firn snap, and not to the calling website). If this method is called more than once, then the additional calls will be no-ops.

This method must be called before either of the below methods are. In practice, you may want to call this method immediately after prompting the user to connect the Snap in the first place.

await window.ethereum.request({
  method: "wallet_invokeSnap",
  params: {
    snapId: "npm:@firnprotocol/snap",
    request: { method: "initialize" },
  },
});

This method will either return nothing (upon success) or will throw an error (upon a failure).

Request Balance

The requestBalance method prompts the user to disclose his Firn balance. The RPC method will either return the user's Firn balance—denominated in milliether (!)—as a plain JavaScript number, or will throw an error. Here's an example invocation:

const balance = await window.ethereum.request({
  // might throw; will be handled above
  method: "wallet_invokeSnap",
  params: {
    snapId: "npm:@firnprotocol/snap",
    request: { method: "requestBalance" },
  },
});
console.log(`User's Firn balance is ${(balance / 1000).toFixed(3)} ETH.`);

Transact

The transact method prompts the user to anonymously execute a prescribed transaction using his Firn account. It will either return the transactionHash of the resulting successful, mined transaction, or else will throw a descriptive error. Here's an example invocation:

import { encodeFunctionData } from "viem";

const TOME_ABI = [
  {
    inputs: [
      {
        internalType: "string",
        name: "message",
        type: "string",
      },
    ],
    name: "broadcast",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
];
const data = encodeFunctionData({
  abi: TOME_ABI,
  functionName: "broadcast",
  args: ["A test message."],
});
const transaction = {
  to: "0x0D9993a3e3A0e73633c153CCf49A0bD17159A60D", // Tome address on Base
  data, // a bytes-like hex string
  value: 0, // a plain `Number`, denominated in milli-ether
};
const transactionHash = await window.ethereum.request({
  method: "wallet_invokeSnap",
  params: {
    snapId: defaultSnapOrigin,
    request: { method: "transact", params: transaction },
  },
});
console.log(`Transaction successful! Its hash is ${transactionHash}.`);

Further details and usage examples can be found at Tome.

About

Firn's official MetaMask Snap.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published