Viem Support

Passport Protocol uses an EIP 1193 compatible interface for signing messages, transaction and typed data. With this we've created a wallet client, which acts as a JSON-RPC account which allows you to leverage all of Viem's features.

1. Install the packages

npm install viem @0xpass/passport-viem

2. Choose your auth method

Passkeys

npm install @0xpass/webauthn-signer

import { WebauthnSigner } from "@0xpass/webauthn-signer";

const signer = new WebauthnSigner({
      rpId: window.location.hostname,
      rpName: "rpName",
});

DOA

npm install @0xpass/key-signer

import { KeySigner } from "@0xpass/key-signer";

const signer = new KeySigner(process.env.PRIVATE_KEY!, true);

In order to generate private key for DOA signer, follow Generating DOA Keys

3. Create WalletClient

To create a wallet client, you'll need to have a registered and authenticated account, to setup a WalletClient with each signer you can follow the examples below.

Passkey Signer

import { http, mainnet, WalletClient } from "viem/chains";
import { createPassportClient } from "@0xpass/passport-viem";
import { Passport } from "@0xpass/passport";

const signer: new WebauthnSigner({
  rpId: "rpId",
  rpName: "rpName",
})

const passport = new Passport({
    scope_id: "insert_your_scope_id",
    signer: signer
});

const userInput {
   username: "insert_registered_username_here"
   userDisplayName: "insert_registered_user_display_name_here"
}

await passport.setupEncryption();
const [authenticatedHeader] = await passport.authenticate(userInput);

const chain = mainnet;
const transport = http("any eth node endpoint");

// Create viem WalletClient using Passport
const client: WalletClient = createPassportClient(
  authenticatedHeader,
  transport,
  chain
);

Developer Owned Auth Signer

import { Passport } from "@0xpass/passport";
import { KeySigner } from "@0xpass/key-signer";
import { createPassportClient } from "@0xpass/passport-viem";
import { walletClientToSmartAccountSigner } from "permissionless";
import { http } from "viem";
import { mainnet } from "viem/chains";

const signer = new KeySigner(process.env.PRIVATE_KEY!, true)

const passport = new Passport({
  scope_id: "scope_id",
  signer: signer
});

const fallbackProvider = http("insert_alchemy_url");

await passport.setupEncryption();
await passport.delegatedRegisterAccount({ username: "test" });

passport.setUserData({ username: "test" });

const chain = mainnet;
const transport = http("any eth node endpoint");

const client = await createPassportClient(
  await passport.getDelegatedAuthenticatedHeaders(),
  transport,
  chain
);

4. Use Viem as usual

Here's an example of the viem wallet client created by Passport sending a transaction.

const [account] = client.getAddresses();
const transaction = await client.prepareTransactionRequest({
  account: account,
  to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
  value: BigInt(1000000000000000),
  chain: mainnet,
});

client
  .signTransaction(transaction)
  .then((res) => alert(JSON.stringify(res)))
  .catch((err) => alert(JSON.stringify(err)));

Last updated