Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt

Use this file to discover all available pages before exploring further.

Available without advertisement until external audit closes. The on-chain classes are live on Starknet mainnet and have been smoke-tested end-to-end (STARK, Ed25519, EIP-191, WebAuthn P-256, Apple JWT) — see scripts/receipts/.

What “signer kind” means

A SHHH V8.4 wallet stores owners, not a fixed key shape. Each owner has a kind_tag that the account uses to dispatch signature verification to the matching verifier class via Starknet’s library_call_syscall. That means one wallet can hold owners of different kinds simultaneously — the headline use case is a passkey on a phone plus a MetaMask on a laptop, both controlling the same wallet. The SDK’s walletType: "SHHH" plus a signerKind selects which verifier the primary owner uses at wallet creation. Additional owners (with the same or different kinds) can be added later via recovery’s propose_add_owner flow.

Available kinds

signerKindVerifierCycle 1 statusUse it for
STARKECDSA on STARK curveDefault — shipped + smokedServer-held key, programmatic wallets, fastest gas
ED25519Ed25519Shipped + smokedPhantom (Solana) users importing to Starknet
EIP191_SECP256K1secp256k1 + EIP-191 personal_signShipped + smokedMetaMask / any EVM-rooted wallet
WEBAUTHN_P256P-256 over WebAuthn assertionsShipped (browser)Platform passkeys — Touch ID / Face ID / Windows Hello / Android biometrics
JWT_ES256_APPLE_SUBES256 over Apple’s id_tokenShipped + smoked”Sign in with Apple” rooted Starknet wallet
JWT_ES256Generic ES256 over JWTWave CService-account auth (machine-to-machine)
SECP256K1Raw secp256k1 ECDSAWave CBitcoin / Cosmos / raw secp256k1 keys
EIP712_SECP256K1secp256k1 + EIP-712Wave CEIP-712-signed payloads from EVM wallets
P256Raw P-256 (no WebAuthn)Wave CHardware tokens / YubiKeys / SE-bound keys
BLS12_381BLS12-381Wave DCommittee multisig (Ethereum validator-style)

Picking a kind

Browser / Expo onboarding — use a passkey

WEBAUTHN_P256 is the default for new SHHH wallets in browser and Expo:
import { createShhhPasskey } from "@chipi-stack/chipi-passkey";

const { credentialId, publicKey } = await createShhhPasskey(userId, userName);
The P-256 private key stays inside the platform authenticator. Chipi never sees it; no PIN derivation; the user authenticates with biometrics on every signature. For wallets created this way, the SDK’s walletType: "SHHH" + signerKind: "WEBAUTHN_P256" is implied.

EVM user importing to Starknet — EIP191_SECP256K1

If the user already has MetaMask (or any wallet that implements personal_sign), use their existing key as the SHHH owner:
// 1. User signs the 32-byte BE messageHash via MetaMask's personal_sign
const signature = await provider.request({
  method: "personal_sign",
  params: [messageHashBe32Hex, ethAddress],
});

// 2. Wrap into the SHHH V2_SNIP12 envelope
import { buildEip191EnvelopeFromSignature } from "@chipi-stack/backend";
const envelope = buildEip191EnvelopeFromSignature({
  signatureHex: signature,
  pubkey: { ethAddress },
});
The user’s secp256k1 key never leaves their wallet; SHHH verifies the EIP-191 signature on-chain.

Solana user importing to Starknet — ED25519

Same pattern: the integrator’s Phantom adapter signs the 32-byte messageHash via the wallet’s signMessage API; the SDK wraps the raw signature into the SHHH envelope. Phantom does NOT expose the private key (and the SDK does not need it) — the adapter returns the signature directly.
// 1. User signs via Phantom (or any Ed25519-capable wallet adapter)
const { signature } = await phantomProvider.signMessage(
  bigintToBe32(oeHash), // 32-byte BE challenge
);

