Step-by-step guide to build, deploy, initialize, and verify the predinex Soroban smart contract on Stellar testnet, then wire it into the web app.
| Tool | Version | Install |
|---|---|---|
| Rust | ≥ 1.78 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
wasm32-unknown-unknown target |
— | rustup target add wasm32-unknown-unknown |
| Stellar CLI | ≥ 22.0 | cargo install --locked stellar-cli --features opt |
| Funded testnet account | — | See step 1 |
# Generate a new keypair
stellar keys generate deployer --network testnet
# Fund via Friendbot
stellar keys fund deployer --network testnet
# Verify balance
stellar account show --network testnet $(stellar keys address deployer)From the repo root:
cd contracts/predinex
cargo build --target wasm32-unknown-unknown --releaseThe optimised WASM is written to:
contracts/predinex/target/wasm32-unknown-unknown/release/predinex.wasm
Run tests before deploying:
cargo teststellar contract deploy \
--wasm contracts/predinex/target/wasm32-unknown-unknown/release/predinex.wasm \
--source deployer \
--network testnetSave the printed contract ID:
export CONTRACT_ID=CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXinitialize must be called exactly once. It binds the SAC token and sets the treasury recipient.
# Deploy a test token (or use an existing SAC address)
stellar contract deploy \
--wasm /path/to/soroban_token_contract.wasm \
--source deployer \
--network testnet
# → TOKEN_ID=CYYY...
export TOKEN_ID=CYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
stellar contract invoke \
--id $CONTRACT_ID \
--source deployer \
--network testnet \
-- initialize \
--token $TOKEN_ID \
--treasury_recipient $(stellar keys address deployer)Open https://stellar.expert/explorer/testnet and search for $CONTRACT_ID.
You should see:
- Contract type: Soroban
- Recent transaction: the
initializeinvocation - Storage entries for
Token,TreasuryRecipient,Treasury,ContractVersion
Verify via CLI:
# Check protocol fee (should return 200)
stellar contract invoke \
--id $CONTRACT_ID \
--source deployer \
--network testnet \
-- get_protocol_fee
# Check treasury recipient
stellar contract invoke \
--id $CONTRACT_ID \
--source deployer \
--network testnet \
-- get_treasury_recipientNEXT_PUBLIC_CONTRACT_ID=CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_TOKEN_ID=CYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
NEXT_PUBLIC_SOROBAN_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_NETWORK_PASSPHRASE=Test SDF Network ; September 2015For pubnet:
NEXT_PUBLIC_SOROBAN_RPC_URL=https://soroban-mainnet.stellar.org
NEXT_PUBLIC_NETWORK_PASSPHRASE=Public Global Stellar Network ; September 2015Start the dev server:
npm run dev
# or
pnpm dev- Full test suite passes:
cargo test - Contract audited by a third party
- Admin and treasury keys on hardware wallet or multisig
-
fee_bpsset to intended value (default 200 = 2 %) - Deployer keypair stored offline after initialization
- Contract ID recorded in
CHANGELOG.md
| Error | Cause | Fix |
|---|---|---|
AlreadyInitialized |
initialize called twice |
Contract is live; skip this step |
HostError: Error(Auth, InvalidAction) |
Missing require_auth |
Pass --source matching the caller argument |
insufficient balance |
Deployer not funded | Run stellar keys fund deployer --network testnet |
| WASM not found | Build not run | Run cargo build --target wasm32-unknown-unknown --release |
PoolNotExpired on claim_expired |
Pool expiry not yet passed | Advance ledger time or wait |