zkfold-smart-wallet-api
v1.8.0
Published
Smart Wallet API - Browser and extension compatible
Downloads
421
Readme
zkFold Smart Wallet API
This SDK lets you integrate zkFold Smart Wallets into your Cardano wallet or dApp. Smart Wallets are backed by Google OAuth: funds are locked in a script that only unlocks when the user proves possession of a valid Google-issued JWT.
Installation
The package is available on npm:
https://www.npmjs.com/package/zkfold-smart-wallet-api
Install it with:
npm install zkfold-smart-wallet-apiDevelopment
To build the library from sources:
npm install
npm run buildQuick start
The flow below shows how to obtain Google OAuth credentials, initialise a wallet, and prepare the background proof required for first-time spending.
1. Initiate the Google OAuth flow
import { Backend, GoogleApi } from 'zkfold-smart-wallet-api';
// Optionally pass an API key as the second argument if your backend requires it
const backend = new Backend('https://wallet-api.zkfold.io', 'your-api-key');
const credentials = await backend.credentials();
const gapi = new GoogleApi(
credentials.client_id,
credentials.client_secret,
'https://your-app.com/oauth/callback'
);
const authUrl = gapi.getAuthUrl('random-state');
window.location.href = authUrl;2. Handle the OAuth callback and create a wallet
import { Prover, Wallet } from 'zkfold-smart-wallet-api';
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
if (!code) throw new Error('Missing OAuth code');
const jwt = await gapi.getJWT(code);
if (!jwt) throw new Error('JWT exchange failed');
const prover = new Prover('https://wallet-prover.zkfold.io');
const wallet = new Wallet(backend, prover, { jwt });If you need to persist the wallet between sessions, serialise the initialiser:
localStorage.setItem('wallet-init', JSON.stringify(wallet.toWalletInitialiser()));3. Kick off background proof generation
When a wallet is activated for the first time, it must submit a zero-knowledge proof before funds can be sent. Generating the proof can take a while, so start it as soon as the wallet is created:
// Fire-and-forget: the proof will be cached on the wallet instance
wallet.getProof();Wallet.sendTo will wait until the proof is ready, but precomputing it keeps the UI responsive.
4. Query wallet data
const email = wallet.getUserId();
const address = await wallet.getAddress();
const balance = await wallet.getBalance();
const utxos = await wallet.getUtxos();5. Send funds
import { AddressType, BigIntWrap, SmartTxRecipient } from 'zkfold-smart-wallet-api';
// Send to another smart wallet user
await wallet.sendTo(
new SmartTxRecipient(AddressType.Email, '[email protected]', {
lovelace: new BigIntWrap('2000000')
})
);
// Send to a regular Cardano address
await wallet.sendTo(
new SmartTxRecipient(AddressType.Bech32, 'addr_test1qr...', {
lovelace: new BigIntWrap('1500000')
})
);sendTo returns a { transaction_id, notifier_errors } object mirroring the backend response.
API reference
Wallet
constructor(backend, prover, { jwt, tokenSKey? })getUserId()– Gmail address extracted from the JWTgetAddress()– Smart wallet bech32 addressaddressForGmail(email)– Resolve another wallet’s addressgetBalance()– Aggregate assets across all UTxOsgetUtxos()– Fetch UTxOs from the backendgetUsedAddresses() / getUnusedAddresses() / getRewardAddresses()– CIP-30 compatible helpersgetChangeAddress()– Currently returns the main addressgetExtensions()– Returns enabled wallet extensions (empty array for now)getProof()– Start/await the activation proof generation (new)sendTo(recipient)– Build, sign, and submit a transaction. If the wallet isn’t activated yet it will include activation + payment in one transaction.toWalletInitialiser()– Serialise the wallet so it can be restored later.
Backend
High-level wrapper around the Smart Wallet backend API:
walletAddress(email)– Resolve an address without activating the walletgetSettings()– Fetch network and version infoactivateWallet(jwt, paymentKeyHash, proof)– Build an activation transactionactivateAndSendFunds(jwt, paymentKeyHash, proof, outs)– Combine activation and paymentsendFunds(email, outs, paymentKeyHash)– Spend from an already activated walletsubmitTx(transaction, emailRecipients?)– Submit a signed CBOR transactionaddVkeyAndSubmit(unsignedTx, vkeyWitness, emailRecipients?)– Backend signs and submits on your behalfaddressUtxo(address)– Pull UTxOs for any addresscredentials()– Retrieve Google OAuth client credentials (requires backend configuration)
All mutating endpoints accept an optional API key supplied via the constructor.
Prover
Used to fetch zero-knowledge proofs for Google JWT validation:
requestProof(proofInput)– Submit proof computation and get a request IDproofStatus(proofId)– Poll for proof completionprove(proofInput)– Convenience helper that internally polls until the proof is ready
GoogleApi
getAuthUrl(state)– Start the OAuth 2.0 authorization code flowgetJWT(code)– Exchange the authorization code for an ID token (JWT)
Serialization helpers
The JSON module exposes serialize/deserialize for lossless (de)serialisation of types that contain BigIntWrap instances. Types.ts exports all shared data structures such as BigIntWrap, SmartTxRecipient, ProofBytes, and response DTOs.
Notes
- For browser builds, ensure
@emurgo/cardano-serialization-lib-browseris available. - Proof generation relies on HTTPS access to Google’s JWKS (
https://www.googleapis.com/oauth2/v3/certs). - When precomputing proofs, run
wallet.getProof()once per fresh JWT; reusetoWalletInitialiser()afterwards to skip regeneration.
