Skip to main content
Backend SDKs are designed for server-side applications: API servers, background workers, scripts. They handle request signing automatically and provide typed access to the full Dfns API.
Backend SDKs require a private key for request signing. Never expose private keys to client-side code. For user-facing applications, use a frontend SDK with delegated signing.

Authentication tokens

All backend SDKs require an authToken. This can be:
  • A Service Account token — long-lived, for server-to-server automation
  • A Personal Access Token (PAT) — long-lived, tied to a specific user
  • A User login token — short-lived, issued after user authentication
See Required headers for details on obtaining tokens.

Request signing

All state-changing requests (POST, PUT, DELETE) must be cryptographically signed. The SDK handles this automatically when you configure a key signer. The signing flow works as follows:
  1. Your SDK sends the request payload to Dfns
  2. Dfns returns a User Action Challenge
  3. Your SDK signs the challenge with your private key
  4. The signed challenge is sent back to complete the request
For a detailed explanation, see Signing requests.

Key signer

Each backend SDK provides a key signer that takes your credential ID and PEM-encoded private key. All SDKs support the same key types:
AlgorithmDescription
Ed25519Edwards-curve Digital Signature Algorithm
ECDSAElliptic Curve DSA (P-256, secp256k1)
RSARSA PKCS#1 v1.5 with SHA-256
Your credential ID and private key come from creating a Service Account or Personal Access Token in the Dfns Dashboard under Settings > Service Accounts or Settings > Personal Access Tokens.
import { AsymmetricKeySigner } from '@dfns/sdk-keysigner'

const signer = new AsymmetricKeySigner({
  credId: 'cr-...',
  privateKey: process.env.DFNS_PRIVATE_KEY!,
})

Direct vs delegated signing

Backend SDKs support two client patterns:

Direct signing

Use the standard client when your backend has the private key and signs requests itself. This is the most common pattern for service accounts and automation. The SDK handles the full signing flow internally — you just call API methods and the signing happens transparently.
import { DfnsApiClient } from '@dfns/sdk'
import { AsymmetricKeySigner } from '@dfns/sdk-keysigner'

const signer = new AsymmetricKeySigner({
  credId: 'cr-...',
  privateKey: process.env.DFNS_PRIVATE_KEY!,
})

const dfns = new DfnsApiClient({
  baseUrl: 'https://api.dfns.io',
  orgId: 'or-...',
  authToken: '...',
  signer,
})

const wallet = await dfns.wallets.createWallet({
  body: { network: 'EthereumSepolia' },
})

Delegated signing

Use the delegated client when the private key is not on your backend — for example, when users sign with passkeys on their own device, or when the key lives in an external KMS. The delegated client splits every state-changing operation into two steps:
  1. Init — your backend sends the request and receives a challenge
  2. Complete — your backend sends the challenge (signed externally) to finish the request
import { DfnsDelegatedApiClient } from '@dfns/sdk'

const dfnsDelegated = new DfnsDelegatedApiClient({
  baseUrl: 'https://api.dfns.io',
  orgId: 'or-...',
  authToken: userAuthToken,
})

// Step 1: Get a challenge
const challenge = await dfnsDelegated.wallets.createWalletInit({
  body: { network: 'EthereumSepolia' },
})

// Step 2: Send challenge to user's frontend for signing
// ... user signs with passkey via frontend SDK ...

// Step 3: Complete with the signed challenge
const wallet = await dfnsDelegated.wallets.createWalletComplete(
  { body: { network: 'EthereumSepolia' } },
  signedChallenge,
)
The Go SDK does not have a delegated client yet. Use the TypeScript or Python SDK for delegated signing flows.
See Delegated wallets for a full implementation guide.
Last modified on March 13, 2026