diff --git a/README.md b/README.md index f83de57..5bd52ff 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,10 @@ docs/ environment-invariants.md api/ secret-system.openapi.yaml + marketplace.openapi.yaml examples/ secret-system.examples.md + marketplace.examples.md handoff/ membership-backend-checklist.md schemas/ diff --git a/docs/api/examples/marketplace.examples.md b/docs/api/examples/marketplace.examples.md new file mode 100644 index 0000000..2539b44 --- /dev/null +++ b/docs/api/examples/marketplace.examples.md @@ -0,0 +1,120 @@ +# Marketplace API Examples (v1) + +## `GET /marketplace/offers` + +Success (`200`): + +```json +{ + "offers": [ + { + "offer_id": "edut.crm.pro.annual", + "issuer_id": "edut.firstparty", + "title": "EDUT CRM Pro", + "summary": "Workspace-bound CRM module.", + "status": "active", + "pricing": { + "currency": "USDC", + "amount_atomic": "199000000", + "decimals": 6, + "chain_id": 8453 + }, + "policies": { + "member_only": true, + "workspace_bound": true, + "transferable": false + } + } + ] +} +``` + +## `POST /marketplace/checkout/quote` + +Request: + +```json +{ + "wallet": "0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5", + "offer_id": "edut.crm.pro.annual", + "workspace_id": "workspace.work.acme" +} +``` + +Success (`200`): + +```json +{ + "quote_id": "cq_01HZZXFQ27ZP6MP0V2R9M6V3KX", + "wallet": "0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5", + "offer_id": "edut.crm.pro.annual", + "currency": "USDC", + "amount": "199.00", + "amount_atomic": "199000000", + "decimals": 6, + "policy_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "expires_at": "2026-02-17T07:44:30Z", + "tx": { + "to": "0x2222222222222222222222222222222222222222", + "data": "0xdeadbeef", + "value": "0x0" + } +} +``` + +Error (`403`): + +```json +{ + "error": "membership_required", + "message": "Active membership is required for checkout." +} +``` + +## `POST /marketplace/checkout/confirm` + +Request: + +```json +{ + "quote_id": "cq_01HZZXFQ27ZP6MP0V2R9M6V3KX", + "wallet": "0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5", + "offer_id": "edut.crm.pro.annual", + "tx_hash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "chain_id": 8453 +} +``` + +Success (`200`): + +```json +{ + "status": "entitlement_active", + "entitlement_id": "ent:8453:0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5:000001", + "offer_id": "edut.crm.pro.annual", + "wallet": "0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5", + "tx_hash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "policy_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "activated_at": "2026-02-17T07:46:02Z" +} +``` + +## `GET /marketplace/entitlements?wallet=...` + +Success (`200`): + +```json +{ + "entitlements": [ + { + "entitlement_id": "ent:8453:0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5:000001", + "offer_id": "edut.crm.pro.annual", + "wallet_address": "0x3ea6cbf98d23e2cf7b6f4f9bb1fb4f50b710f2d5", + "workspace_id": "workspace.work.acme", + "state": "active", + "policy_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "issued_at": "2026-02-17T07:46:02Z" + } + ] +} +``` diff --git a/docs/api/marketplace.openapi.yaml b/docs/api/marketplace.openapi.yaml new file mode 100644 index 0000000..6a6f1ec --- /dev/null +++ b/docs/api/marketplace.openapi.yaml @@ -0,0 +1,232 @@ +openapi: 3.0.3 +info: + title: EDUT Marketplace API + version: v1 + description: Membership-gated offer and entitlement commerce endpoints. +servers: + - url: https://api.edut.ai +paths: + /marketplace/offers: + get: + summary: List active offers + responses: + '200': + description: Offer list + content: + application/json: + schema: + type: object + required: [offers] + properties: + offers: + type: array + items: + $ref: '#/components/schemas/Offer' + /marketplace/offers/{offer_id}: + get: + summary: Get offer by id + parameters: + - in: path + name: offer_id + required: true + schema: + type: string + responses: + '200': + description: Offer record + content: + application/json: + schema: + $ref: '#/components/schemas/Offer' + '404': + description: Not found + /marketplace/checkout/quote: + post: + summary: Create checkout quote (membership required) + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutQuoteRequest' + responses: + '200': + description: Quote created + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutQuoteResponse' + '403': + description: Membership not active + /marketplace/checkout/confirm: + post: + summary: Confirm checkout transaction and mint entitlement + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutConfirmRequest' + responses: + '200': + description: Entitlement active + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutConfirmResponse' + /marketplace/entitlements: + get: + summary: List entitlements for wallet + parameters: + - in: query + name: wallet + required: true + schema: + type: string + pattern: '^0x[a-fA-F0-9]{40}$' + responses: + '200': + description: Entitlements list + content: + application/json: + schema: + type: object + required: [entitlements] + properties: + entitlements: + type: array + items: + $ref: '#/components/schemas/Entitlement' +components: + schemas: + Offer: + type: object + required: [offer_id, issuer_id, title, status, pricing, policies] + properties: + offer_id: + type: string + issuer_id: + type: string + title: + type: string + summary: + type: string + status: + type: string + enum: [draft, active, paused, retired] + pricing: + type: object + required: [currency, amount_atomic, decimals] + properties: + currency: + type: string + enum: [USDC, ETH] + amount_atomic: + type: string + decimals: + type: integer + chain_id: + type: integer + policies: + type: object + required: [member_only, workspace_bound, transferable] + properties: + member_only: + type: boolean + workspace_bound: + type: boolean + transferable: + type: boolean + CheckoutQuoteRequest: + type: object + required: [wallet, offer_id] + properties: + wallet: + type: string + pattern: '^0x[a-fA-F0-9]{40}$' + offer_id: + type: string + workspace_id: + type: string + CheckoutQuoteResponse: + type: object + required: [quote_id, wallet, offer_id, currency, amount_atomic, policy_hash, expires_at] + properties: + quote_id: + type: string + wallet: + type: string + offer_id: + type: string + currency: + type: string + amount: + type: string + amount_atomic: + type: string + decimals: + type: integer + policy_hash: + type: string + expires_at: + type: string + format: date-time + tx: + type: object + additionalProperties: true + CheckoutConfirmRequest: + type: object + required: [quote_id, wallet, offer_id, tx_hash, chain_id] + properties: + quote_id: + type: string + wallet: + type: string + pattern: '^0x[a-fA-F0-9]{40}$' + offer_id: + type: string + tx_hash: + type: string + pattern: '^0x[a-fA-F0-9]{64}$' + chain_id: + type: integer + CheckoutConfirmResponse: + type: object + required: [status, entitlement_id, offer_id, wallet, tx_hash] + properties: + status: + type: string + enum: [entitlement_active] + entitlement_id: + type: string + offer_id: + type: string + wallet: + type: string + tx_hash: + type: string + policy_hash: + type: string + activated_at: + type: string + format: date-time + Entitlement: + type: object + required: [entitlement_id, offer_id, wallet_address, state] + properties: + entitlement_id: + type: string + offer_id: + type: string + wallet_address: + type: string + workspace_id: + type: string + state: + type: string + enum: [active, suspended, revoked, expired] + policy_hash: + type: string + issued_at: + type: string + format: date-time diff --git a/docs/roadmap-status.md b/docs/roadmap-status.md index 4daa59a..7d262e0 100644 --- a/docs/roadmap-status.md +++ b/docs/roadmap-status.md @@ -39,6 +39,7 @@ Implemented now: 12. Deployment templates + invariants + chain operations runbook. 13. Issuer onboarding pack, migration policy, trust page spec, and integration mapping docs. 14. Public `/trust` page scaffold aligned with trust-page spec. +15. Dedicated marketplace OpenAPI contract and examples. Remaining in this repo: