Accounts and signing
Personal accounts
Each user's account is a Soroban smart account built from Stellar's open-source Passkey Kit wallet, pinned by its code hash. The user's passkey, a secp256r1 key held on their device, is its signer.
| Step | What happens |
|---|---|
| Sign up | The user signs in with email or Google, then creates a passkey |
| Account created | BlockFinaX deploys the user's smart account with the passkey as its signer, and pays the deployment fee |
| Approving an action | The passkey signs a Soroban authorization entry for the exact call (WebAuthn, with the user's fingerprint or face) |
| Backup passkeys | Added as further signers with add_signer, each approved by an existing passkey on chain |
BlockFinaX never holds a key that controls a user's account. Losing every passkey means losing access, which is why backup passkeys exist.
Business accounts
A business account is a separate Soroban smart account running OpenZeppelin stellar-accounts 0.8.0. BlockFinaX deploys it when a member creates the business, with that member's passkey as its first admin, and pays the deployment fee. Each member's passkey sits on the account's context rules for their role (details).
| Step | What happens |
|---|---|
| Create | The account is deployed with rule 0 (Default): the creator's passkey and a threshold policy of 1 |
| Add a member | An admin approves add_signer (or, for the first operator, add_context_rule for each operator rule); BlockFinaX confirms the change by reading the account back |
| Remove a member | An admin approves remove_signer (or remove_context_rule for the last operator); the member loses app access when removal starts |
| Approving an action | The member's passkey signs the OpenZeppelin auth digest, which binds the account, the call and the context rule ids the member claims |
A member uses the same passkey for their personal wallet and a business account. The two sign different digests for different accounts, so an approval for one can never be used on the other.
The app acts for a business by sending X-BFX-Organisation: <id> on API requests. The API checks active membership on every request and swaps in the business account.
Sponsored transactions
Users never need XLM. The app sends the signed authorization to BlockFinaX, which checks it and passes it to OpenZeppelin Relayer Channels. Channels builds the transaction and pays the fee. If Channels can't complete it, a BlockFinaX fee account submits and pays instead.
| Relayer policy | Rule |
|---|---|
| One call | Exactly one contract call per transaction |
| Allowed targets | The currency pool, the rate pool, USDC transfers and approvals to Circle's TokenMessenger, Circle CCTP, and adding a signer to the user's own account |
| Own account | Calls that name an account must name the signed-in user's |
| Bound signature | The authorization must be for that exact call |
| Fallback fee cap | The BlockFinaX fee account spends at most 50 XLM per call; normal calls cost far less |
For a business account the relayer also applies the member's role. The account's context rules enforce the same on chain.
| Role | Relayed |
|---|---|
| Admin | Pool calls, USDC transfers, Circle CCTP, and changes to the business account's signers, rules and policies. Never upgrade or execute |
| Operator | Pool calls only |
| Viewer | Nothing |