Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Welcome to snaK

snaK is your gateway to Kadena blockchain through MetaMask. This documentation will help you:

  • Get started with snaK as a user
  • Integrate snaK into your dApp as a developer
  • Understand how snaK works under the hood

snaK brings Kadena's powerful multi-chain capabilities to MetaMask users, enabling seamless interaction with Kadena dApps while maintaining MetaMask's security and convenience.

Introduction

MetaMask is a popular Ethereum wallet and browser extension that developers can integrate into a variety of third-party applications. MetaMask Snaps is an open-source solution to enhance MetaMask’s functionalities beyond its native capabilities.

snaK enables users to interact directly with the Kadena blockchain without relying on traditional JSON-RPC endpoints, offering Kadena-native functionalities like sending $KDA, performing cross-chain transfers, and retrieving account information. Initially developed by the Kadena Community, it's now maintained by Mindsend Datatech.

What is a Snap?

MetaMask Snaps is an open-source framework allowing secure extensions to MetaMask, enhancing Web3 user experiences. It empowers the addition of new API methods, supports various blockchain protocols, and tweaks existing functionalities via the Snaps JSON-RPC API.

Snaps enable users to interact with new blockchains, protocols, and decentralized applications (dApps) beyond what is natively supported by MetaMask. The goal of the MetaMask Snaps system is to create a more open, customizable, and extensible wallet experience for users while fostering innovation and collaboration within the blockchain and decentralized application ecosystem.

📚 Learn more:

Getting Started with snaK

snaK is a MetaMask extension that brings Kadena-native capabilities—like account creation, transaction signing, and cross-chain transfers—directly into your MetaMask wallet.

This guide walks you through installing the snaK Snap and using it via dApps that support it.

Installation

Before you can use snaK, you must have MetaMask installed and configured in your browser.

  1. Visit the official MetaMask Snap Directory and locate snaK.
  2. Click Install to grant permissions and enable the Snap.
  3. The Snap will now be available inside your MetaMask under the “Snaps” section.

💡 When installed, the Snap runs isolated from other extensions, using MetaMask’s permissioned execution model for enhanced security.

Using snaK

Once installed, snaK can be accessed via supported decentralized applications (dApps). You don’t interact with it directly through MetaMask—it activates automatically when the connected site uses Snap methods.

The web interface for interacting with snaK is available at snak.mindsend.xyz.

Here’s what you can do with the Snap-enabled dApp:

  • Create a Kadena Account:
    Click “+ Add Account” to generate a new Kadena account managed by the Snap.

  • Send and Receive $KDA:
    Use the dApp’s interface to send and receive KDA tokens across any of Kadena’s 20 chains.

  • Sign Transactions Securely:
    When a dApp sends a transaction request, MetaMask will trigger a secure popup for approval.

  • Perform Cross-Chain Transfers:
    The Snap abstracts the complexity of transferring KDA between Kadena’s braided chains.

  • Buy $KDA:
    Integrated onramp support (e.g., Simplex) allows you to purchase KDA within the dApp.

  • Use Gas Stations:
    Fee abstraction via Kadena’s gas stations ensures transactions can be executed without the sender owning KDA initially.

  • Ledger Support:
    The Snap can store Ledger-based Kadena accounts (signing must be handled manually by the dApp).

  • View Balances & Activity:
    The dApp can show balances and recent transactions using Snap-stored accounts.

Learn More

Snap Architecture

What does snaK look like under the hood?

snaK Architecture Diagram


One of the primary benefits of developing and using a Snap like snaK in your application is that it inherits the security model of MetaMask. Each Snap runs in its own isolated execution environment, completely sandboxed from other Snaps and browser extensions.

In the case of snaK, this isolation is crucial because the Snap manages private keys for Kadena accounts derived from the user's MetaMask seed phrase or imported independently. The Snap exposes a minimal set of RPC APIs, such as:

  • create-account
  • show-account
  • transfer

These functions allow secure interaction with the Chainweb network while keeping private key material inaccessible to the application.


Secure Storage and Execution

Within snaK, key data such as:

  • Private Key
  • Public Key
  • Account ID
  • Chain ID

