Add marketplace OpenAPI contract and example payloads
This commit is contained in:
parent
6158460b8c
commit
65744ef700
@ -58,8 +58,10 @@ docs/
|
|||||||
environment-invariants.md
|
environment-invariants.md
|
||||||
api/
|
api/
|
||||||
secret-system.openapi.yaml
|
secret-system.openapi.yaml
|
||||||
|
marketplace.openapi.yaml
|
||||||
examples/
|
examples/
|
||||||
secret-system.examples.md
|
secret-system.examples.md
|
||||||
|
marketplace.examples.md
|
||||||
handoff/
|
handoff/
|
||||||
membership-backend-checklist.md
|
membership-backend-checklist.md
|
||||||
schemas/
|
schemas/
|
||||||
|
|||||||
120
docs/api/examples/marketplace.examples.md
Normal file
120
docs/api/examples/marketplace.examples.md
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
232
docs/api/marketplace.openapi.yaml
Normal file
232
docs/api/marketplace.openapi.yaml
Normal file
@ -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
|
||||||
@ -39,6 +39,7 @@ Implemented now:
|
|||||||
12. Deployment templates + invariants + chain operations runbook.
|
12. Deployment templates + invariants + chain operations runbook.
|
||||||
13. Issuer onboarding pack, migration policy, trust page spec, and integration mapping docs.
|
13. Issuer onboarding pack, migration policy, trust page spec, and integration mapping docs.
|
||||||
14. Public `/trust` page scaffold aligned with trust-page spec.
|
14. Public `/trust` page scaffold aligned with trust-page spec.
|
||||||
|
15. Dedicated marketplace OpenAPI contract and examples.
|
||||||
|
|
||||||
Remaining in this repo:
|
Remaining in this repo:
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user