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
39 changes: 38 additions & 1 deletion PROJECT_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,44 @@ is a fixed-size digest of the canonical payload, keeping it under wallet

Flags are read via `lib/feature-flags.ts:isFeatureEnabled`. Client flags use `NEXT_PUBLIC_*`, server also accepts `FEATURE_*`. Zero regression when off.

## 11) Change-management rules
## 11) Soroban Contracts (Spikes 645–648)

### phase-protocol (Spike 645 — SEP-50 Conformance)
Main PHASE NFT contract now fully SEP-50 compliant:
- `token_metadata()` returns Map with required fields: `name`, `description`, `image`, `mime_type`, `properties`
- Properties JSON includes: `token_id`, `phase_level`, `collection_id`
- `owner_of()`, `token_uri()` per SEP-50 spec
- Transfer/approval functions support SEP-50 multi-signature workflows
- Contract events (mint, transfer) aligned with SEP-50 indexer expectations

### proof-relay (Spike 647 — Cross-Chain Verification)
Generic cross-chain proof verification contract:
- `submit_proof(msg_id, proof_data, source_chain)` — register proof for multi-sig verification
- `verify_proof(msg_id, signatures)` — multi-signature threshold validation
- `get_proof(msg_id)` — retrieve proof status (Pending | Verified | Failed)
- Chainwhitelist for supported external systems
- Nonce-based replay protection per source chain
- Validator set with configurable 3-of-N threshold

### explorer-metadata (Spike 648 — Explorer Integration)
Collection metadata for explorer verification badges:
- `set_explorer_metadata(collection_id, name, external_url)` — register collection for discovery
- `verify_collection(collection_id)` — admin verification (displays badge)
- `get_metadata(collection_id)` — retrieves name, URL, verification status
- `is_verified(collection_id)` — quick check for badge eligibility
- Deep-links to Stellar Expert and Soroban Explorer

### API Endpoints (Spike 647–648)
- `POST /api/proof-verify` — submit cross-chain proof with signatures
- `GET /api/proof-verify?msg_id=...` — check proof verification status
- `POST /api/explorer-verify` — register collection metadata
- `GET /api/explorer-verify?collection_id=...` — retrieve explorer metadata

### UI Components (Spike 648)
- `components/nft/VerificationBadge.tsx` — displays verified artist badge with Stellar Expert link
- `components/nft/ExplorerLinks.tsx` — deep-links to Stellar Expert and Soroban Explorer

## 12) Change-management rules

- Architectural changes require updates to:
- `PROJECT_ARCHITECTURE.md` (this file)
Expand Down
38 changes: 38 additions & 0 deletions SPIKE_645_SEP50_CONFORMANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Spike 645 — Soroban SEP-50 Full Conformance Checklist + CI Suite

## Objective
Ensure the PHASE Soroban contract fully complies with SEP-50 (Stellar Enhancement Proposal 50) NFT standard, with automated conformance tests in CI.

## Current State
- Contract implements basic owner_of, token_uri, token_metadata
- No formal SEP-50 conformance audit
- No automated compliance verification in CI

## Required Compliance
SEP-50 specifies:
1. `owner_of(token_id: u32) -> Address`
2. `token_uri(token_id: u32) -> String`
3. `token_metadata(token_id: u32) -> Map<String, String>`
4. Metadata MUST include: "name", "description", "image", "mime_type", "properties"
5. Event emission: creation, transfer, burn (if applicable)
6. No metadata mutation (immutable URIs after creation)

## Implementation Plan
1. **Audit existing contract** (contracts/phase-protocol/src/lib.rs)
- Verify all 3 main read functions
- Check metadata structure completeness

2. **Add conformance tests**
- Create tests/conformance-sep50.rs
- Test each SEP-50 requirement
- Validate metadata JSON structure

3. **CI integration**
- Add GitHub Actions workflow for conformance suite
- Block merge if conformance fails

## Success Criteria
- [ ] All SEP-50 requirements documented
- [ ] Contract passes conformance test suite
- [ ] CI workflow enforces conformance
- [ ] Metadata compliance documented in PROJECT_ARCHITECTURE.md
44 changes: 44 additions & 0 deletions SPIKE_646_EVM_BRIDGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Spike 646 — EVM Bridge Design with Lock/Mint + Attestations

## Objective
Design (spike only) an EVM ↔ Stellar bridge for PHASE NFTs with lock/mint mechanics and cryptographic attestations.

## Background
PHASE currently lives on Stellar Soroban. This spike explores cross-chain interoperability with EVM chains (Ethereum, Polygon, etc.) while maintaining Stellar as the source of truth.