are stored in internal Snap state. Only the Snap has access to this information. The RPC API handler gates all external access and enforces capability-based restrictions.

The Snap is also responsible for managing the current account context, ensuring actions are executed against the correct wallet index and chain ID.


Why it Matters

This architecture ensures that:

  • No external dApp or Snap can access your private keys.
  • All transactions must be explicitly signed via the Snap interface.
  • The Snap can support multiple chain IDs in Kadena’s multi-chain architecture.
  • Users retain full control over account selection and transaction authorization.

By leveraging MetaMask's Snap framework, snaK ensures high-security interaction with the Kadena blockchain, giving developers and users a reliable tool for integrating Web3 functionality with native wallet capabilities.

Frequently Asked Questions (FAQ)

How do I install snaK?

For users:

You can install snaK through the MetaMask Snaps Directory. After installation, access it through: MetaMask → Settings → Snaps → snaK

For developers integrating snaK:

Ensure MetaMask is installed in your browser. snaK can be installed via a supported dApp or manually through the MetaMask Snaps Directory.

Note that Snaps have minimal UI. To unlock the full functionality, dApps must integrate directly with the Snap's RPC API. You can view our demo app for reference and SDK usage.


What are MetaMask Snaps?

MetaMask Snaps are secure, sandboxed extensions that add new features to MetaMask. Snaps can add support for new protocols (like Kadena), handle signing flows, show custom notifications, or introduce new account models.


Are Snaps safe to use?

Yes. Snaps are sandboxed and can only access what users explicitly approve. They cannot access your MetaMask private keys or seed phrase. Every Snap declares its required permissions during installation, and MetaMask handles consent.


Can I interact with snaK directly in MetaMask?

Not directly. snaK is designed to be accessed through a dApp using the exposed Snap RPC methods. These methods enable account creation, balance queries, and transaction signing.

We provide a reference frontend for users to handle basic wallet operations and an SDK and wallet adapter to help dApps integrate snaK.


Why is my snaK address different from my MetaMask address?

snaK generates a new Kadena key pair using entropy provided by MetaMask, not by accessing the seed phrase directly. This ensures your snaK account is securely tied to your MetaMask account, but operates independently from Ethereum addresses.

This snaK-generated account is stored securely in isolated state and used for signing Kadena transactions.


Can I import an existing Kadena account?

Not yet. For now, snaK only supports generating new Kadena accounts using MetaMask-provided entropy. Importing external private keys is not currently supported, but may be added in a future release.


What happens if I uninstall snaK?

If you uninstall snaK and later reinstall it while using the same MetaMask seed phrase, the same snaK account(s) will be restored automatically.

Your account derivation is based on MetaMask entropy, so snaK can recover accounts deterministically without storing them externally.


Can I export the private key of my snaK account?

Not yet. For security reasons, snaK does not currently support exporting private keys. This may be supported in the future with proper UI/UX and user confirmation flows via MetaMask.


Is snaK available on MetaMask Mobile?

Not yet. MetaMask Mobile does not currently support Snaps. snaK is available only in desktop browser extensions (Chrome, Firefox, Brave). MetaMask has announced upcoming support for Snaps on mobile.


Troubleshooting Common Issues

Prompt to install MetaMask even when it's already installed?
Check if you have other wallets (like Koala Wallet) interfering with window.ethereum.

Ledger connection issues?

  • Ensure you're using a supported browser (Chrome/Edge/Opera)
  • Make sure the Kadena app is open on your Ledger
  • Try a different USB cable or port
  • Check that HID permissions are granted in your browser

Where can I get support?

For general support and questions, please use these channels:

Our team monitors these channels and will respond to inquiries as quickly as possible.

Support

While we strive to make our documentation comprehensive, sometimes you may need additional help. Here are the official support channels:

Official Support Channels

  1. Support Portal
    For technical issues and bug reports:
    https://support.mindsend.xyz/

  2. Community Discord
    For general questions and community support:
    https://discord.gg/CZzZSKxzWP

Before Contacting Support

