Skip to main content
@chipi-stack/core is in development (v0.1.0). APIs may change before stable release.

Overview

SignerAdapter is an interface that abstracts over different key management strategies. Instead of hardwiring passkey logic into transaction flows, you program against the SignerAdapter interface and swap implementations as needed.

The Interface

Implementations

DirectSigner

Signs with a local private key. For development and testing only.
Never use DirectSigner with real private keys in production. It exists for local development and testing.

Constructor

  • privateKey (string): Hex-encoded StarkNet private key (must start with 0x)
  • accountAddress (string, optional): Account address. Defaults to the derived public key.

Throws

  • If privateKey is not a valid hex string starting with 0x

PasskeySigner

Wraps a WebAuthn assertion function that produces Starknet-compatible signatures {r, s} from a challenge. Users authenticate via biometrics (Face ID, fingerprint) and the result is used to sign transactions.

Constructor

  • authenticateFn: A function that takes a challenge hash and returns a Starknet-compatible signature {r, s} via WebAuthn assertion
  • publicKey: The passkey public key obtained during registration
  • accountAddress: The user’s StarkNet account address
Most developers should use the usePasskeyAuth hook from @chipi-stack/chipi-passkey/hooks instead of PasskeySigner directly. PasskeySigner is for advanced use cases where you need low-level control over the signing flow.

ExternalSigner

Generic adapter for a signer that can sign a raw Starknet hash with one STARK key and return { r, s }: a key in a KMS or HSM, your own signing service, an MPC provider. You supply the three interface methods and ExternalSigner wraps them.
createAccount sends exactly [r, s] as the transaction signature, so the account must accept a plain two-felt signature from that key (an OpenZeppelin account, for example).
Browser wallets don’t fit ExternalSigner. Bramble, Ready and Braavos never sign a raw hash: their only signing method, wallet_signTypedData, signs SNIP-12 typed data, whose hash includes the signing account’s own address. The signature shape also depends on the account: [r, s] for Bramble’s OpenZeppelin account and Braavos, ["1", "0", publicKey, r, s] for Ready (Argent).To send from the user’s own wallet, wrap it in starknet.js’s WalletAccount and pass that to TxBuilder (example). To make Bramble a co-owner or guardian of a Chipi wallet, see Trusted wallets.
Signing typed data with Bramble through WalletAccount:

Constructor

Use Cases

Backend Automation

Use DirectSigner with a key stored in a vault/HSM for programmatic transaction execution:

Multi-Wallet Support

Support several key holders without branching transaction code:
Transaction code is the same regardless of signer: createAccount({ signer, provider }) gives TxBuilder an Account. A browser wallet (Bramble, Braavos, Ready) skips this step: its WalletAccount already is an Account.

Easy Testing

Mock signers for unit tests:

Auth Provider Migration

If you switch from Privy to another provider, only the SignerAdapter implementation changes. All TxBuilder, Erc20, and Amount code stays the same.

Connecting to TxBuilder

createAccount() bridges any SignerAdapter into a starknet.js Account for use with TxBuilder.

Direct (user pays gas)

  • TxBuilder: Uses the Account (which uses the signer) to execute transactions
  • Introduction: Overview of when to use core vs hooks