feat(oracle): add PowAttestOracleClient for attest.powforge.dev#159
feat(oracle): add PowAttestOracleClient for attest.powforge.dev#159zekebuilds-lab wants to merge 5 commits into
Conversation
|
Update: Key types: |
|
Quick update:
The oracle nonce (R) returned by the 19 tests green on 0.3.0. Happy to share test patterns if useful. |
bennyhodl
left a comment
There was a problem hiding this comment.
Thanks for adding a new oracle 🎉
One comment for a utility
| /// and the 1-byte BigSize length prefix. `OracleAnnouncement::read` and | ||
| /// `OracleAttestation::read` expect only the payload, so the leading 4 bytes | ||
| /// are skipped here. | ||
| fn read_tlv_payload<T: Readable>(bytes: &[u8]) -> Result<T, lightning::ln::msgs::DecodeError> { |
There was a problem hiding this comment.
ddk-messages has a helper exactly for this
ddk_messages::ser_impls::read_as_tlv
There was a problem hiding this comment.
Done — replaced read_tlv_payload with ddk_messages::ser_impls::read_as_tlv across all three call sites (announcement, attestation, and the test). Removed the local helper entirely.
I also updated the struct-level doc to reference read_as_tlv now that the comment about the 4-byte skip is gone.
Replace local read_tlv_payload with the existing read_as_tlv helper from ddk-messages as requested by @bennyhodl. read_as_tlv reads BigSize type and BigSize length fields correctly regardless of payload size, where the previous implementation hardcoded a 4-byte skip.
|
Addressed the review — switched to |
Adds a fourth oracle implementation alongside
kormir,nostr, andp2p_derivatives:PowAttestOracleClient— a thin HTTP client for pow-attest,a PoW-gated Schnorr attestation oracle implementing the dlcspecs
OracleAnnouncement(type 55332) and
OracleAttestation(type 55400) TLV formats.Discussed in #158.
What this PR adds
ddk/src/oracle/pow_attest.rs—PowAttestOracleClientimplementingddk_manager::Oracleandcrate::Oracleddk/examples/pow_attest.rs— connects toattest.powforge.dev, fetches and prints a decoded announcementpow-attestfeature flag inddk/Cargo.toml(default off, mirrors thekormirflag pattern, reuses the existing optionalreqwestdep)[[example]]registration withrequired-features = ["pow-attest"]How it works
The oracle exposes binary TLV endpoints that match the dlcspecs format verbatim:
GET /api/v1/info— returnsoracle_pubkey(x-only, hex)GET /api/v1/bounty/{event_id}/announcement.tlv— fullOracleAnnouncementTLV wire bytesGET /api/v1/bounty/{event_id}/attestation.tlv— fullOracleAttestationTLV wire bytesThe response is the full TLV wire format (3-byte BigSize type prefix + 1-byte BigSize length prefix + payload).
OracleAnnouncement::read/OracleAttestation::readexpect only the payload, so theleading 4 bytes are skipped (
&bytes[4..]) before reading. There is a comment inread_tlv_payloadcalling out that, if message payloads ever grow past 252 bytes,the BigSize length prefix becomes multi-byte and the offset will need to follow the
BigSize rules in dlcspecs.
Round-trip verification
The included unit test
roundtrips_static_announcementdecodes a capturedannouncement.tlvblob (the static6ba7b810-9dad-11d1-80b4-00c04fd430c8bountykept on the pow-attest server for downstream testing) through
ddk_messages::oracle_msgs::OracleAnnouncement::readand asserts on theoracle_event.event_idandoracle_nonces.len(). This is the gate thatconfirms the server's TLV wire bytes are dlcspecs-compatible.
Use case
pow-attest signs
RELEASEDattestations when an external condition is met (e.g.a GitHub PR is merged, an issue closed, a "dead man's switch" deadline elapsed).
Combined with a DLC, this enables conditional release — for example, trustless
bug-bounty payouts: lock funds in a contract, oracle signs when the PR merges,
anyone can execute using the revealed Schnorr scalar.
Test vectors: https://attest.powforge.dev/test-vectors
Background: https://dev.to/zekebuilds/trustless-bug-bounty-releases-with-a-pow-gated-dlc-oracle-46f0
Notes for review
kormir.rsshape (HTTP client with optionalArc<Logger>, bothddk_manager::Oracleandcrate::Oracleimpls).pow-attestfeature reuses the existing optionalreqwestdep that already backskormirandp2pderivatives.attest.powforge.devover the public internet by default;POW_ATTEST_HOSTandEVENT_IDenv vars override.2bc7…a0e5) is stable; the test-vectors page gives deterministic anchor values for any future regression test.Happy to address any feedback on naming, error variants, the static fixture
format, or anything else.