To help us serve you better, please:

  • Check the FAQs first - your question may already be answered
  • Have your MetaMask version and browser information ready
  • For technical issues, include steps to reproduce the problem

Issue Prioritization

We prioritize issues based on:

  • Security vulnerabilities (highest priority)
  • Functionality-breaking bugs
  • Feature requests
  • General questions

We respond to support requests as quickly as we can.

snaK User Guide

This guide walks you through the steps to connect your MetaMask wallet to the Kadena Snap, install it, approve permissions, and perform basic operations like switching networks and sending $KDA.

💻 Note: The Kadena Snap is only available in the MetaMask browser extension. Users must switch to desktop to interact with the Kadena Snap.

What is snaK?

Kadena Snap is a custom MetaMask Snap that allows users to interact directly with the Kadena blockchain. It enables you to:

  • Manage Kadena accounts securely inside MetaMask
  • Perform cross-chain transfers across Kadena's 20 chains
  • Sign and send transactions using $KDA
  • View account balances and activity
  • Use gas stations to simplify fees
  • Buy KDA through integrated fiat onramps

The Kadena Snap is fully isolated, permissions-based, and built using MetaMask’s secure extensibility model.

Who is this guide for?

This guide is intended for:

  • Users who want to manage $KDA from within MetaMask
  • Developers building dApps that integrate with the Kadena Snap
  • Testers exploring the Kadena Snap functionalities on testnet

No prior knowledge of Kadena or Snaps is required, though basic familiarity with MetaMask is helpful.

What you'll need

Before getting started, make sure you have:

  • ✅ MetaMask installed in your browser
  • ✅ Access to a Snap-compatible dApp (or localhost test setup)
  • ✅ Some $KDA (use the faucet if testing)
  • ✅ Basic understanding of MetaMask permissions

💡 You can install the Kadena Snap even without a dApp using the MetaMask Snap Directory.

What this guide covers

This guide includes:

  • Connecting your MetaMask wallet
  • Installing and approving the Kadena Snap
  • Using the Kadena Snap to send transactions
  • Switching to the testnet (optional)
  • Funding accounts via faucet
  • Using advanced Snap features like cross-chain transfers

You’re now ready to explore the Kadena Snap and unlock full-chain functionality from right inside MetaMask.

Troubleshooting

Common Issues

  • Accounts not appearing?
    ✅ Ensure MetaMask is fully unlocked
    ✅ Check that the Kadena Snap is properly installed
    ✅ Refresh the dApp page

  • Transactions failing?
    🔹 Verify you have enough KDA for gas
    🔹 Confirm the correct chain is selected
    🔹 Verify you are connected to the correct network
    🔹 Check network status at status.kadena.io

  • Connection problems?
    🔄 Try reconnecting your wallet
    🔄 Reinstall the Kadena Snap if needed (accounts will recover)

Security Guidelines

⚠️ Important Security Notes

  • Your KDA accounts are generated from your MetaMask seed phrase

  • The same security practices for ETH apply to your KDA:

    • Never share your recovery phrase
    • Use a hardware wallet for maximum security
    • Be cautious of phishing sites
  • Always verify:

    • Transaction details in MetaMask popups
    • Website URLs before connecting
    • Contract addresses when interacting with dApps

🔒 Best Practices

  • Regularly review connected sites in MetaMask
  • Keep your browser and MetaMask updated
  • Consider using a dedicated browser and/or wallet for Kadena Snap

snaK Video Tutorials

Welcome to the snaK tutorial series! Below you will find step-by-step video guides to help you get started with snaK, the Kadena Wallet Snap for MetaMask.


1. Installing snaK – Kadena Wallet Snap for MetaMask

Learn how to install snaK and start managing your Kadena accounts seamlessly within your MetaMask browser extension.


2. Creating a snaK Account Using Seed Phrase

Discover how to create a new Kadena account in snaK using your seed phrase to recover or create your wallet securely.


3. Creating Ledger Accounts with snaK

Learn how to create and manage Ledger hardware wallet accounts with snaK, combining hardware security with Kadena blockchain convenience.

Connect to snaK

When visiting a dApp that uses snaK, you’ll be prompted to connect your MetaMask wallet.

