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
81 changes: 81 additions & 0 deletions docs/adr/0001-soroban-rust-smart-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ADR-0001: Use Soroban (Rust) for Smart Contract Development

**Status:** Accepted
**Date:** 2024-01-15
**Authors:** [@rinafcode]
**Reviewers:** [@rinafcode]
**Tags:** contract, infrastructure

---

## Context

TeachLink requires a smart contract platform to manage tokenized learning rewards, proof-of-participation records, and educator incentive payouts. The contract must be auditable, deterministic, and deployable on a network with low transaction fees suitable for micro-reward use cases.

Several smart contract platforms were available at the time of this decision. The choice of platform determines the programming language, toolchain, deployment target, and long-term maintenance burden.

Key constraints:

- Micro-transactions (reward payouts as small as fractions of a token) require negligible fees
- The team has existing experience with Rust systems programming
- The contract surface area is large (bridge, escrow, rewards, reputation, assessment modules), so type safety and compile-time correctness guarantees are important
- Long-term auditability matters; the contract code must be readable and verifiable by external reviewers

## Decision

We will write TeachLink's smart contracts in Rust targeting the Soroban platform on the Stellar network. All contract modules (bridge, escrow, tokenization, rewards, reputation, assessment, emergency, audit, analytics, reporting, backup) will be compiled to `wasm32-unknown-unknown` and deployed as a single Soroban contract.

## Alternatives Considered

| Alternative | Reason Rejected |
|-------------|-----------------|
| Solidity on EVM (Ethereum / Polygon) | Gas fees unsuitable for micro-reward transactions; EVM bytecode harder to audit than Rust source; team preference for Rust type system |
| Move on Aptos / Sui | Ecosystem too early at decision time; limited tooling and auditor familiarity; cross-chain bridge support was less mature |
| CosmWasm (Rust on Cosmos) | Viable technically, but Stellar's Horizon API and SEP standards provide better fiat on/off-ramp integrations needed for educator payouts |
| Ink! on Substrate | Strong Rust support, but Polkadot parachain deployment complexity was disproportionate to the project's scale |

## Consequences

### Positive

- Rust's type system eliminates entire classes of contract bugs at compile time
- `cargo test` and `cargo clippy` integrate naturally into CI, giving immediate feedback on contract correctness
- Soroban's WASM execution environment is deterministic and sandboxed
- Stellar's low fee model supports the micro-reward use cases central to TeachLink
- The `wasm32-unknown-unknown` target produces compact, verifiable artifacts

### Negative / Trade-offs

- Soroban is a relatively new platform; the ecosystem of third-party libraries and auditors is smaller than EVM
- Cross-chain bridge to EVM networks requires a custom bridge module, adding significant complexity
- Windows development requires additional setup (MSVC toolchain or Docker) due to WASM linker limitations on MinGW

### Neutral

- The `wasm32-unknown-unknown` compile target is separate from native test compilation; developers must be aware of the two-target workflow (`cargo build --target wasm32-unknown-unknown` vs `cargo test`)

## Implementation Notes

**Affected modules:**

- `contracts/teachlink/` (entire contract workspace)

**Build command:**

```bash
cargo build --release --target wasm32-unknown-unknown -p teachlink-contract
```

**Related issues / PRs:** Initial project setup

---

## Review Checklist

- [x] Context accurately describes the problem without solution bias
- [x] Decision is stated clearly and unambiguously
- [x] At least two alternatives are documented with rejection rationale
- [x] Consequences cover both positive and negative outcomes
- [x] Status field is set correctly
- [x] Tags accurately reflect the domain
- [x] Linked to the relevant GitHub issue or PR
73 changes: 73 additions & 0 deletions docs/adr/0002-tokenized-learning-rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# ADR-0002: Tokenized Learning Rewards Architecture

**Status:** Accepted
**Date:** 2024-02-10
**Authors:** [@rinafcode]
**Reviewers:** [@rinafcode]
**Tags:** contract, platform

---

## Context

TeachLink's core value proposition is rewarding learners and educators with on-chain tokens tied to verifiable learning activity. The contract must mint, distribute, and track reward tokens in a way that is transparent, resistant to manipulation, and useful as a credential signal (proof-of-participation).

Design questions at the time of this decision:

- Should rewards use a custom token standard or the Stellar Asset Contract (SAC)?
- Should participation proofs be stored on-chain or referenced via content-addressed hashes?
- How should educator incentives be structured relative to learner rewards to prevent gaming?

## Decision

We will implement the rewards module as a contract-native distribution system that issues reward tokens through the `rewards` module and records proof-of-participation as on-chain events (Soroban contract events) rather than storing full participation data in contract storage. Educator incentives will be handled through a separate escrow module that releases funds upon verified learner milestone completion, not upon content upload.

## Alternatives Considered

| Alternative | Reason Rejected |
|-------------|-----------------|
| Store full participation records in contract storage | Contract storage on Soroban is metered and expensive for large payloads; event-based proofs are sufficient for auditability and cheaper to emit |
| Educator rewards on content upload | Creates perverse incentive to flood the platform with low-quality content; milestone-based release ties educator payout to actual learner success |
| Use only Stellar Classic assets (no SAC / contract layer) | Lacks programmable distribution logic; cannot encode conditional releases or reputation-weighted rewards |

## Consequences

### Positive

- Proof-of-participation events are permanent, publicly verifiable, and indexable by the TypeScript indexer layer
- Escrow-based educator incentives align educator success with learner outcomes
- Keeping participation data off-chain storage (in events) keeps contract storage footprint small and predictable
- The separation of `rewards`, `escrow`, and `tokenization` modules allows each to be upgraded or audited independently

### Negative / Trade-offs

- Soroban events are not queryable from within the contract itself; external consumers (indexer) must subscribe and store event history for queries
- Escrow release logic requires reliable milestone verification; an oracle or off-chain verifier must signal completion, introducing a trust assumption

### Neutral

- The event-based participation record means the indexer is a required component for any UI that displays learning history; the contract alone is not sufficient for a full product experience

## Implementation Notes

**Affected modules:**

- `contracts/teachlink/rewards`
- `contracts/teachlink/escrow`
- `contracts/teachlink/tokenization`
- `contracts/teachlink/reputation`
- `indexer/` (event subscription and storage)

**Related issues / PRs:** #

---

## Review Checklist

- [x] Context accurately describes the problem without solution bias
- [x] Decision is stated clearly and unambiguously
- [x] At least two alternatives are documented with rejection rationale
- [x] Consequences cover both positive and negative outcomes
- [x] Status field is set correctly
- [x] Tags accurately reflect the domain
- [x] Linked to the relevant GitHub issue or PR
78 changes: 78 additions & 0 deletions docs/adr/0003-cross-chain-bridge-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# ADR-0003: Cross-Chain Bridge Design

**Status:** Accepted
**Date:** 2024-03-05
**Authors:** [@rinafcode]
**Reviewers:** [@rinafcode]
**Tags:** contract, cross-chain, security

---

## Context

TeachLink operates on Stellar/Soroban, but learners and educators may hold assets or identities on other networks (EVM chains, in particular). To avoid locking users into a single chain, TeachLink needs a mechanism to bridge assets and credential signals between Stellar and external blockchains.

A bridge introduces significant security surface area: bridge contracts are among the most frequently exploited components in the broader blockchain ecosystem. The design must balance interoperability with security and auditability.

Key constraints:

- The bridge must not require a trusted single operator (single point of failure / centralization risk)
- Slashing conditions must exist to punish malicious or faulty validators
- The design must be extensible to additional chains beyond the initial target

## Decision

We will implement the bridge as a BFT (Byzantine Fault Tolerant) multi-validator consensus module within the TeachLink contract. The `bridge` module handles asset lock/unlock on the Stellar side, the `bft_consensus` module manages validator set and quorum logic, and the `slashing` module enforces penalties for misbehavior. Liquidity management across chains is handled by the `liquidity` module.

No single validator can unilaterally authorize a cross-chain transfer; a quorum signature is required.

## Alternatives Considered

| Alternative | Reason Rejected |
|-------------|-----------------|
| Use an existing third-party bridge (e.g., Wormhole, Axelar) | Introduces external dependency and trust assumptions on a third-party protocol; limits control over slashing and dispute resolution logic |
| Trusted relayer (single operator) | Single point of failure; compromised relayer key results in total bridge loss; unacceptable for a platform managing educator and learner funds |
| Optimistic bridge with fraud proofs | Introduces a challenge window (latency) that degrades UX for micro-transactions; more complex to implement correctly in Soroban's execution model |

