Skip to main content

Smart Wallets

Smart wallets are the foundation of the SatsTerminal Borrow SDK. They provide secure, deterministic EVM accounts derived from Bitcoin wallet signatures.

What is a Smart Wallet?

A smart wallet is an ERC-4337 smart contract account that:
  • Is derived deterministically from a Bitcoin signature
  • Supports gasless transactions via account abstraction
  • Enables session-based authorization for secure operations
  • Provides multi-chain support with the same derivation

How Derivation Works

  1. User signs a deterministic message with their Bitcoin wallet
  2. The signature is used to derive EVM private keys
  3. A smart account address is computed from these keys
  4. The same BTC wallet always produces the same smart account

Signing Message Format

Sign this message to access your SatsTerminal Borrow Account.

Loan Wallet #0

This signature will be used to derive your secure Smart Account keys.
The Loan Wallet # index allows multiple smart accounts per BTC wallet.

Multi-Index Architecture

Each user can have multiple smart wallets, indexed starting from 0:
IndexPurpose
0Base wallet (portfolio, withdrawals)
1+Loan wallets (one per loan)
// Base wallet (index 0) - created during setup()
await sdk.setup();

// Loan wallet (index 1) - created for first loan
await sdk.getLoan({ ... });

// Loan wallet (index 2) - created for second loan
await sdk.getLoan({ ... });

Why Multiple Wallets?

Using separate wallets per loan provides:
  1. Isolation - Each loan’s collateral is isolated
  2. Clarity - Clear separation of funds
  3. Security - Compromised loan doesn’t affect others
  4. Tracking - Easier transaction history per loan

Signature Caching

The SDK caches signatures to avoid repeated signing prompts:
// First call - prompts for signature
await sdk.setup(); // User signs message

// Subsequent calls - uses cached signature
await sdk.startNewLoan(); // No prompt if signature cached
Signatures are stored with namespaced keys:
@satsterminal/borrow/wallet_0_signature
@satsterminal/borrow/wallet_1_signature

Clearing Cached Signatures

// Clear all cached signatures
sdk.clearSession();

Smart Account Features

Gasless Transactions

Smart accounts enable gasless transactions via ERC-4337:
  • Users don’t need ETH for gas
  • Gas is paid by the protocol
  • Transactions are bundled efficiently

Session Keys

Instead of signing every transaction, users authorize a session:
const session = await sdk.setup();
console.log('Session valid until:', new Date(session.activeSession.validUntil * 1000));
Sessions allow the SDK to execute transactions without additional signatures.

Cross-Chain Support

The same Bitcoin signature derives different addresses per chain:
// Same BTC wallet, different chains
const sdkArb = new BorrowSDK({ chain: ChainType.ARBITRUM, ... });
const sdkBase = new BorrowSDK({ chain: ChainType.BASE, ... });

// Will derive different smart account addresses
await sdkArb.setup();
await sdkBase.setup();

Wallet States

Deployed vs Undeployed

Smart accounts can exist in two states:
StateDescription
UndeployedAddress computed but contract not deployed
DeployedContract deployed on-chain
const { userStatus } = await sdk.setup();
console.log('Is deployed:', userStatus.isDeployed);
Deployment happens automatically during the first transaction.

Restoring Wallets

If a user switches devices, wallets can be restored:
// New device - no cached signature
const sdk = new BorrowSDK(config);

// Setup will prompt for signature again
// Same signature = same smart account
await sdk.setup();
The deterministic derivation ensures the same BTC wallet always recovers the same smart accounts.

Security Considerations

Signature Security

  • Signatures are stored locally (browser localStorage or provided storage)
  • Never transmitted except for initial derivation
  • Can be cleared via clearSession()

Smart Account Security

  • Controlled only by the derived keys
  • Session keys have limited scope and expiry
  • Multi-sig upgrades possible (future)

Best Practices

  1. Clear sessions on logout - Call clearSession() when user disconnects
  2. Use secure storage - Provide encrypted storage in production
  3. Monitor session expiry - Refresh sessions before they expire
  4. Validate addresses - Always verify smart account addresses match expectations