Connect to snaK via MetaMask

Your Kadena account will be derived from your MetaMask Secret Recovery Phrase.

🔐 Security Implications

  • One seed phrase controls both ETH and KDA assets
  • Compromising the seed compromises both chains
  • Store it as securely as you would for crypto assets

💡 Protection Tips

  • Use a hardware wallet for your MetaMask seed
  • Never enter your phrase on any website
  • Bookmark official dApps to avoid phishing
  • Enable MetaMask's phishing detection

Approve the snaK Connection Request

MetaMask will display a connection request, asking you to approve the origin (e.g., snak.mindsend.xyz wants to use @mindsend/kadena-snap).

Connection Request

Click "Connect" to proceed.

Approve Permissions to Add Kadena Snap

You’ll now be asked to install Kadena Snap, which includes requesting permissions:

  • Manage Kadena accounts
  • Display dialog windows in MetaMask
  • Display a custom screen

Add to MetaMask

Click "Confirm" to continue.

Confirm Final Snap Permissions

MetaMask may show a final prompt to "Proceed with caution", requesting permission to manage your Kadena accounts.

Proceed with Caution

Check the box to Install the Kadena Snap and click Confirm to proceed.

Kadena Installed Successfully

Once installed, MetaMask will display confirmation that Kadena is ready to use.

Installation Complete

Click OK to return to the dApp.

Create and Fund Your Account

To perform any transaction, your new account needs $KDA tokens.

  • For testnet usage, get free testnet $KDA using the official faucet: 🔗 Kadena Testnet Faucet

  • For mainnet, there are multiple ways to acquire $KDA, including:

    • Centralized exchanges (CEX)
    • Decentralized exchanges (DEX)
    • Payment providers such as Simplex

Once funded, you’ll see a screen like this while a transaction is being processed:

Transaction Processing

Using Ledger with the Kadena Snap

This guide walks you through how to connect and use your Ledger Hardware Wallet with snaK.

✅ Tested with Ledger Nano S
🔒 Requires HID permission to be granted to your browser

🛠️ The app provides similar functionality to the official Kadena Transfer tool, but integrated directly into your wallet flow — no extra tabs or context switching required.


Browser Compatibility

navigator.hid is required for Ledger support. Only available in HTTPS secure contexts and supported by Chromium-based desktop browsers.

BrowserSupport
Desktop Browsers
Chrome✅ 89+
Edge✅ 89+
Firefox❌ No
Opera✅ 75+
Safari❌ No
Mobile Browsers
Chrome Android❌ No
Firefox Android❌ No
Opera Android❌ No
Safari iOS❌ No
Samsung Internet❌ No
WebView Android❌ No
Other Platforms
Deno❓ ?
Node.js❌ No

1. Install Kadena App on Ledger

  1. Open Ledger Live.
  2. Go to My Ledger.
  3. Search for Kadena and install the app.

Ledger Live with Kadena installed


2. Open Kadena App on Ledger

Ledger Live with Kadena installed

After installation:

  • Unlock your Ledger.
  • Navigate to and open the Kadena app on the device.
  • You should see the message: Kadena is ready.

Ledger Live with Kadena installed

📌 If you haven't opened the app, snaK will prompt you to open it on your Ledger.


3. Add a Ledger Account in snaK

  1. In snaK, click Add + in the sidebar.
  2. Select Ledger account.

Add Ledger Account


4. Grant HID Permission

If it's your first time connecting a Ledger:

  1. You’ll see a browser prompt asking for permission to connect to a HID device.
  2. Select your Ledger device and click Connect.

Connect to HID Device


5. You're Done

Your Ledger account is now added and ready to use! 🎉
You can now sign and send transactions from this account as described in other guides (e.g., Send KDA).


Official Ledger Guide

For a detailed step-by-step guide from Ledger (including how to use Kadena Transfer), check out:

📄 Ledger’s official Kadena guide

This includes installation instructions and general advice for managing KDA safely.


Ledger-Specific Troubleshooting