## Consequences

### Positive

- BFT consensus eliminates single-point-of-failure risk at the bridge layer
- Slashing creates economic incentives for validators to behave correctly
- The modular design (`bridge`, `bft_consensus`, `slashing`, `multichain`, `liquidity`) allows each component to be tested and audited in isolation
- Extensible to additional chains by adding new chain adapters to the `multichain` module

### Negative / Trade-offs

- Building and maintaining a custom BFT consensus module is significantly more complex than delegating to a third-party bridge
- Validator set management (onboarding, rotation, slashing) requires ongoing operational overhead
- BFT consensus requires a minimum validator set size to be meaningful; a small or poorly distributed validator set reduces the security guarantees

### Neutral

- Cross-chain transfers have higher latency than native Stellar transactions due to the consensus round requirement; this is expected and documented for users

## Implementation Notes

**Affected modules:**

- `contracts/teachlink/bridge`
- `contracts/teachlink/bft_consensus`
- `contracts/teachlink/slashing`
- `contracts/teachlink/multichain`
- `contracts/teachlink/liquidity`

**Related issues / PRs:** #

---

## Review Checklist

- [x] Context accurately describes the problem without solution bias
- [x] Decision is stated clearly and unambiguously
- [x] At least two alternatives are documented with rejection rationale
- [x] Consequences cover both positive and negative outcomes
- [x] Status field is set correctly
- [x] Tags accurately reflect the domain
- [x] Linked to the relevant GitHub issue or PR
73 changes: 73 additions & 0 deletions docs/adr/0004-indexer-technology-selection.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# ADR-0004: Indexer Technology Selection (TypeScript / NestJS)

**Status:** Accepted
**Date:** 2024-03-20
**Authors:** [@rinafcode]
**Reviewers:** [@rinafcode]
**Tags:** indexer, infrastructure

---

## Context

The TeachLink smart contract emits Soroban events for all significant state changes (reward distributions, escrow releases, participation proofs, bridge transfers). These events are not directly queryable from within the contract or via simple RPC calls in a structured way. A separate indexer process is needed to subscribe to Soroban events, transform them, store them in a queryable database, and expose them to client applications via an API.

The indexer is an optional but practically required component for any production UI. It also hosts the recommendation and analytics features that are not feasible to run on-chain.

Key constraints:

- Must integrate with Stellar Horizon and Soroban RPC event subscription endpoints
- Must support long-running background processes (event listeners, retry logic)
- The team has more TypeScript experience than Go or Python for service development

## Decision

We will implement the indexer as a TypeScript/NestJS service. NestJS provides a structured module and dependency injection system suitable for a long-running service with multiple subsystems (event ingestion, storage, API, monitoring). The service subscribes to Soroban events via the Stellar SDK and stores processed data in a PostgreSQL database.

## Alternatives Considered

| Alternative | Reason Rejected |
|-------------|-----------------|
| Go service | Strong concurrency model, but team TypeScript familiarity is higher; NestJS module structure maps well to the multi-feature indexer design |
| Python (FastAPI / Celery) | Viable, but async event processing patterns in Python are less ergonomic than TypeScript; type safety weaker without strict mypy enforcement |
| The Graph protocol | Designed primarily for EVM chains; Soroban subgraph support was not mature at decision time |
| Rust (same language as contract) | Would maximize code sharing for type definitions, but NestJS ecosystem provides more out-of-the-box tooling for REST APIs, background jobs, and observability integration |

## Consequences

### Positive

- NestJS's module system naturally maps to TeachLink's multi-feature architecture (one module per contract feature domain)
- TypeScript's type system allows sharing schema types between indexer and frontend clients
- Large ecosystem of Stellar JavaScript/TypeScript SDKs (`@stellar/stellar-sdk`)
- NestJS integrates well with Prometheus metrics exporters used in the observability stack (ADR-0005)

### Negative / Trade-offs

- TypeScript/Node.js has higher memory overhead than Go or Rust for long-running processes
- The indexer introduces a separate runtime dependency; operators must manage both the contract deployment and the indexer service
- Schema drift between on-chain event payloads and indexer DTOs must be managed carefully (see `NAMING_CONVENTIONS.md`)

