Skip to main content
The Node.js SDK runs on your backend and calls the Digital Asset Accounts passkey API with your API key.

What you can do

The SDK wraps the passkey routes only. It doesn’t send the operation that SCA protects. Your backend sends that request itself, with the SCA headers. For a ceremony in a native application, send redirectUri instead of embedOrigin, and pass the frame token to the iOS, Android, or React Native SDK. redirectUri, username, and displayName need version 0.2.5 or later.

Install

The SDK needs Node.js 22 or later. The package is ECMAScript modules (ESM) only, so use import, not require.

Initialize

An EU-restricted API key requires mutual TLS. The default transport uses Node’s fetch, which can’t present a client certificate, so every call fails with a 403. Supply a transport that sends your certificate. This example uses undici:
Use the fetch that undici exports, not Node’s built-in fetch. The built-in fetch can reject an Agent from a different undici version.
The transport receives your API key in its headers. Don’t log them.

Methods

createDaaClient returns a DaaClient. Its passkeys property is a PasskeysApi, which has these methods:

daa.passkeys.createRegistration

Opens a passkey enrollment ceremony for an end customer. Calls POST /v1/accounts/passkeys/registrations.

Parameters

Returns

Don’t retry createRegistration with the same idempotency key after you send the frameToken to the page. The retry issues a new token and breaks the ceremony in progress. Retrying a call whose response you never received is safe.

daa.passkeys.complete

Completes enrollment with the result of a client SDK’s enroll. Calls POST /v1/accounts/passkeys.

Parameters

Returns


daa.passkeys.list

Lists an end customer’s passkeys. Calls GET /v1/accounts/passkeys.

Parameters

Returns

An array of passkeys. Revoked passkeys are included, with revokedDate set. Each passkey includes passkeyId, credentialId, algorithm, aaguid, attestationFormat, transports, backupEligible, backupState, signCount, rpId, paymentEligible, createDate, and updateDate.

daa.passkeys.status

Returns whether an end customer requires SCA, together with their passkeys. Calls the same route as list, GET /v1/accounts/passkeys.

Parameters

Returns


daa.passkeys.revoke

Revokes a passkey. The passkey isn’t deleted, and list still returns it. Calls DELETE /v1/accounts/passkeys/{passkeyId}.

Parameters

Returns

Nothing.

daa.passkeys.openChallenge

Opens an approval ceremony for one protected request. Calls POST /v1/accounts/passkeys/challenges.

Parameters

Returns

After the page returns the assertion, send the protected request with the same body plus two headers. The SDK exports their names as SCA_HEADERS:
A retry under a new idempotency key is a different intent and needs a new challenge. For the full enrollment and approval steps, see How-to: Implement SCA.

Errors

A non-2xx response throws DaaApiError. With the built-in transport, a network failure, such as a DNS error, a TLS error, or a timeout, throws DaaTransportError. The SDK passes errors from your own transport through unchanged, so throw DaaTransportError from it for those failures. After a transport error, the request might or might not have been applied.
DaaApiError has these fields: DAA_ERROR_CODES maps names to the numeric codes. Common codes:

Usage notes

  • Don’t log frameToken. It grants access to one pending ceremony.
  • Send only frameToken to the page. Keep the rest of each response on your server.
  • Circle decides whether SCA applies to an end customer. A request that Circle doesn’t gate succeeds without SCA headers.

Versions

The SDK follows semantic versioning. Before version 1.0.0, a minor version can include breaking changes, so pin an exact version. The source is at circlefin/daa-node-sdk, in packages/node, with a changelog for each release.