Connection Issues

  • If your Ledger isn't detected:
    • Ensure the Kadena app is open on your device
    • Try reconnecting the USB cable
    • Restart your browser
    • Check browser HID permissions (chrome://settings/content/hid)

Transaction Errors

  • "Device disconnected" during signing:
    • Keep the Kadena app open throughout the process
    • Avoid screen timeout on your Ledger
    • Check for firmware updates in Ledger Live

Browser Compatibility

  • If HID permissions aren't available:
    • Switch to Chrome/Edge/Opera (desktop versions only)
    • Ensure you're on HTTPS
    • Disable any wallet-extensions that might interfere

Additional Resources


Switching Networks (Optional)

To switch between Kadena Mainnet and Kadena Testnet, select the desired network from the dropdown on the snaK UI.

Switching networks in snaK

When switching between networks, you'll be prompted to approve the network switch.

Sending KDA

After funding your account, you can send $KDA to other accounts or perform native cross-chain transfers using the snaK interface.

Send KDA

  • From Account: Your Kadena address
  • To account: Recipient address
  • To chain: Select destination chain (e.g., Chain 1–20)
  • Amount: Amount of $KDA
  • Gas Fee: Usually prefilled

Click Send to broadcast your transaction.

Signing Transactions

To complete a transaction, you must review and approve the signature request with the Kadena Snap in the MetaMask popup.

Sign Transaction via MetaMask

After you have reviewed the transaction signature request, select Approve.

If the transaction is approved and successful, you will see this transaction in your Transaction Log.

Transaction List

This displays both the -5 KDA that was sent and the gas fee paid. You can view the transaction on the block explorer by clicking directly on a transaction. A popup will also show on the snaK interface with more details about your transaction.

Transaction Sent

Select Close to return to the snaK UI

Add a Custom Network on snaK

⚠️ To add networks, Dev Mode must be enabled. Without it, the "Add Network" button is hidden.


1. Enable Developer Mode

  1. Open snaK.
  2. Toggle Dev Mode ON (top-right of the app).

Dev Mode Toggle


2. Add Custom Network

  1. Open the network dropdown.
  2. Click Add Network.
  3. Fill in the fields:

Add Network Add Network

FieldExample
NameMindsend Mainnet
Network IDmainnet01
Node URLhttps://chainweb.mindsend.xyz/chainweb/0.0
Explorer Transaction URLhttps://explorer.chainweb.com/mainnet/tx/[[txHash]]
Explorer Address URLhttps://explorer.chainweb.com/mainnet/account/[[address]]
Explorer Address Transactionshttps://explorer.chainweb.com/mainnet/transfer/[[address]]
Is Testnet?Enable if it's a testnet
Transaction List URLhttps://graph.kadena.network/graphql
Transaction List TTL30000
Buy Page URL(Optional)
  1. Click Send.
  2. Approve the request in the popup.

Approve Network


✅ Your network is now available in the dropdown.

Network Available

You can now switch to it as in the Switching Networks section.

Switch Custom Network

and Voilá

Custom Network Connected

Dev Quickstart

Kadena Snap RPC Calls Documentation

This documentation covers the RPC methods provided by the Kadena Snap, allowing interaction with the Kadena blockchain via MetaMask. The Kadena Snap provides methods for checking connection status, managing accounts, interacting with networks, and signing transactions.

Table of Contents

  1. Available RPC Methods

Type Definitions

Below are the type definitions used in the Kadena Snap RPC calls. These types help ensure type safety and clarity when working with the RPC methods.

type CheckConnectionResponse = boolean;

type SnapAccount = {
  id: string;
  address: string;
  publicKey: string;
  index: number;
  name: string;
};

type CreateAccountResponse = SnapAccount;

type GetAccountsResponse = SnapAccount[];

type DeleteAccountParams = {
  id: string;
};

type DeleteHardwareAccountParams = {
  id: string;
};

type SnapNetwork = {
  name: string;
  networkId: string;
  blockExplorerTransaction: string;
  blockExplorerAddress: string;
  blockExplorerAddressTransactions: string;
  isTestnet: boolean;
  nodeUrl: string;
  transactionListUrl: string;
  transactionListTtl: number;
  buyPageUrl: string;
};

type GetNetworksResponse = SnapNetwork[];

type StoreNetworkParams = {
  network: SnapNetwork;
};

type DeleteNetworkParams = {
  networkId: string;
};

type GetActiveNetworkResponse = string;

type SetActiveNetworkParams = {
  networkId: string;
};

type SetAccountNameParams = {
  id: string;
  name: string;
};

type SetHardwareAccountNameParams = {
  id: string;
  name: string;
};

type SignTransactionParams = {
  id: string;
  transaction: string;
};

type SignTransactionResponse = string;

Available RPC Methods

kda_checkConnection

Description: Checks if the Kadena Snap is connected.

Request Example:

const isConnected = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_checkConnection' },
  },
});

