Bridgelet Core
Soroban smart contracts for ephemeral account restrictions
Status: Active Development
Bridgelet Core contains the Soroban smart contracts that enforce single-use restrictions on ephemeral Stellar accounts and manage the sweep logic for transferring funds to permanent wallets.
| Function | Contract | Stub Status | Production Requirement | Tracking Issue |
|---|---|---|---|---|
verify_sweep_authorization |
EphemeralAccount | Partial - Uses require_auth() instead of Ed25519 signature verification |
Implement env.crypto().ed25519_verify() against stored authorized_signer with signature covering destination + nonce + contract_id |
#86 |
| Token transfers | SweepController | Implemented - execute_transfers() calls token.transfer() for all assets |
Already implemented in transfers.rs |
N/A |
- EphemeralAccount::sweep(): Currently uses Soroban's
require_auth()for authorization instead of cryptographic Ed25519 signature verification. The signature parameters (destination,auth_signature) are accepted but not cryptographically verified. Production implementation should useenv.crypto().ed25519_verify()similar to SweepController's implementation. - SweepController::claim(): Experimental gas-free claim path. The recipient signs a Soroban auth entry for
claim(recipient, ephemeral_account), and a relayer/SDK can submit the transaction and pay fees. Internally the controller usesauthorize_as_current_contract()so the downstreamEphemeralAccount::sweep()call can satisfyauthorized_controller.require_auth(). - SweepController::execute_transfers(): Token transfer logic is fully implemented using SEP-41 token contracts. All recorded payments are transferred atomically to the destination.
- Security guidance: Always route sweeps through
SweepControllerfor proper Ed25519 signature verification. Do not callEphemeralAccount::sweep()directly until the signature verification stub is replaced.
- Language: Rust
- Framework: Soroban SDK 22.0.0
- Testing: soroban-cli + Rust test framework
- Build: Cargo + stellar-cli
Manages restrictions on temporary accounts:
- Single inbound payment enforcement
- Authorized sweep destination
- Time-based expiration logic
- Event emission for auditability
Handles fund transfers:
- Validates claim authorization
- Executes atomic sweeps
- Handles multi-asset transfers
- Reclaims base reserves
contracts/ ├── ephemeral_account/ │ ├── src/ │ │ ├── lib.rs # Main contract │ │ ├── storage.rs # State management │ │ ├── events.rs # Event definitions │ │ └── errors.rs # Error types │ └── Cargo.toml ├── sweep_controller/ │ ├── src/ │ │ ├── lib.rs │ │ ├── authorization.rs │ │ └── transfers.rs │ │ ├── storage.rs # State management │ │ └── errors.rs # Error types │ └── Cargo.toml └── shared/ └── types.rs # Shared types
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Soroban CLI
cargo install --locked soroban-cli --version 22.0.0
# Add wasm target
rustup target add wasm32-unknown-unknown
# Install Binaryen (for WASM optimization)
# Minimum required version: 100
# macOS:
brew install binaryen
# Ubuntu/Debian:
apt-get install binaryen
# Or download from: https://github.com/WebAssembly/binaryen/releases# Build contracts (with WASM optimization if binaryen is installed)
./scripts/build.sh
# The build script automatically optimizes WASM files using wasm-opt -O3
# if Binaryen is installed. This typically reduces binary size by 15-30%.
# If wasm-opt is not found, the build continues without optimization.
# Run tests
cargo test
# Deploy to testnet
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/ephemeral_account.wasm \
--network testnet \
--source SIGNER_SECRET_KEY# Unit tests
cargo test
# Integration tests
cargo test --test integration
# Deploy to local sandbox for testing
./scripts/test-local.sh- Test Workflow (
.github/workflows/test.yml): Runs on every push tomain/developand on PRs tomain- Runs cargo tests for all contracts
- Checks code formatting with
cargo fmt - Runs clippy for linting
- Builds all contracts for wasm32-unknown-unknown target
- Uploads WASM artifacts for deployment
- Deploy Workflow (
.github/workflows/deploy-testnet.yml): Automatically deploys to Stellar Testnet on merge tomain- Runs tests, format checks, clippy, and builds before deployment
- Deploys all three contracts:
ephemeral_account,sweep_controller,reserve_contract - Stores contract IDs as CI artifacts (90-day retention)
- Posts deployment summary with contract IDs to GitHub Actions summary
- Can also be triggered manually via
workflow_dispatch
To enable automated deployments, add the following secret to your GitHub repository:
TESTNET_DEPLOYER_SECRET_KEY: Stellar testnet deployer secret key (S... format)
To trigger a manual deployment:
- Go to Actions tab in GitHub
- Select "Deploy to Testnet" workflow
- Click "Run workflow"
- Optionally provide a reason for the deployment
pub trait EphemeralAccountInterface {
// Initialize ephemeral account with restrictions
fn initialize(
env: Env,
creator: Address,
expiry_ledger: u32,
recovery_address: Address,
) -> Result<(), Error>;
// Record inbound payment (called automatically)
fn record_payment(env: Env, amount: i128, asset: Address) -> Result<(), Error>;
// Execute sweep to permanent wallet
fn sweep(env: Env, destination: Address) -> Result<(), Error>;
// Check if account is expired
fn is_expired(env: Env) -> bool;
}See Bridgelet Documentation for full API reference.
Contracts emit events for off-chain monitoring:
AccountCreated { creator, expiry_ledger }
PaymentReceived { amount, asset }
SweepExecutedMulti { destination, payments }
AccountExpired { recovery_address, total_amount, reserve_amount }- All storage keys use proper namespacing
- Authorization checks on every state-changing operation
- Reentrancy protection via Soroban's execution model
- Timestamp-based expiration uses ledger time
See Security Audit Report (coming soon)
MIT