Skip to content
Draft
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = ["contracts/*"]
exclude = ["contracts/fixtures"]
resolver = "2"

[workspace.package]
Expand Down
21 changes: 21 additions & 0 deletions contracts/fixtures/events/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "prompt-contract-event-fixtures",
"version": "1.0.0",
"supportedEventTypes": ["publish", "purchase", "unlock"],
"supportedVersions": [1, 2],
"fixtures": {
"supported": [
{ "eventType": "publish", "version": 1, "path": "publish.v1.json" },
{ "eventType": "publish", "version": 2, "path": "publish.v2.json" },
{ "eventType": "purchase", "version": 1, "path": "purchase.v1.json" },
{ "eventType": "purchase", "version": 2, "path": "purchase.v2.json" },
{ "eventType": "unlock", "version": 1, "path": "unlock.v1.json" },
{ "eventType": "unlock", "version": 2, "path": "unlock.v2.json" }
],
"unsupported": [
{ "name": "unknown_topic", "path": "unsupported.unknown_topic.json" },
{ "name": "invalid_version", "path": "unsupported.invalid_version.json" },
{ "name": "malformed_payload", "path": "unsupported.malformed_payload.json" }
]
}
}
30 changes: 30 additions & 0 deletions contracts/fixtures/events/publish.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schemaVersion": 1,
"eventType": "publish",
"description": "V1 legacy contract publish event (PromptCreated) without metadata fields",
"rawEvent": {
"topic": ["PromptCreated", "1"],
"value": {
"prompt_id": 1,
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"price_stroops": 10000000,
"asset": "CB64D3G7SM2RTH6JSGG34DDTRHQAU2ZM4HI7J3AWGFFQ2SXZHOQUJZTM"
},
"ledger": 10001,
"transaction": "a1b2c3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "publish",
"version": 1,
"promptId": "1",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"priceStroops": "10000000",
"priceXlm": 1.0,
"asset": "CB64D3G7SM2RTH6JSGG34DDTRHQAU2ZM4HI7J3AWGFFQ2SXZHOQUJZTM",
"title": null,
"category": null,
"metadataUri": null,
"contentHash": null
}
}
35 changes: 35 additions & 0 deletions contracts/fixtures/events/publish.v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"schemaVersion": 2,
"eventType": "publish",
"description": "V2 contract publish event with explicit schema version, title, category, metadata URI, and content hash",
"rawEvent": {
"topic": ["PromptCreated", "1", "v2"],
"value": {
"schema_version": 2,
"prompt_id": 1,
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"price_stroops": 25000000,
"asset": "CB64D3G7SM2RTH6JSGG34DDTRHQAU2ZM4HI7J3AWGFFQ2SXZHOQUJZTM",
"title": "Advanced Quantum Agent Prompt",
"category": "AI Development",
"metadata_uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"content_hash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
},
"ledger": 10002,
"transaction": "b2c3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef01",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "publish",
"version": 2,
"promptId": "1",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"priceStroops": "25000000",
"priceXlm": 2.5,
"asset": "CB64D3G7SM2RTH6JSGG34DDTRHQAU2ZM4HI7J3AWGFFQ2SXZHOQUJZTM",
"title": "Advanced Quantum Agent Prompt",
"category": "AI Development",
"metadataUri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"contentHash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
}
}
32 changes: 32 additions & 0 deletions contracts/fixtures/events/purchase.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"schemaVersion": 1,
"eventType": "purchase",
"description": "V1 legacy contract purchase event (PromptPurchased) without referral fees or tx_hash metadata",
"rawEvent": {
"topic": ["PromptPurchased", "1"],
"value": {
"prompt_id": 1,
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"price_stroops": 10000000,
"referrer": null
},
"ledger": 10003,
"transaction": "c3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef0102",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "purchase",
"version": 1,
"promptId": "1",
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"priceStroops": "10000000",
"priceXlm": 1.0,
"referrer": null,
"referralFeeStroops": null,
"referralFeeXlm": null,
"txHash": "c3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef0102",
"versionIndex": 1
}
}
36 changes: 36 additions & 0 deletions contracts/fixtures/events/purchase.v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"schemaVersion": 2,
"eventType": "purchase",
"description": "V2 contract purchase event with explicit schema version, referral fee stroops, and version index",
"rawEvent": {
"topic": ["PromptPurchased", "1", "v2"],
"value": {
"schema_version": 2,
"prompt_id": 1,
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"price_stroops": 10000000,
"referrer": "GDRWKPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"referral_fee_stroops": 500000,
"tx_hash": "0xc3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef0102",
"version_index": 3
},
"ledger": 10004,
"transaction": "d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef010203",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "purchase",
"version": 2,
"promptId": "1",
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"creator": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"priceStroops": "10000000",
"priceXlm": 1.0,
"referrer": "GDRWKPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3IFOKIJWVSYY",
"referralFeeStroops": "500000",
"referralFeeXlm": 0.05,
"txHash": "0xc3d4e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef0102",
"versionIndex": 3
}
}
25 changes: 25 additions & 0 deletions contracts/fixtures/events/unlock.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"schemaVersion": 1,
"eventType": "unlock",
"description": "V1 contract unlock event (PromptUnlocked) containing prompt_id, buyer, and timestamp",
"rawEvent": {
"topic": ["PromptUnlocked", "1"],
"value": {
"prompt_id": 1,
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"timestamp": 1717000000
},
"ledger": 10005,
"transaction": "e5f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef01020304",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "unlock",
"version": 1,
"promptId": "1",
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"timestamp": 1717000000,
"requestId": null,
"clientSession": null
}
}
28 changes: 28 additions & 0 deletions contracts/fixtures/events/unlock.v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"schemaVersion": 2,
"eventType": "unlock",
"description": "V2 contract unlock event with explicit schema version, request_id, and client session metadata",
"rawEvent": {
"topic": ["PromptUnlocked", "1", "v2"],
"value": {
"schema_version": 2,
"prompt_id": 1,
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"timestamp": 1717000100,
"request_id": "req_unlock_9901",
"client_session": "sess_client_a99"
},
"ledger": 10006,
"transaction": "f60718293a4b5c6d7e8f901234567890abcdef1234567890abcdef0102030405",
"eventIndex": 0
},
"expectedCanonical": {
"eventType": "unlock",
"version": 2,
"promptId": "1",
"buyer": "GBZXN7PIRZGNMHGA7MUUUF4GWPY5AYPV6LY4UV2GL6VJGIQRXFDNMADI",
"timestamp": 1717000100,
"requestId": "req_unlock_9901",
"clientSession": "sess_client_a99"
}
}
19 changes: 19 additions & 0 deletions contracts/fixtures/events/unsupported.invalid_version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"description": "Event with an unsupported or unreleased schema version (v99) that consumers cannot safely decode",
"rawEvent": {
"topic": ["PromptCreated", "1", "v99"],
"value": {
"schema_version": 99,
"prompt_id": 1,
"future_field": "unsupported_data"
},
"ledger": 10008,
"transaction": "11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff",
"eventIndex": 0
},
"expectedDeadLetter": {
"reason": "UNSUPPORTED_VERSION",
"detectedVersion": "99",
"recoverable": true
}
}
17 changes: 17 additions & 0 deletions contracts/fixtures/events/unsupported.malformed_payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "Event with recognized topic and version but missing mandatory fields or invalid types",
"rawEvent": {
"topic": ["PromptCreated", "1"],
"value": {
"prompt_id": 1,
"price_stroops": -500
},
"ledger": 10009,
"transaction": "3344556677889900aabbccddeeff11223344556677889900aabbccddeeff1122",
"eventIndex": 0
},
"expectedDeadLetter": {
"reason": "SCHEMA_VALIDATION_FAILED",
"recoverable": false
}
}
17 changes: 17 additions & 0 deletions contracts/fixtures/events/unsupported.unknown_topic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "Event with unrecognized event topic that cannot be mapped to any known event handler",
"rawEvent": {
"topic": ["PromptUnknownTopicEvent", "1"],
"value": {
"prompt_id": 1,
"data": "some_random_payload"
},
"ledger": 10007,
"transaction": "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
"eventIndex": 0
},
"expectedDeadLetter": {
"reason": "UNKNOWN_EVENT_TYPE",
"recoverable": false
}
}
9 changes: 9 additions & 0 deletions contracts/prompt-hash/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,15 @@ impl PromptHashTrait for PromptHashContract {
}
}

