npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@crossmint/wallet-sdk

v0.0.9-alpha.1

Published

An SDK for Crossmint Smart Contract wallets on EVM.

Downloads

18

Readme

Crossmint SDK

Crossmint SDK is a library that provides a simple and convenient interface for interacting with various blockchain accounts. This library enables developers to create and manage abstract wallets, send transactions, sign messages, and interact with smart contracts.


📋 Table of Contents


📥 Installation

npm install --save @crossmint/wallet-sdk

🌐 Connect

To initialize the Crossmint API object and connect using a Signer object, you only need the following code:

Using Signer:

import { getOrCreateWalletSigner, APIClient } from "@crossmint/wallet-sdk";
import { Signer } from "ethers";

const apiClient: APIClient; // Provide your implementation of APIClient
const signer: Signer; // Get signer object from ethers.js
const userEmail: string; // Provide the user's email address
const jsonRpcProviderConnection: string; // RPC Provider URL or chainId

// Create an initialized instance of the AbstractWallet
const wallet = await getOrCreateWalletSigner(apiClient, signer, userEmail, jsonRpcProviderConnection);

Using Web3Auth:

import { getOrCreateWalletWeb3Auth, APIClient } from "@crossmint/wallet-sdk";
import { Signer } from "ethers";
import { Blockchain, NetworkType } from '@crossmint/wallet-sdk/lib/utils/blockchainUtils';

const apiClient: APIClient; // Provide your implementation of APIClient
const web3authOptions: {
  chain: Blockchain | number; //("ethereum" | "goerli" | "polygon" | "mumbai" | "optimism" | "optimism_goerli" | "arbitrum" | "arbitrum_goerli" | "base" | "base_goerli") or chainId
  network: NetworkType; // Network Type ("mainnet" | "testnet" | "cyan" | "development" | "aqua")
  rpcTargetUri: string; // RPC target URL. Example: "https://rpc-mumbai.maticvigil.com".
  clientId: string; // Web3Auth Client ID. You can get it from your W3A Project dashboard https://dashboard.web3auth.io/home/web3auth
  displayName: string; // Display Name for the chain
  blockExplorer: string; // Blockchain's explorer URL. (eg: https://etherscan.io)
  ticker: string; // Default currency ticker of the network (e.g: ETH)
  tickerName: string; // Name for currency ticker (e.g: Ethereum)
  loginProvider: LoginProviders; //("google" | "facebook" | "reddit" | "discord" | "twitch" | "apple" | "line" | "github" | "kakao" | "linkedin" | "twitter" | "weibo" | "wechat" | "email_passwordless" | "sms_passwordless" | "jwt")
  email?: string; // Email address for 'email_passwordless' login.
};

// Create an initialized instance of the AbstractWallet
const wallet = await getOrCreateWalletWeb3Auth(apiClient, web3authOptions);

To connect, you will need to implement an APIClient, which will interact with your backend server to call the necessary Crossmint APIs.


🔌 APIClient

In order for the SDK to work, we need to make a few API calls to Crossmint servers. API keys (x-project-id and x-client-secret) are highly sensitive and cannot be included in requests coming from a front-end client, otherwise are easily susceptible to sniffing. Because of this, these API calls need to be made from your own servers. You will need to provide an implementation of APIClient that uses your own authentication system to perform calls from the front-end SDK to your back-end, subsequently calling the Crossmint APIs.

An example APIClient may look like this:

import { StoreAbstractWalletInput, TransferInput } from "crossmint";
class MyAPIClient implements APIClient {
  private baseUri = "https://example.api.com/api";
  private jwtToken: string;

  constructor(jwtToken: string) {
    this.jwtToken = jwtToken;
  }

  async getSessionKey(address: string) {
    const url = `${this.baseUri}/v2-alpha1/wallets/sessionkey`;
    const options = {
      method: "POST",
      headers: {
        Authorization: `Bearer ${this.jwtToken}`,
      },
      body: JSON.stringify({ address }),
    };

    const res = await fetch(url, options);
    return res.json();
  }

  async storeAbstractWallet(input: StoreAbstractWalletInput) {
    const url = `${this.baseUri}/v2-alpha1/wallets`;
    const options = {
      method: "POST",
      headers: {
        Authorization: `Bearer ${this.jwtToken}`,
      },
      body: JSON.stringify(input),
    };

    const res = await fetch(url, options);
    return res.json();
  }

}

And on your backend, you'll pass on these calls to the Crossmint API and return the result. An example in next.js may look like:

// getSessionKey
export default apiHandler(async (req: NextApiRequest, res: NextApiResponse) => {
  const { address, chain } = req.body;

  const url = `https://example.api.com/api/v2-alpha1/wallets/sessionkey`;
  const options = {
    method: "POST",
    headers: {
      accept: "application/json",
      "content-type": "application/json",
      "x-project-id": process.env.CROSSMINT_PROJECT_ID,
      "x-client-secret": process.env.CROSSMINT_CLIENT_SECRET,
    },
    body: JSON.stringify({ address, chain }),
  };
  const response = await fetch(url, options);
  const data = await response.json();
  res.status(200).json(data);
});

⚙️ Functionalities

The wallet created with getOrCreateWallet is an instance of AbstractWallet.

You can do the following with the AbstractWallet:

  • Send transactions
  • Estimate gas
  • Connect to a provider
  • Get the wallet's address
  • Sign messages
  • Sign typed data
  • Approve plugins
  • Sign transactions
  • Execute batch transactions
  • Execute delegate calls
  • List all assets associated with the wallet
  • Transfer all assets associated with the wallet

For example:

const balance = await wallet.getBalance();
const signerAddress = wallet.address!;
const signedMsg = await wallet.signMessage(message);
const receipt = await wallet.sendTransaction(transaction);

In addition, AbstractWallet provides the following specific methods:

const isValid = await wallet.verifyMessage(message, signature);

This method allows you to verify the signer of a message. message is the original message that was signed, and signature is the signed message. The method returns a boolean indicating whether the signature is valid or not.


🔐 Authentication & Firebase

Firebase Authentication State Check

The checkAuthState function monitors changes in a user's Firebase authentication state. When the user is authenticated, the function fetches the user's JWT token. If the user is not authenticated, the function resolves with undefined.

For its implementation:

import { firebaseAuth, onAuthStateChanged } from "firebase/app"; // Ensure you have the right imports based on your Firebase setup.

export const checkAuthState = (): Promise<string | undefined> => {
  return new Promise((resolve, reject) => {
    const auth = firebaseAuth();
    onAuthStateChanged(auth, async user => {
      try {
        if (user) {
          const jwt = await user.getIdToken(true);
          resolve(jwt);
        } else {
          resolve(undefined);
        }
      } catch (error) {
        reject(error);
      }
    });
  });
};

🤝 Contributing

We welcome contributions from the community! To contribute, please fork this repository and submit a pull request.


📝 License

This project is licensed under the MIT License.