### Neutral

- The indexer is architecturally optional; the contract functions correctly without it, but the full product experience (learning history, analytics, recommendations) requires it

## Implementation Notes

**Affected modules:**

- `indexer/` (entire indexer workspace)

**Related issues / PRs:** #

---

## Review Checklist

- [x] Context accurately describes the problem without solution bias
- [x] Decision is stated clearly and unambiguously
- [x] At least two alternatives are documented with rejection rationale
- [x] Consequences cover both positive and negative outcomes
- [x] Status field is set correctly
- [x] Tags accurately reflect the domain
- [x] Linked to the relevant GitHub issue or PR
79 changes: 79 additions & 0 deletions docs/adr/0005-observability-stack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# ADR-0005: Observability Stack (Prometheus, Alertmanager, Grafana)

**Status:** Accepted
**Date:** 2024-04-08
**Authors:** [@rinafcode]
**Reviewers:** [@rinafcode]
**Tags:** infrastructure, indexer

---

## Context

The TeachLink indexer is a long-running service with several subsystems (event ingestion, API, background jobs). Production incidents on an event-driven system are hard to diagnose without visibility into throughput, lag, error rates, and resource usage.

Additionally, the Soroban contract itself emits telemetry-relevant events (reward distributions, escrow state changes, bridge operations) that should be surfaced to operators for health monitoring.

An observability stack must be chosen that:

- Collects and stores time-series metrics from the indexer runtime
- Provides alerting for anomalies (ingestion lag, high error rates, validator slashing events)
- Offers dashboards accessible to non-developer operators
- Can be self-hosted alongside the indexer without external SaaS dependency

## Decision

We will use Prometheus for metrics collection, Alertmanager for alert routing, and Grafana for dashboards. The NestJS indexer will expose a `/metrics` endpoint compatible with Prometheus scraping. Contract-level telemetry will be surfaced by mapping Soroban events to Prometheus counters and gauges within the indexer.

## Alternatives Considered

| Alternative | Reason Rejected |
|-------------|-----------------|
| Datadog / New Relic (SaaS APM) | Per-seat and per-metric pricing unsuitable for an open-source project; introduces external data dependency |
| OpenTelemetry collector → Jaeger | Better suited to distributed tracing than time-series metrics; the indexer's primary observability need is metrics and alerting, not trace correlation |
| InfluxDB + Chronograf | Viable time-series stack, but Prometheus + Grafana has broader community adoption, more pre-built dashboards, and stronger NestJS integration libraries |

## Consequences

### Positive

- Prometheus + Grafana is the de-facto standard for self-hosted service monitoring; large library of pre-built dashboards and exporters
- Alertmanager integrates with common notification channels (PagerDuty, Slack, email) without custom webhook code
- NestJS has first-class Prometheus integration via `@willsoto/nestjs-prometheus`
- Entirely self-hosted; no external data egress required

### Negative / Trade-offs

- Requires operators to run three additional services (Prometheus, Alertmanager, Grafana) alongside the indexer
- Long-term metric storage requires configuring Prometheus remote write or a separate time-series store (e.g., Thanos, Mimir) for retention beyond the default 15-day window
- Grafana dashboard-as-code tooling (Grafonnet) adds a learning curve for contributors who want to modify dashboards

### Neutral

- The observability stack is documented separately in `OBSERVABILITY.md` and `indexer/MONITORING.md`; this ADR records only the technology selection rationale

## Implementation Notes

**Affected modules:**

- `indexer/` (metrics endpoint and instrumentation)
- `docker-compose.yml` (Prometheus, Alertmanager, Grafana service definitions)

**Reference docs:**

- `OBSERVABILITY.md`
- `indexer/MONITORING.md`

**Related issues / PRs:** #

---

## Review Checklist

- [x] Context accurately describes the problem without solution bias
- [x] Decision is stated clearly and unambiguously
- [x] At least two alternatives are documented with rejection rationale
- [x] Consequences cover both positive and negative outcomes
- [x] Status field is set correctly
- [x] Tags accurately reflect the domain
- [x] Linked to the relevant GitHub issue or PR
Loading
Loading