Response: CheckConnectionResponse


kda_addAccount

Description: Derives a new account from the Kadena Snap.

Request Example:

const account = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_addAccount' },
  },
});

Response: SnapAccount


kda_addHardwareAccount

Description: Adds a new hardware account from the Kadena Ledger App.

Request Example:

const account = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_addHardwareAccount',
      params: {
        index: 0,
        address: '<address>',
        publicKey: '<publicKey>',
      },
    },
  },
});

Response: SnapAccount


kda_deleteAccount

Description: Deletes an account by its ID on Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_deleteAccount',
      params: { id: '<id>' },
    },
  },
});

Response: None


kda_deleteHardwareAccount

Description: Deletes a hardware account by its ID on Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_deleteHardwareAccount',
      params: { id: '<id>' },
    },
  },
});

Response: None


kda_getAccounts

Description: Retrieves all accounts from the Kadena Snap.

Request Example:

const accounts = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_getAccounts' },
  },
});

Response: SnapAccount[]


kda_getHardwareAccounts

Description: Retrieves all hardware accounts from the Kadena Snap.

Request Example:

const hardwareAccounts = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_getHardwareAccounts' },
  },
});

Response: SnapAccount[]


kda_getNetworks

Description: Retrieves all networks from the Kadena Snap.

Request Example:

const networks = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_getNetworks' },
  },
});

Response: SnapNetwork[]


kda_storeNetwork

Description: Adds a network to the Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_storeNetwork',
      params: {
        network: {
          name: 'New Network',
          chainId: 1,
          networkId: 'new-network-id',
          nodeUrl: 'https://new-network-node.url',
          blockExplorerTransaction: 'https://explorer.url/tx/{txId}',
          blockExplorerAddress: 'https://explorer.url/address/{address}',
          isTestnet: true,
        },
      },
    },
  },
});

Response: SnapNetwork


kda_deleteNetwork

Description: Deletes a network from the Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_deleteNetwork',
      params: { networkId: '<networkId>' },
    },
  },
});

Response: None


kda_getActiveNetwork

Description: Retrieves the active network from the Kadena Snap.

Request Example:

const activeNetwork = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: { method: 'kda_getActiveNetwork' },
  },
});

Response: GetActiveNetworkResponse


kda_setActiveNetwork

Description: Sets the active network in the Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_setActiveNetwork',
      params: { networkId: '<networkId>' },
    },
  },
});

Response: None


kda_setAccountName

Description: Updates the name of an account in the Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_setAccountName',
      params: {
        id: '<id>',
        name: 'New Account Name',
      },
    },
  },
});

Response: None


kda_setHardwareAccountName

Description: Updates the name of a hardware account in the Kadena Snap.

Request Example:

await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_setHardwareAccountName',
      params: {
        id: '<id>',
        name: 'New Hardware Account Name',
      },
    },
  },
});

Response: None


kda_signTransaction

Description: Signs a transaction using the Kadena Snap.

Request Example:

const signature = await window.ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: defaultSnapOrigin,
    request: {
      method: 'kda_signTransaction',
      params: {
        id: '<id>',
        transaction: '<Transaction Payload>',
      },
    },
  },
});

Response: SignTransactionResponse


Example: useKadenaSnap Hook

To leverage these RPC methods in a React application, you can implement a custom hook, such as useKadenaSnap. This hook provides an interface for using the RPC methods within the React component lifecycle.

