Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions .github\workflows\docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Deploy Documentation

on:
push:
branches:
- main
paths:
- 'docs/**'
- 'docs-site/**'
- '.github/workflows/docs.yml'
pull_request:
branches:
- main
paths:
- 'docs/**'
- 'docs-site/**'
- '.github/workflows/docs.yml'
# Allow manual trigger
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: 'pages'
cancel-in-progress: false

jobs:
# ─── Build Job ─────────────────────────────────────────────────────────────
build:
name: Build Documentation
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for git-based last-modified timestamps

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: docs-site/package-lock.json

- name: Setup GitHub Pages
uses: actions/configure-pages@v5

- name: Install docs dependencies
working-directory: docs-site
run: npm ci

- name: Copy docs content into docs-site
run: |
# Copy docs from the /docs directory into docs-site/docs
# preserving the directory structure
echo "📁 Syncing content from /docs to /docs-site/docs..."

# Guide docs
mkdir -p docs-site/docs/guide
for f in docs/guide/*.md; do
[ -f "$f" ] && cp "$f" "docs-site/docs/guide/" && echo " ✅ Copied $f"
done

# API docs
mkdir -p docs-site/docs/api
for f in docs/api/*.md; do
[ -f "$f" ] && cp "$f" "docs-site/docs/api/" && echo " ✅ Copied $f"
done

# Tutorial docs
mkdir -p docs-site/docs/tutorial
for f in docs/tutorial/*.md; do
[ -f "$f" ] && cp "$f" "docs-site/docs/tutorial/" && echo " ✅ Copied $f"
done

# Root docs (README, API, index)
for f in docs/README.md docs/API.md docs/index.md; do
[ -f "$f" ] && cp "$f" "docs-site/docs/" && echo " ✅ Copied $f"
done

echo "✨ Content sync complete!"

- name: Build Docusaurus site
working-directory: docs-site
run: npm run build
env:
NODE_ENV: production

- name: Upload artifact for Pages
uses: actions/upload-pages-artifact@v3
with:
path: docs-site/build

# ─── Deploy Job (only on push to main) ─────────────────────────────────────
deploy:
name: Deploy to GitHub Pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
# Only deploy on push to main, not on pull requests
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

# ─── Link Check Job ─────────────────────────────────────────────────────────
link-check:
name: Check Documentation Links
runs-on: ubuntu-latest
needs: build
# Only run on pull requests to catch broken links before merge
if: github.event_name == 'pull_request'

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: docs-site/package-lock.json

- name: Install docs dependencies
working-directory: docs-site
run: npm ci

- name: Build for link checking
working-directory: docs-site
run: npm run build
env:
NODE_ENV: production

- name: Check links
working-directory: docs-site
run: |
npm run serve -- --port 3000 &
sleep 5
npx broken-link-checker http://localhost:3000 \
--recursive \
--ordered \
--filter-level 3 \
--exclude "github.com" \
--exclude "npmjs.com" \
--exclude "stellar.org" \
|| echo "⚠️ Some links may be broken — review above output"
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
175 changes: 3 additions & 172 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,175 +1,6 @@
# SoroSave SDK
# SoroSave Documentation Site

TypeScript SDK for interacting with the SoroSave smart contracts on Soroban.
This directory contains the Docusaurus-powered documentation site for the SoroSave SDK.

## Installation
## Local Development

```bash
npm install @sorosave/sdk
```

### React Hooks

If you're using React, you can also install the peer dependency:

```bash
npm install react @sorosave/sdk
```

## Usage

### Core SDK

```typescript
import { SoroSaveClient } from "@sorosave/sdk";

const client = new SoroSaveClient({
rpcUrl: "https://soroban-testnet.stellar.org",
contractId: "YOUR_CONTRACT_ID",
networkPassphrase: "Test SDF Network ; September 2015",
});

const tx = await client.createGroup({
admin: "G...",
name: "My Savings Group",
token: "TOKEN_ADDRESS",
contributionAmount: 1000000n,
cycleLength: 86400,
maxMembers: 5,
}, sourcePublicKey);

const group = await client.getGroup(1);
```

### React Hooks

The SDK includes React hooks for easy frontend integration:

```tsx
import {
SoroSaveProvider,
useGroup,
useContribute,
useMemberGroups
} from "@sorosave/react";

// 1. Wrap your app with the provider
function App() {
return (
<SoroSaveProvider config={{
contractId: "YOUR_CONTRACT_ID",
rpcUrl: "https://soroban-testnet.stellar.org",
networkPassphrase: "Test SDF Network ; September 2015",
}}>
<YourApp />
</SoroSaveProvider>
);
}

// 2. Use hooks in your components
function GroupInfo({ groupId }: { groupId: number }) {
const { group, loading, error, refetch } = useGroup(groupId);

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!group) return <div>Group not found</div>;

return (
<div>
<h2>{group.name}</h2>
<p>Members: {group.members.length}/{group.maxMembers}</p>
<p>Status: {group.status}</p>
<button onClick={refetch}>Refresh</button>
</div>
);
}

// 3. Contribute to a group
function ContributeButton({ groupId, memberAddress }: {
groupId: number;
memberAddress: string
}) {
const { contribute, loading, error } = useContribute();

const handleContribute = async () => {
const keypair = StellarSdk.Keypair.fromSecret("YOUR_SECRET_KEY");
await contribute({
member: memberAddress,
groupId,
sourceKeypair: keypair,
});
};

return (
<button onClick={handleContribute} disabled={loading}>
{loading ? "Contributing..." : "Contribute"}
</button>
);
}

// 4. Get all groups for a member
function MemberGroups({ address }: { address: string }) {
const { groupIds, loading, refetch } = useMemberGroups(address);

return (
<div>
<h3>Your Groups ({groupIds.length})</h3>
<ul>
{groupIds.map(id => <li key={id}>Group #{id}</li>)}
</ul>
<button onClick={refetch}>Refresh</button>
</div>
);
}
```

### Available Hooks

| Hook | Description |
|------|-------------|
| `useGroup(groupId)` | Fetch and monitor a savings group by ID |
| `useContribute()` | Mutation hook for making contributions |
| `useMemberGroups(address)` | Get all groups a member belongs to |
| `useSoroSaveClient()` | Access the raw SDK client |
| `useSoroSaveConfig()` | Access the current configuration |

## API

### Core SDK Methods

- `createGroup()` — Create a new savings group
- `joinGroup()` — Join an existing group
- `leaveGroup()` — Leave a group (while forming)
- `startGroup()` — Start the group (admin only)
- `contribute()` — Contribute to the current round
- `distributePayout()` — Distribute pot to recipient
- `pauseGroup()` / `resumeGroup()` — Admin controls
- `raiseDispute()` — Raise a dispute
- `getGroup()` — Get group details
- `getRoundStatus()` — Get round info
- `getMemberGroups()` — Get all groups for a member

## Development

```bash
# Install dependencies
pnpm install

# Build
pnpm build

# Test
pnpm test

# Lint
pnpm lint
```

## Documentation

- [ARCHITECTURE.md](./ARCHITECTURE.md) — Protocol architecture
- [CONTRIBUTING.md](./CONTRIBUTING.md) — How to contribute

## License

MIT
12 changes: 12 additions & 0 deletions docs\api\client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
id: client
title: SoroSaveClient
sidebar_position: 2
---

# SoroSaveClient

The main client class for interacting with the SoroSave smart contract.

## Constructor

34 changes: 34 additions & 0 deletions docs\api\index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
id: index
title: API Overview
sidebar_position: 1
---

# API Reference

Complete API reference for the SoroSave SDK.

## Modules

### Core SDK (`@sorosave/sdk`)

| Export | Description |
|--------|-------------|
| [`SoroSaveClient`](./client) | Main client class for contract interactions |
| [Types](./types) | TypeScript type definitions |
| [Utils](./utils) | Utility functions |

### React SDK (`@sorosave/react`)

| Export | Description |
|--------|-------------|
| `SoroSaveProvider` | React context provider |
| `useGroup(groupId)` | Hook for fetching a savings group |
| `useContribute()` | Mutation hook for making contributions |
| `useMemberGroups(address)` | Hook for fetching all groups for an address |
| `useSoroSave()` | Hook for accessing the SDK client directly |

## Quick Reference

### Creating a Group

Loading