Embed & Integrate

The Silk SDK is designed for ease of use by both seasoned Web3 devs and those new to self-custody wallets and cryptography.

Install

npm i @silk-wallet/silk-wallet-sdk

Use

For New Devs

Just getting started with Web3 development?

You can easily embed Silk to your site following standard practices that minimizes bugs or performance issues.

Silk exposes an EIP-1193 compliant interface, so you can use it just as you would use MetaMask, one of the most common Web3 wallet services. The only difference is that Silk must be initialized.

The following code initializes Silk, presents the login modal to the user, and gets the user's wallet addresses.

import { initSilk } from "@silk-wallet/silk-wallet-sdk"

// Initialize Silk
const silk = initSilk()

// Open the Silk login modal. silk.login() will throw if the user does not log in
try {
  await silk.login()
} catch (error) {
  console.error(error)
}

// Optional: Get the user wallet addresses
const accounts = await silk.request({ method: "eth_requestAccounts" })

For Web3 Devs

Know how to use windows.ethereum and wagmi?

If you have a codebase that already uses window.ethereum or wagmi, you can still integrate Silk in a couple lines.

First, you need to initialize Silk and have the user login (as above). Then assign silk to window.ethereum.

If you are using wagmi, Silk will work with the injected connector. Just assign silk to window.ethereum, have the user log in, and then use the wagmi hooks as you would with any other wallet.

import { initSilk } from "@silk-wallet/silk-wallet-sdk"

// Initialize Silk
const silk = initSilk()
window.ethereum = silk

// wagmi InjectedConnector will now connect to the Silk provider.

// Remember to have the user log in. If the user does not log in,
// calls to window.ethereum.request() will error out.
// silk.login() will throw if the user does not log in.
try {
  await window.ethereum.login()
} catch (error) {
  console.log(error)
}

If you want to give the user other wallet options in the Silk signup screen, use the loginSelector method instead of the login method. See the Methods section for details.

Once users have logged in, you can use Silk as a Provider object with libraries such as viem, ethers, wagmi, or any other that supports EIP-1193 Providers. Simply pass the silkobject as the provider and you are good to go.

Examples

Silk Demo App

We created a demo app that showcases all of Silk's functionality, so you can easily see how these methods behave. Go to our demo-app repository to see and copy the source code or clone the repo to run the app locally.

Silk + Next.js + Viem

Check out the repo below for this template app using Silk and Viem:

Silk + Next.js + Wagmi

This app created by Axé DAO is an example of using Silk wrapped into a Wagmi Connector. The connector code below is going to be shipped with the Silk SDK in the future.

Example wagmi config with Silk Connector

const wagmiConfig: Config = createConfig({
  chains: [optimism, gnosis, sepolia, localhost],
  connectors: [silk({ config: { appName: "My App", darkMode: true } })],
  transports: {
    [optimism.id]: http(ENV.optimismProviderUrl),
    [gnosis.id]: http(ENV.gnosisProviderUrl),
    [sepolia.id]: http(ENV.sepoliaProviderUrl),
    [localhost.id]: http("http://127.0.0.1:8545"),
  },
  ssr: true,
});

This is the preferred setup, if you want to embed Silk into your app and simply rely on wagmi hooks for all blockchain interaction. Note, however, that the connector is a standard wagmi interface and does not expose the Silk instance and its added features like Request Email or Request SBT. To access these you can instantiate Silk anywhere in your app as a secondary instance using the initSilk function described above.

Example: ConnectButton with wagmi's useConnect hook

"use client";

import { useAccount, useConnect } from "wagmi";
import { sepolia } from "wagmi/chains";
import { UserRejectedRequestError } from "viem";
import silk from "@/utils/silk.connector";

export default function ConnectPanel() {
  const { connect, error, isError, connectors } = useConnect();
  const account = useAccount();

  const handleConnect = async () => {
    const silkConnector = connectors.find((connector) => connector.id === "silk");
    try {
      // There should already be a silk connector in the wagmi config which also
      // enables automatic reconnect on page refresh, but just in case, we can also create
      // the connector here.
      if (!silkConnector) {
        connect({
          chainId: sepolia.id,
          connector: silk({ config: { appName: "My App", darkMode: true } }),
        });
      } else {
        connect({ chainId: sepolia.id, connector: silkConnector });
      }
    } catch (error) {
      console.error("Error connecting to Silk:", error);
      if (error instanceof UserRejectedRequestError) console.log("User aborted the transaction");
    }
  };

  return (
    <div classname="flex flex-col gap-8 row-start-2 items-center sm:items-start">
      {!account.address ? (
        <button onclick="{handleConnect}">Connect</button>
      ) : (
        <div classname="flex items-center justify-center">Connected: {account.address}</div>
      )}
      {isError && error.message && <div classname="text-red-500">{error.message}</div>}
    </div>
  );
}

On this page