import { useState } from 'react';
import { SnapAccount, SnapNetwork } from '../types';
import { defaultSnapOrigin } from '../config/snap';

export default function useKadenaSnap() {
  const [connected, setConnected] = useState<boolean>(false);

  const checkConnection = async (): Promise<boolean> => {
    try {
      const isConnected = await window.ethereum.request<boolean>({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: { method: 'kda_checkConnection' },
        },
      });
      setConnected(isConnected !== undefined && isConnected !== null);
      return isConnected ?? false;
    } catch (error) {
      console.error('Error checking connection:', error);
      return false;
    }
  };

  const addAccount = async (): Promise<SnapAccount> => {
    try {
      const response = await window.ethereum.request<SnapAccount>({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: { method: 'kda_addAccount' },
        },
      });

      if (
        !response ||
        !response.address ||
        !response.publicKey ||
        typeof response.index !== 'number' ||
        !response.name
      ) {
        throw new Error('Account creation failed: Missing essential data');
      }

      return response as SnapAccount;
    } catch (error) {
      console.error('Error creating account:', error);
      throw error;
    }
  };

  const getAccounts = async (): Promise<SnapAccount[]> => {
    try {
      const accounts = await window.ethereum.request<
        (SnapAccount | undefined)[]
      >({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: { method: 'kda_getAccounts' },
        },
      });

      if (!accounts) {
        throw new Error('No accounts returned from Kadena snap');
      }

      return accounts.filter(
        (account): account is SnapAccount => account !== undefined,
      );
    } catch (error) {
      console.error('Error getting accounts:', error);
      return [];
    }
  };

  const getNetworks = async (): Promise<SnapNetwork[]> => {
    try {
      const networks = await window.ethereum.request<
        (SnapNetwork | undefined)[]
      >({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: { method: 'kda_getNetworks' },
        },
      });

      return (networks ?? []).filter(
        (network): network is SnapNetwork => !!network,
      );
    } catch (error) {
      console.error('Error getting networks:', error);
      return [];
    }
  };

  const addNetwork = async (
    network: Partial<SnapNetwork>,
  ): Promise<Partial<SnapNetwork>> => {
    try {
      const newNetwork = await window.ethereum.request<SnapNetwork>({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: {
            method: 'kda_storeNetwork',
            params: {
              network: {
                name: network.name!,
                chainId: network.chainId!,
                networkId: network.networkId!,
                nodeUrl: network.nodeUrl!,
                blockExplorerTransaction: network.blockExplorerTransaction!,
                blockExplorerAddress: network.blockExplorerAddress!,
                blockExplorerAddressTransactions:
                  network.blockExplorerAddressTransactions!,
                isTestnet: network.isTestnet!,
                transactionListUrl: network.transactionListUrl!,
                transactionListTtl: network.transactionListTtl!,
                buyPageUrl: network.buyPageUrl!,
              },
            },
          },
        },
      });

      if (!newNetwork) {
        throw new Error('Failed to add network: No network returned');
      }

      return newNetwork;
    } catch (error) {
      console.error('Error adding network:', error);
      throw error;
    }
  };

  const deleteNetwork = async (networkId: string): Promise<void> => {
    try {
      await window.ethereum.request<void>({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: {
            method: 'kda_deleteNetwork',
            params: { networkId },
          },
        },
      });
    } catch (error) {
      console.error('Error deleting network:', error);
      throw error;
    }
  };

  const signMessage = async (
    id: string,
    transaction: string,
  ): Promise<string> => {
    try {
      const signature = await window.ethereum.request<string | undefined>({
        method: 'wallet_invokeSnap',
        params: {
          snapId: defaultSnapOrigin,
          request: {
            method: 'kda_signTransaction',
            params: { id, transaction },
          },
        },
      });
      if (!signature) {
        throw new Error('Signing failed');
      }
      return signature.toString().replace('0x', '');
    } catch (error) {
      console.error('Error signing transaction:', error);
      throw error;
    }
  };

  return {
    connected,
    checkConnection,
    addAccount,
    getAccounts,
    getNetworks,
    addNetwork,
    deleteNetwork,
    signMessage,
  };
}