Dfns Integration Guide
Dfns is an MPC/TSS Wallet-as-a-Service API/SDK provider. Dfns aims to optimize the balance of security and UX by deploying key shares into a decentralized network on the backend while enabling wallet access via biometric open standards on the frontend like Webauthn. Reach out here to set up a sandbox environment to get started.
Dfns seamlessly integrates with Account Abstraction by signing UserOperation
s. See the examples below for initializing a DFNS signer and creating a provider with that signer. You can follow this guide to send and sponsor UserOperation
s with the provider created.
Dfns created a full example of a gas-less transaction via a paymaster in our SDK, adapted from our gas sponsorship example.
Install Dfns SDK
npm i @dfns/lib-viem @dfns/sdk @dfns/sdk-keysigner
yarn add @dfns/lib-viem @dfns/sdk @dfns/sdk-keysigner
Create a SmartAccountSigner
Setup the Dfns Web3 Provider and wrap it in an AlchemyProvider
.
import { LocalAccountSigner, type SmartAccountSigner } from "@alchemy/aa-core";
import { DfnsWallet } from "@dfns/lib-viem";
import { DfnsApiClient } from "@dfns/sdk";
import { AsymmetricKeySigner } from "@dfns/sdk-keysigner";
import { LocalAccount, toAccount } from "viem/accounts";
// See the Dfns example https://github.com/dfns/dfns-sdk-ts/tree/m/examples/libs/viem/alchemy-aa-gasless for details on populating the environment variables.
const DFNS_PRIVATE_KEY = null;
const DFNS_CRED_ID = null;
const DFNS_APP_ORIGIN = null;
const DFNS_APP_ID = null;
const DFNS_AUTH_TOKEN = null;
const DFNS_API_URL = null;
const SEPOLIA_WALLET_ID = null;
const initDfnsWallet = (walletId: string) => {
const signer = new AsymmetricKeySigner({
privateKey: DFNS_PRIVATE_KEY!,
credId: DFNS_CRED_ID!,
appOrigin: DFNS_APP_ORIGIN!,
});
const dfnsClient = new DfnsApiClient({
appId: DFNS_APP_ID!,
authToken: DFNS_AUTH_TOKEN!,
baseUrl: DFNS_API_URL!,
signer,
});
return DfnsWallet.init({
walletId,
dfnsClient,
maxRetries: 10,
});
};
export const createDfnsSigner = async (): Promise<SmartAccountSigner> => {
const sepoliaWallet = await initDfnsWallet(SEPOLIA_WALLET_ID!);
const account = toAccount(sepoliaWallet) as LocalAccount;
const dfnsSigner = new LocalAccountSigner(account as any);
return dfnsSigner;
};
Use it with Light Account
import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy";
import { sepolia } from "@alchemy/aa-core";
import { createDfnsSigner } from "./dfns";
// Remember to replace "ALCHEMY_API_KEY" with your own Alchemy API key, get one here: https://dashboard.alchemy.com/
const ALCHEMY_API_KEY = "API_KEY";
const chain = sepolia;
const createAlchemyProvider = async () => {
return createModularAccountAlchemyClient({
apiKey: ALCHEMY_API_KEY,
chain,
signer: await createDfnsSigner(),
});
};
import { LocalAccountSigner, type SmartAccountSigner } from "@alchemy/aa-core";
import { DfnsWallet } from "@dfns/lib-viem";
import { DfnsApiClient } from "@dfns/sdk";
import { AsymmetricKeySigner } from "@dfns/sdk-keysigner";
import { LocalAccount, toAccount } from "viem/accounts";
// See the Dfns example https://github.com/dfns/dfns-sdk-ts/tree/m/examples/libs/viem/alchemy-aa-gasless for details on populating the environment variables.
const DFNS_PRIVATE_KEY = null;
const DFNS_CRED_ID = null;
const DFNS_APP_ORIGIN = null;
const DFNS_APP_ID = null;
const DFNS_AUTH_TOKEN = null;
const DFNS_API_URL = null;
const SEPOLIA_WALLET_ID = null;
const initDfnsWallet = (walletId: string) => {
const signer = new AsymmetricKeySigner({
privateKey: DFNS_PRIVATE_KEY!,
credId: DFNS_CRED_ID!,
appOrigin: DFNS_APP_ORIGIN!,
});
const dfnsClient = new DfnsApiClient({
appId: DFNS_APP_ID!,
authToken: DFNS_AUTH_TOKEN!,
baseUrl: DFNS_API_URL!,
signer,
});
return DfnsWallet.init({
walletId,
dfnsClient,
maxRetries: 10,
});
};
export const createDfnsSigner = async (): Promise<SmartAccountSigner> => {
const sepoliaWallet = await initDfnsWallet(SEPOLIA_WALLET_ID!);
const account = toAccount(sepoliaWallet) as LocalAccount;
const dfnsSigner = new LocalAccountSigner(account as any);
return dfnsSigner;
};