fn unlock_prompt(env: Env, buyer: Address, prompt_id: u64) -> Result<(), Error> {
buyer.require_auth();
if !Self::has_access(env.clone(), buyer.clone(), prompt_id)? {
return Err(Error::Unauthorized);
}
Events::emit_prompt_unlocked(&env, prompt_id, buyer, env.ledger().timestamp());
Ok(())
}

fn get_prompt(env: Env, prompt_id: u64) -> Result<Prompt, Error> {
Storage::require_prompt(&env, prompt_id)
}
Expand Down
17 changes: 17 additions & 0 deletions contracts/prompt-hash/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,15 @@ impl Events {
pub fn emit_dispute_appealed(env: &Env, prompt_id: u64, buyer: Address) {
DisputeAppealed { prompt_id, buyer }.publish(env);
}

pub fn emit_prompt_unlocked(env: &Env, prompt_id: u64, buyer: Address, timestamp: u64) {
PromptUnlocked {
prompt_id,
buyer,
timestamp,
}
.publish(env);
}
}

#[contractevent]
Expand Down Expand Up @@ -558,3 +567,11 @@ pub struct DisputeAppealed {
pub prompt_id: u64,
pub buyer: Address,
}

#[contractevent]
pub struct PromptUnlocked {
#[topic]
pub prompt_id: u64,
pub buyer: Address,
pub timestamp: u64,
}
Loading