// 2. Wrap into the SHHH V2_SNIP12 envelope
import { buildEd25519EnvelopeFromSignature } from "@chipi-stack/backend";
const envelope = buildEd25519EnvelopeFromSignature({
  signature, // 64-byte Ed25519 signature from Phantom
  pubkey: phantomPubkey, // 32-byte Ed25519 pubkey registered at wallet creation
});
For server-held STARK-rooted Ed25519 wallets (test fixtures, programmatic agents), the lower-level buildEd25519Envelope({ privateKey, messageHash }) builder is also available — that path keeps the key inside the SDK. The Phantom flow above is the headline browser path.

Server / programmatic — STARK

For wallets you control server-side (gift-card recipients, AI agents, internal automations), STARK is the fastest path. The SDK holds the encrypted STARK key and decrypts it server-side with the org’s encryption key.
// Defaults to STARK when walletType: "SHHH" and signerKind is omitted (TS).
// Python: pass signer_kind=ShhhSignerKind.STARK explicitly.
const wallet = await sdk.createWallet({
  params: { encryptKey, externalUserId, chain: Chain.STARKNET },
  bearerToken,
});
PIN is weak — not recommended for production.A user-typed PIN is a short, low-entropy string. Anyone who shoulder-surfs the PIN, observes a phishing form, or compromises the browser at typing time can decrypt the wallet’s private key. PIN remains in the SDK only as a fallback recovery surface for users who lose access to their platform authenticator.Production embedded-wallet apps should default to a platform passkey (Touch ID, Face ID, Windows Hello, Android biometrics) via the @chipi-stack/chipi-passkey package. For SHHH V8.4 wallets, signerKind: "WEBAUTHN_P256" keeps the private key inside the platform authenticator — it never leaves the device, never reaches Chipi servers, and is never derived from a user-typed secret.Only prompt for a PIN as the encryption key when:
  • The user explicitly opted into a PIN-only flow (e.g. cold-storage / paper-backup recovery), or
  • The platform genuinely has no WebAuthn / biometric support available.
If you are migrating an existing PIN-based wallet to a passkey, look up useMigrateWalletToPasskey in your framework’s hook docs.

iOS-first consumer flows — JWT_ES256_APPLE_SUB

Bind a Starknet wallet to a specific sub claim from “Sign in with Apple”. Multi-tenant friendly: the verifier checks the claim AND the Apple team’s signing key. Use for LATAM iOS users who don’t have MetaMask but do have Apple IDs.

Gas overhead [#gas-overhead]

The paymaster reserves gas per signer kind. Heavier curves cost more L2 gas to verify on chain:
Kindl2_gas overheadComment
STARK2MCheapest — native curve
SECP256K15M
EIP191_SECP256K110Msecp256k1 + 32-byte BE re-encode
EIP712_SECP256K112Msecp256k1 + EIP-712 hashing
P25630M
ED2551933M
WEBAUTHN_P25635MP-256 + SHA-256 over clientDataJSON
JWT_ES25660MES256 + JWT header/payload parse
JWT_ES256_APPLE_SUB62MES256 + sub extraction
BLS12_38180MPairing-heavy
The paymaster reserves these per signature; you don’t budget them yourself. Cited for capacity planning.

Self-custodial implications by kind

KindWhere the key livesChipi’s view
STARK (server)Chipi-held, encrypted at rest with the org’s encryptKeyEncrypted-at-rest, decryptable server-side
STARK (client, PIN)Encrypted in localStorage / Secure Enclave with the user’s PINCiphertext only, but PIN is the key
STARK (client, passkey-PRF)Encrypted with a key the platform authenticator derives via WebAuthn PRFCiphertext only; PRF must be available for decrypt
ED25519 / EIP191_SECP256K1 / EIP712_SECP256K1External wallet (Phantom / MetaMask)Chipi never sees the key
WEBAUTHN_P256Inside platform authenticator (Secure Enclave / TPM)Chipi never sees the key; cannot be extracted
JWT_ES256_APPLE_SUBApple’s signing infrastructureChipi sees only the signed id_token; depends on Apple
WEBAUTHN_P256 and the external-wallet kinds give you the strongest “Chipi cannot move the user’s funds” story. STARK (server) is the weakest but most operationally convenient.
  • Recovery — guardian recovery + multi-device on top of any signer kind
  • Threshold — N-of-M with mixed kinds
  • Migration — moving a CHIPI v29 wallet to SHHH