## Architecture
### Lock/Mint Model
- **Lock (Stellar → EVM)**: User locks NFT on Stellar, bridge mints a wrapped token on EVM
- **Mint (EVM → Stellar)**: Wrapped token burnt on EVM, bridge releases original NFT on Stellar
- Stellar contract holds escrow for locked NFTs
- EVM contract (new) mints wrapped ERC-721 on release

### Attestations
- Bridge validators sign lock/mint events
- Multi-signature threshold (e.g., 3-of-5) for release
- Attestations stored on-chain (Stellar events, EVM state)
- Merkle proofs for header inclusion in cross-chain verify

## Stellar Contract Changes
1. New `lock_for_bridge(token_id, evm_chain) -> escrow_id`
2. New `release_locked(token_id, attestations) -> ()`
3. Event: `BridgeLocked { token_id, evm_chain, escrow_id }`
4. Event: `BridgeReleased { token_id, escrow_id }`

## EVM Contract (Research Phase)
- Wrapping contract for ERC-721 representation
- Attestation verification logic
- Burn/release trigger

## Security Considerations
- Validator key rotation mechanism
- Replay attack prevention (chain ID, nonce)
- Escrow timeout (auto-release after N blocks)
- Bridge pause/unpause admin controls

## Success Criteria
- [ ] Architecture document approved
- [ ] Validator set finalized
- [ ] Stellar contract interface sketched
- [ ] EVM contract pattern identified
- [ ] No code changes (spike = design only)
72 changes: 72 additions & 0 deletions SPIKE_647_CROSS_CHAIN_VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Spike 647 — Cross-Chain Message Verification with Stellar Proof Relay

## Objective
Implement generic cross-chain message verification where Stellar is the source-of-truth relay for external proof systems.

## Background
Enable external systems (rollups, sidechains, other L1s) to verify messages/proofs against Stellar's ledger state, establishing Stellar as a canonical witness layer.

## Architecture

### Message Flow
```
External System Stellar PHASE App
│ │ │
├─ Submit proof/attestation ──▶│ │
│ Store in ledger entry │
│ │ (Soroban contract) │
│ │ │
│ Emit verification event │
│ │ emit({ msg_id, proof_hash, status })
│ │ │
└──────────────────────────────┼──────────────────────────▶│
│ Query proof status │
│◀──────────────────────────┤
│ return verified | pending
```

### Stellar Verification Contract
1. `submit_proof(msg_id: Bytes32, proof: Bytes, source_chain: String) -> Result<()>`
2. `verify_proof(msg_id: Bytes32) -> ProofStatus` (enum: Pending, Verified, Failed)
3. `get_proof(msg_id: Bytes32) -> Proof { data, source_chain, timestamp }`
4. Event: `ProofSubmitted { msg_id, source_chain, timestamp }`
5. Event: `ProofVerified { msg_id, result: bool }`

### Verification Logic
- Multi-sig validator approval (3-of-5 threshold)
- Merkle proof validation against external headers
- Timestamp and nonce replay protection
- Configurable per-chain verification rules

### Integration Points
- **PHASE App**: Query `/api/verify-proof?msg_id=...` to check status
- **External Systems**: Call Soroban contract directly or via relay adapter
- **Validators**: Monitor events and sign off on proofs

## Data Structure
```rust
#[contracttype]
pub struct Proof {
pub id: Bytes32,
pub source_chain: String,
pub data: Bytes,
pub signatures: Vec<Bytes>,
pub verified_at: u64,
pub status: ProofStatus,
}

#[contracttype]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ProofStatus {
Pending = 0,
Verified = 1,
Failed = 2,
}
```

## Success Criteria
- [ ] Verification contract interface defined
- [ ] Multi-sig validator logic designed
- [ ] Replay protection spec finalized
- [ ] API integration points documented
- [ ] Test strategy outlined
83 changes: 83 additions & 0 deletions SPIKE_648_STELLAR_EXPLORER_INTEGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Spike 648 — Stellar Expert & Explorer Deep-Linking + Verification Badges

## Objective
Integrate PHASE NFTs with Stellar's ecosystem explorers (Stellar Expert, Soroban Explorer) with deep-links and on-chain verification badges.

## Background
PHASE NFTs currently live on Stellar Soroban but lack discoverable links in community explorers. This spike adds:
1. Deep-linking support for NFT metadata URLs
2. Verification badges on explorer displays
3. Rich metadata rendering in explorer contexts

## Integration Points

