Skip to content

Commit 38910a3

Browse files
Merge pull request #214 from DavisVT/docs/deploy-playbook
docs(credit): deployment and invocation playbook
2 parents 17b2dd7 + a4ec5e1 commit 38910a3

File tree

2 files changed

+354
-1
lines changed

2 files changed

+354
-1
lines changed

contracts/credit/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
mod auth;
1414
mod config;
1515
mod events;
16+
mod lifecycle;
17+
mod query;
18+
mod risk;
19+
mod storage;
1620
pub mod types;
1721
mod auth;
1822
mod storage;

docs/credit.md

Lines changed: 350 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,356 @@ stellar keys address admin
515515

516516
For the backend/risk-engine identity used to open credit lines:
517517

518-
(Examples unchanged — still valid)
518+
This section provides step-by-step instructions to deploy the contract on Stellar testnet,
519+
initialize it, configure liquidity, and invoke core methods.
520+
521+
### Prerequisites
522+
523+
- **Rust 1.75+** with `wasm32-unknown-unknown` target installed
524+
- **Stellar Soroban CLI** v21.0.0+: [install guide](https://developers.stellar.org/docs/tools-and-sdks/cli/install-soroban-cli)
525+
- **soroban-cli configured network**: add testnet or futurenet if not present
526+
- **Account on testnet**: funded with XLM for gas and operations
527+
528+
### Step 1: Network and Identity Setup
529+
530+
#### Configure Stellar Testnet
531+
532+
```bash
533+
soroban network add --name testnet --rpc-url https://soroban-testnet.stellar.org:443 --network-passphrase "Test SDF Network ; September 2015"
534+
```
535+
536+
#### Create or Import an Identity
537+
538+
```bash
539+
# Generate a new identity (stores keypair in ~/.config/soroban/keys/)
540+
soroban keys generate admin --network testnet
541+
542+
# Or import an existing keypair
543+
soroban keys generate admin --secret-key --network testnet
544+
# Then paste your secret key (starts with S...)
545+
```
546+
547+
Verify the identity was created:
548+
549+
```bash
550+
soroban keys ls
551+
```
552+
553+
Fund the identity's address on testnet:
554+
1. Get the public key: `soroban keys show admin`
555+
2. Visit [Stellar Testnet Friendbot](https://friendbot.stellar.org/) and fund the address
556+
3. Wait for the transaction to confirm (~5 seconds)
557+
558+
### Step 2: Build the Contract
559+
560+
```bash
561+
# Build release WASM (optimized for size and deployment)
562+
rustup target add wasm32-unknown-unknown
563+
cargo build --release --target wasm32-unknown-unknown -p creditra-credit
564+
```
565+
566+
The compiled WASM is at: `target/wasm32-unknown-unknown/release/creditra_credit.wasm`
567+
568+
### Step 3: Deploy the Contract
569+
570+
```bash
571+
# Deploy to testnet
572+
CONTRACT_ID=$(soroban contract deploy \
573+
--wasm target/wasm32-unknown-unknown/release/creditra_credit.wasm \
574+
--source admin \
575+
--network testnet)
576+
577+
echo "Contract deployed at: $CONTRACT_ID"
578+
```
579+
580+
Save the `CONTRACT_ID` in an environment variable for subsequent commands.
581+
582+
### Step 4: Initialize the Contract
583+
584+
```bash
585+
# Get the admin identity's public key
586+
ADMIN_PUBKEY=$(soroban keys show admin)
587+
588+
# Initialize with admin
589+
soroban contract invoke \
590+
--id $CONTRACT_ID \
591+
--source admin \
592+
--network testnet \
593+
-- init --admin $ADMIN_PUBKEY
594+
```
595+
596+
This sets the admin address and defaults the liquidity source to the contract address.
597+
598+
### Step 5: Configure Liquidity Token and Source
599+
600+
#### (Optional) Create a Test Liquidity Token
601+
602+
If deploying a mock token for testing:
603+
604+
```bash
605+
# Deploy a Stellar Asset Contract for USDC (testnet)
606+
USDC_CONTRACT=$(soroban contract deploy native \
607+
--network testnet \
608+
--source admin)
609+
610+
echo "USDC contract at: $USDC_CONTRACT"
611+
```
612+
613+
#### Set Liquidity Token
614+
615+
```bash
616+
soroban contract invoke \
617+
--id $CONTRACT_ID \
618+
--source admin \
619+
--network testnet \
620+
-- set_liquidity_token --token_address $USDC_CONTRACT
621+
```
622+
623+
#### Set Liquidity Source (Reserve Account)
624+
625+
The liquidity source is where reserve tokens are held. It can be the contract address,
626+
an external reserve account, or another contract.
627+
628+
```bash
629+
# Option A: Keep contract as reserve (already set in init)
630+
# No additional action needed
631+
632+
# Option B: Set a different reserve account
633+
RESERVE_PUBKEY=$(soroban keys show reserve)
634+
soroban contract invoke \
635+
--id $CONTRACT_ID \
636+
--source admin \
637+
--network testnet \
638+
-- set_liquidity_source --reserve_address $RESERVE_PUBKEY
639+
```
640+
641+
### Step 6: Open a Credit Line
642+
643+
Create a credit line for a borrower. This is typically called by the backend/risk engine.
644+
645+
```bash
646+
# Generate or use an existing borrower identity
647+
soroban keys generate borrower --network testnet
648+
BORROWER_PUBKEY=$(soroban keys show borrower)
649+
650+
# Open a credit line
651+
# - borrower: the borrower address
652+
# - credit_limit: 10000 (in smallest token unit, typically microunits)
653+
# - interest_rate_bps: 300 (3% annual interest)
654+
# - risk_score: 75 (out of 100)
655+
soroban contract invoke \
656+
--id $CONTRACT_ID \
657+
--source admin \
658+
--network testnet \
659+
-- open_credit_line \
660+
--borrower $BORROWER_PUBKEY \
661+
--credit_limit 10000 \
662+
--interest_rate_bps 300 \
663+
--risk_score 75
664+
```
665+
666+
Verify the credit line was created:
667+
668+
```bash
669+
soroban contract invoke \
670+
--id $CONTRACT_ID \
671+
--source admin \
672+
--network testnet \
673+
-- get_credit_line --borrower $BORROWER_PUBKEY
674+
```
675+
676+
### Step 7: Fund the Liquidity Reserve
677+
678+
If using a liquidity token, the reserve account must hold sufficient balance for draws.
679+
680+
```bash
681+
# If USDC contract is the token, fund the reserve
682+
# This example assumes the contract is the reserve
683+
soroban contract invoke \
684+
--id $USDC_CONTRACT \
685+
--source admin \
686+
--network testnet \
687+
-- mint --to $CONTRACT_ID --amount 50000
688+
689+
# Verify reserve balance
690+
soroban contract invoke \
691+
--id $USDC_CONTRACT \
692+
--source admin \
693+
--network testnet \
694+
-- balance --id $CONTRACT_ID
695+
```
696+
697+
### Step 8: Draw Credit
698+
699+
A borrower draws against their credit line. This transfers tokens from the reserve to the borrower.
700+
701+
```bash
702+
# Borrower draws 1000 units
703+
soroban contract invoke \
704+
--id $CONTRACT_ID \
705+
--source borrower \
706+
--network testnet \
707+
-- draw_credit \
708+
--borrower $BORROWER_PUBKEY \
709+
--amount 1000
710+
```
711+
712+
Verify the draw:
713+
714+
```bash
715+
soroban contract invoke \
716+
--id $CONTRACT_ID \
717+
--source admin \
718+
--network testnet \
719+
-- get_credit_line --borrower $BORROWER_PUBKEY
720+
```
721+
722+
Expected result: `utilized_amount` should now be 1000.
723+
724+
### Step 9: Repay Credit
725+
726+
Borrowers repay their drawn amount. The tokens are transferred back to the liquidity source.
727+
728+
#### Prerequisite: Approve Token Transfer
729+
730+
The borrower must approve the contract to transfer tokens on their behalf.
731+
732+
```bash
733+
# Borrower approves the contract to transfer up to 2000 units
734+
soroban contract invoke \
735+
--id $USDC_CONTRACT \
736+
--source borrower \
737+
--network testnet \
738+
-- approve \
739+
--from $BORROWER_PUBKEY \
740+
--spender $CONTRACT_ID \
741+
--amount 2000 \
742+
--expiration_ledger 1000000
743+
```
744+
745+
#### Execute Repayment
746+
747+
```bash
748+
# Borrower repays 500 units
749+
soroban contract invoke \
750+
--id $CONTRACT_ID \
751+
--source borrower \
752+
--network testnet \
753+
-- repay_credit \
754+
--borrower $BORROWER_PUBKEY \
755+
--amount 500
756+
```
757+
758+
Verify the repayment:
759+
760+
```bash
761+
soroban contract invoke \
762+
--id $CONTRACT_ID \
763+
--source admin \
764+
--network testnet \
765+
-- get_credit_line --borrower $BORROWER_PUBKEY
766+
```
767+
768+
Expected result: `utilized_amount` should now be 500.
769+
770+
### Step 10: Update Risk Parameters (Admin Only)
771+
772+
The admin can adjust credit limits, interest rates, and risk scores.
773+
774+
```bash
775+
soroban contract invoke \
776+
--id $CONTRACT_ID \
777+
--source admin \
778+
--network testnet \
779+
-- update_risk_parameters \
780+
--borrower $BORROWER_PUBKEY \
781+
--credit_limit 20000 \
782+
--interest_rate_bps 400 \
783+
--risk_score 85
784+
```
785+
786+
### Step 11: Manage Credit Line Status
787+
788+
#### Suspend a Credit Line
789+
790+
Prevent draws while allowing repayment.
791+
792+
```bash
793+
soroban contract invoke \
794+
--id $CONTRACT_ID \
795+
--source admin \
796+
--network testnet \
797+
-- suspend_credit_line --borrower $BORROWER_PUBKEY
798+
```
799+
800+
#### Default a Credit Line
801+
802+
Mark the borrower as in default (blocks draws, allows repayment).
803+
804+
```bash
805+
soroban contract invoke \
806+
--id $CONTRACT_ID \
807+
--source admin \
808+
--network testnet \
809+
-- default_credit_line --borrower $BORROWER_PUBKEY
810+
```
811+
812+
#### Close a Credit Line
813+
814+
- **Admin**: can force-close at any time
815+
- **Borrower**: can only close when `utilized_amount` is 0
816+
817+
```bash
818+
# Admin force-close
819+
soroban contract invoke \
820+
--id $CONTRACT_ID \
821+
--source admin \
822+
--network testnet \
823+
-- close_credit_line \
824+
--borrower $BORROWER_PUBKEY \
825+
--closer $ADMIN_PUBKEY
826+
827+
# Or borrower self-close (only when fully repaid)
828+
soroban contract invoke \
829+
--id $CONTRACT_ID \
830+
--source borrower \
831+
--network testnet \
832+
-- close_credit_line \
833+
--borrower $BORROWER_PUBKEY \
834+
--closer $BORROWER_PUBKEY
835+
```
836+
837+
### Useful Quick Reference
838+
839+
**Export identities to variables for scripting:**
840+
841+
```bash
842+
ADMIN=$(soroban keys show admin)
843+
BORROWER=$(soroban keys show borrower)
844+
RESERVE=$(soroban keys show reserve)
845+
TOKEN=$USDC_CONTRACT
846+
CONTRACT=$CONTRACT_ID
847+
```
848+
849+
**Query contract state:**
850+
851+
```bash
852+
# Check a specific credit line
853+
soroban contract invoke --id $CONTRACT --source admin --network testnet -- get_credit_line --borrower $BORROWER
854+
855+
# Check token balance
856+
soroban contract invoke --id $TOKEN --source admin --network testnet -- balance --id $CONTRACT
857+
```
858+
859+
**Troubleshooting common errors:**
860+
861+
| Error | Cause | Fix |
862+
|-------|-------|-----|
863+
| `HostError: Error(Auth, InvalidAction)` | Identity not authorized | Ensure `--source` identity is loaded and has been funded |
864+
| `HostError: Value(ContractError(1))` | Credit line not found | Verify credit line was opened with correct borrower address |
865+
| `HostError: Error(Contract, InvalidContractData)` | Contract ID invalid or contract not deployed | Check `$CONTRACT_ID` and verify deployment succeeded |
866+
| `Insufficient liquidity reserve` | Reserve balance too low | Fund the reserve with more tokens via `mint` or transfer |
867+
| `Insufficient allowance` | Token approval too low | Increase borrower's approval via token `approve` |
519868

520869
---
521870

0 commit comments

Comments
 (0)