Skip to content
Merged
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
18 changes: 15 additions & 3 deletions app/onchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ Soroban smart contracts for ChainForge's on-chain escrow and claimable aid packa
|---|---|---|
| `aid_escrow` | Testnet | `CDSBJ27PKTNFTRW6OKPCVXDRUSSRUIQUG6DW5PUTKLDXTDT23NQIS6JG` |

> **Redeploy required for delegate support.** The wasm deployed at the address
> above predates the delegate/recovery entrypoints and the `claim(id, claimer)`
> signature change. `set_delegate`, `get_delegate`, `get_delegate_info`,
> `get_delegate_history`, and `cleanup_expired_delegates` are **not** callable on
> the currently deployed contract until a new wasm is built and deployed. See
> [the deployment runbook](../../docs/testnet-deploy-runbook.md).

[View on Stellar Expert](https://stellar.expert/explorer/testnet/contract/CDSBJ27PKTNFTRW6OKPCVXDRUSSRUIQUG6DW5PUTKLDXTDT23NQIS6JG) · [View on Stellar Lab](https://lab.stellar.org/r/testnet/contract/CDSBJ27PKTNFTRW6OKPCVXDRUSSRUIQUG6DW5PUTKLDXTDT23NQIS6JG) · [Deployment Record](deployments/testnet-2026-06-03.md)

---
Expand Down Expand Up @@ -65,7 +72,12 @@ Events use stable topic identifiers (struct name in snake_case) so indexers and
| `fund(token, from, amount)` | Deposits funds into the contract pool | `from` |
| `create_package(operator, id, recipient, amount, token, expires_at)` | Creates a package with a manual ID | `admin` or `distributor` |
| `batch_create_packages(operator, recipients, amounts, token, expires_in)` | Creates multiple packages with auto-incremented IDs | `admin` or `distributor` |
| `claim(id)` | Recipient claims their allocated funds | `recipient` |
| `claim(id, claimer)` | Recipient or a registered, unexpired delegate claims the package (funds always pay out to the recipient) | `recipient` or `delegate` |
| `set_delegate(package_id, delegate, expires_at)` | Registers a delegate (recovery) address, optionally with an expiry (`0` = never). Rejected for claimed packages or when the delegate equals the recipient | `admin` |
| `get_delegate(package_id)` | Returns the active delegate, or `None` if unset or expired | None |
| `get_delegate_info(package_id)` | Returns the active delegate and its expiry | None |
| `get_delegate_history(package_id)` | Returns the append-only delegate audit trail | None |
| `cleanup_expired_delegates()` | Removes expired delegates, returning the number cleaned | `admin` |
| `disburse(id)` | Admin manually sends package funds to recipient | `admin` |
| `revoke(id)` / `cancel_package(id)` | Cancels an active package and unlocks funds | `admin` |
| `refund(id)` | Returns funds from an expired/cancelled package to admin | `admin` |
Expand Down Expand Up @@ -112,8 +124,8 @@ Use `scripts/testnet-invoke.sh` for repeatable testnet calls against the `aid_es
--amount 10000000 \
--token CTOKEN...

# Claim and inspect package state
./scripts/testnet-invoke.sh claim --id 1
# Claim (by recipient or a registered delegate) and inspect package state
./scripts/testnet-invoke.sh claim --id 1 --claimer GRECIPIENT...
./scripts/testnet-invoke.sh get-package --id 1
./scripts/testnet-invoke.sh view-status --id 1
./scripts/testnet-invoke.sh get-aggregates --token CTOKEN...
Expand Down
21 changes: 18 additions & 3 deletions app/onchain/contracts/aid_escrow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Soroban smart contract for managing aid-package escrow on Stellar.
| **Version** | `0.1.0` |
| **Deployed** | 2026-06-03 |

> **Redeploy required.** The wasm deployed at this address predates the
> delegate/recovery entrypoints (`set_delegate`, `get_delegate`, …) and the
> `claim(id, claimer)` signature change; a new wasm must be built and deployed
> before those functions are callable on testnet.

Explorer: [Stellar Expert](https://stellar.expert/explorer/testnet/contract/CDSBJ27PKTNFTRW6OKPCVXDRUSSRUIQUG6DW5PUTKLDXTDT23NQIS6JG) · [Stellar Lab](https://lab.stellar.org/r/testnet/contract/CDSBJ27PKTNFTRW6OKPCVXDRUSSRUIQUG6DW5PUTKLDXTDT23NQIS6JG)

Full deployment record with transaction hashes and verification steps: [deployments/testnet-2026-06-03.md](../../deployments/testnet-2026-06-03.md)
Expand Down Expand Up @@ -54,13 +59,23 @@ expires and is refunded.
|---|---|---|
| `create_package(env, operator, id, recipient, amount, token, expires_at)` | Admin / Distributor | Creates a single aid package with a specific ID. Locks funds from the available pool. |
| `batch_create_packages(env, operator, recipients, amounts, token, expires_in)` | Admin / Distributor | Creates multiple packages in one transaction using auto-incrementing IDs. |
| `claim(env, id)` | Recipient | Recipient claims the package. Transfers tokens to recipient and marks package as claimed. |
| `claim(env, id, claimer)` | Recipient / Delegate | Recipient or a registered, unexpired delegate claims the package. Transfers tokens to the recipient and marks the package as claimed. |
| `disburse(env, id)` | Admin | Admin manually disburses a package to its recipient. |
| `revoke(env, id)` | Admin | Admin revokes a package, returning funds to the surplus pool. |
| `refund(env, id)` | Admin | Refunds an expired or cancelled package to the admin. |
| `cancel_package(env, package_id)` | Admin | Cancels a package (transitions to Cancelled status). |
| `extend_expiration(env, package_id, additional_time)` | Admin / Distributor | Extends the expiration time of an active package. |

### Delegate (Recovery) Support

| Function | Auth | Description |
|---|---|---|
| `set_delegate(env, package_id, delegate, expires_at)` | Admin | Registers `delegate` as the recovery address for a package, optionally with an `expires_at` deadline (`0` = never). Rejected for claimed packages and when the delegate equals the recipient. |
| `get_delegate(env, package_id)` | — | Returns the active delegate, or `None` if unset or expired. |
| `get_delegate_info(env, package_id)` | — | Returns the active delegate and its expiry, or `None` if unset. |
| `get_delegate_history(env, package_id)` | — | Returns the append-only audit trail of delegate assignments and removals. |
| `cleanup_expired_delegates(env)` | Admin | Removes expired delegates from storage, returning the number cleaned up. |

### Queries

| Function | Auth | Description |
Expand All @@ -73,7 +88,7 @@ expires and is refunded.
## Package Lifecycle

```
Created --> Claimed (recipient claims)
Created --> Claimed (recipient or delegate claims)
Created --> Expired (past expiry, recipient tries to claim)
Created --> Cancelled (admin cancels)
Created --> Claimed (admin) (admin disburses)
Expand Down Expand Up @@ -143,7 +158,7 @@ All state-changing operations emit events with stable topics for indexer consump

- `EscrowFunded` — pool funded
- `PackageCreated` — package created
- `PackageClaimed` — recipient claimed
- `PackageClaimed` — package claimed (by recipient or delegate)
- `PackageDisbursed` — admin disbursed
- `PackageRevoked` — admin revoked
- `PackageRefunded` — admin refunded
Expand Down
Loading
Loading