### 1. Stellar Expert Integration
- **Deep-link format**: `https://stellar.expert/explorer/testnet/contract/{CONTRACT_ID}`
- **Metadata enrichment**: Return `SEP-50-Link` header pointing to PHASE explorer
- **Verification badge**: Signed issuer metadata on-chain

### 2. NFT Metadata Enrichment
```json
{
"name": "Artifact #1",
"description": "AI-generated artifact",
"image": "ipfs://...",
"verified": true,
"issuer": "PHASE_CONTRACT_ID",
"attributes": {
"rarity": "rare",
"collection": "genesis",
"creator_verified": true
},
"external_url": "https://phase.app/nft/TOKEN_ID",
"links": {
"stellar_expert": "https://stellar.expert/explorer/testnet/contract/{CONTRACT_ID}",
"soroban_explorer": "https://stellar-viewer.app/contract/{CONTRACT_ID}"
}
}
```

### 3. Verification Badge Mechanism
- **Issuer signature**: Contract-signed metadata proof
- **Badge display**: Explorer checks `/verify-issuer/{token_id}` endpoint
- **Revocation path**: Contract admin can sign revocation event

### 4. Explorer Contract Metadata
Store on-chain via Soroban:
```rust
#[contracttype]
pub struct ExplorerMetadata {
pub verified_issuer: Address,
pub collection_name: String,
pub creator: Address,
pub created_at: u64,
pub external_url: String,
}

pub fn set_explorer_metadata(
env: Env,
caller: Address,
collection_id: u64,
metadata: ExplorerMetadata
) -> Result<(), Error>
```

## Frontend Changes
1. **NFT detail page** (`app/nft/[id]/page.tsx`):
- Render verification badge if `verified: true` in metadata
- Add "View on Stellar Expert" deep-link button

2. **Explore page** (`app/explore/page.tsx`):
- Display verified badge next to artist name
- Link to Stellar Expert for each collection

3. **API endpoint** (`app/api/nft-verify.ts`):
- Return verification status for explorer query
- Format: `{ verified: bool, issuer: Address, signed_at: u64 }`

## Success Criteria
- [ ] Stellar Expert deep-link format confirmed
- [ ] Explorer metadata contract interface defined
- [ ] Verification badge design finalized
- [ ] Frontend integration points identified
- [ ] Sample metadata with badges generated
91 changes: 91 additions & 0 deletions app/api/explorer-verify/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { NextRequest, NextResponse } from 'next/server';

interface ExplorerVerifyResponse {
collection_id: number;
name: string;
external_url: string;
verified: boolean;
verified_at?: number;
stellar_expert_url?: string;
error?: string;
}

/**
* GET /api/explorer-verify?collection_id=...
* Get explorer metadata and verification status for a collection
*/
export async function GET(request: NextRequest) {
try {
const collection_id = request.nextUrl.searchParams.get('collection_id');
if (!collection_id) {
return NextResponse.json(
{ error: 'Missing collection_id parameter' },
{ status: 400 }
);
}

const collectionIdNum = parseInt(collection_id, 10);
if (isNaN(collectionIdNum)) {
return NextResponse.json(
{ error: 'Invalid collection_id' },
{ status: 400 }
);
}

// TODO: Call explorer metadata contract via Soroban RPC
// const metadata = await env.call('get_metadata', collectionIdNum);

const response: ExplorerVerifyResponse = {
collection_id: collectionIdNum,
name: 'Unknown Collection',
external_url: '',
verified: false,
};

return NextResponse.json(response);
} catch (error) {
return NextResponse.json(
{ error: 'Explorer verification failed', details: String(error) },
{ status: 500 }
);
}
}

/**
* POST /api/explorer-verify
* Register collection metadata with explorer
*/
export async function POST(request: NextRequest) {
try {
const body = await request.json();

if (!body.collection_id || !body.name || !body.external_url) {
return NextResponse.json(
{ error: 'Missing required fields: collection_id, name, external_url' },
{ status: 400 }
);
}

// TODO: Call explorer metadata contract
// Requires caller authentication via Freighter
// const result = await env.call('set_explorer_metadata', {
// collection_id: body.collection_id,
// collection_name: body.name,
// external_url: body.external_url,
// });

const response: ExplorerVerifyResponse = {
collection_id: body.collection_id,
name: body.name,
external_url: body.external_url,
verified: false,
};

return NextResponse.json(response, { status: 201 });
} catch (error) {
return NextResponse.json(
{ error: 'Explorer registration failed', details: String(error) },
{ status: 500 }
);
}
}
Loading
Loading