Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
19ef8ff
feat: Implement Proof of Inclusion support in poi-rs module
itsyaasir Jul 2, 2026
8f3722e
feat: Add Proof of Inclusion support with verification and error hand…
itsyaasir Jul 3, 2026
40fd79a
Merge pull request #306 from iotaledger/feat/290-poi-proof-envelope-api
itsyaasir Jul 7, 2026
8e1d9c9
feat: Implement ProofVersion conversion and add verifier tests for tr…
itsyaasir Jul 7, 2026
6b7b0b7
test: Cover PoI verifier failure cases
itsyaasir Jul 7, 2026
66ce368
Merge pull request #307 from iotaledger/feat/291-poi-verifier-dispatch
itsyaasir Jul 7, 2026
f410224
feat: Add gRPC client support for Proof of Inclusion and enhance erro…
itsyaasir Jul 7, 2026
414b5ca
Merge pull request #308 from iotaledger/feat/292-poi-grpc-proof-const…
itsyaasir Jul 8, 2026
a9ba01b
feat: Add support for object proofs in source and enhance error handling
itsyaasir Jul 9, 2026
fd02c62
Merge pull request #309 from iotaledger/feat/293-poi-object-proof-sup…
itsyaasir Jul 9, 2026
477f15b
feat: Add support for event proofs in source and enhance related erro…
itsyaasir Jul 9, 2026
5f4a41c
Merge pull request #310 from iotaledger:feat/294-poi-event-proof-support
itsyaasir Jul 9, 2026
6dd9352
Merge branch 'main' into feat/poi-implementation
itsyaasir Jul 10, 2026
9827f43
feat: Implement committee resolution for checkpoint verification and …
itsyaasir Jul 10, 2026
043abeb
Merge branch 'feat/poi-implementation' into feat/295-poi-committee-re…
itsyaasir Jul 10, 2026
b9d3da5
Merge pull request #316 from iotaledger/feat/295-poi-committee-resolu…
itsyaasir Jul 10, 2026
c2a4621
refactor: Simplify error handling in GrpcSource implementation
itsyaasir Jul 10, 2026
3fa6e6e
feat: Add verified committee cache
itsyaasir Jul 13, 2026
7bcaae4
test: Cover committee cache behavior
itsyaasir Jul 13, 2026
7f7b5ba
refactor: Remove unused tests from committee cache module
itsyaasir Jul 13, 2026
c85eea5
refactor: Rename committee resolution mode
itsyaasir Jul 13, 2026
5176c43
Merge pull request #317 from iotaledger/feat/296-poi-committee-cache
itsyaasir Jul 13, 2026
7cc4d24
feat: Add golden tests for proof verification and include fixture data
itsyaasir Jul 13, 2026
62b543b
feat: Add dev-dependencies for iota-config and test-cluster; remove o…
itsyaasir Jul 13, 2026
27fd80b
feat: Implement ProofBuilder and related components for proof constru…
itsyaasir Jul 14, 2026
3a13e5c
feat: Enhance ProofBuilder to support stacking multiple object and ev…
itsyaasir Jul 14, 2026
2e1d26e
feat: Add chain identifier support in ProofBuilder and related tests
itsyaasir Jul 15, 2026
17f5840
Merge pull request #318 from iotaledger/feat/297-poi-golden-fixtures
itsyaasir Jul 16, 2026
7b60b9f
feat: Enhance Proof of Inclusion CLI and underlying logic
itsyaasir Jul 16, 2026
11fb1e0
feat: Refactor committee authentication logic and improve error handling
itsyaasir Jul 16, 2026
b98d8a4
feat: Update CLI command name and enhance dependencies for Proof of I…
itsyaasir Jul 20, 2026
a6dd16c
Merge pull request #320 from iotaledger/feat/poi/cli
itsyaasir Jul 20, 2026
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
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,33 @@ rust-version = "1.85"

[workspace]
resolver = "2"
members = ["audit-trail-rs", "examples", "notarization-rs"]
members = ["audit-trail-rs", "examples", "notarization-rs", "poi-rs"]
exclude = ["bindings/wasm/notarization_wasm", "bindings/wasm/audit_trail_wasm"]

[workspace.dependencies]
anyhow = "1.0"
async-trait = "0.1"
bcs = "0.1"
chrono = { version = "0.4", default-features = false }
clap = { version = "4.6.1", features = ["derive"] }
hyper = "1"
iota-grpc-client = { git = "https://github.com/iotaledger/iota-rust-sdk.git", package = "iota-sdk-grpc-client", rev = "36bffd625e1b1d38307eb9e49bd2cb7dd988bb11" }
iota-grpc-types = { git = "https://github.com/iotaledger/iota-rust-sdk.git", package = "iota-sdk-grpc-types", rev = "36bffd625e1b1d38307eb9e49bd2cb7dd988bb11" }
iota-sdk = { git = "https://github.com/iotaledger/iota.git", package = "iota-sdk", tag = "v1.26.1" }
iota-sdk-types = { git = "https://github.com/iotaledger/iota-rust-sdk.git", rev = "36bffd625e1b1d38307eb9e49bd2cb7dd988bb11", default-features = false }
iota-types = { git = "https://github.com/iotaledger/iota.git", tag = "v1.26.1" }
iota_interaction = { git = "https://github.com/iotaledger/product-core.git", tag = "v0.8.22", default-features = false, package = "iota_interaction" }
iota_interaction_rust = { git = "https://github.com/iotaledger/product-core.git", tag = "v0.8.22", default-features = false, package = "iota_interaction_rust" }
iota_interaction_ts = { git = "https://github.com/iotaledger/product-core.git", tag = "v0.8.22", default-features = false, package = "iota_interaction_ts" }
product_common = { git = "https://github.com/iotaledger/product-core.git", tag = "v0.8.22", default-features = false, package = "product_common" }
reqwest = { version = "0.12.28", default-features = false, features = ["rustls-tls"] }
secret-storage = { git = "https://github.com/iotaledger/secret-storage.git", tag = "v0.3.0", default-features = false }
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
serde-aux = { version = "4.7.0", default-features = false }
serde_json = { version = "1.0", default-features = false }
sha2 = { version = "0.10", default-features = false }
strum = { version = "0.27", default-features = false, features = ["std", "derive"] }
tempfile = "3.27.0"
thiserror = { version = "2.0", default-features = false }
tokio = { version = "1.52.2", default-features = false, features = ["macros", "sync", "rt", "process"] }

Expand Down
38 changes: 38 additions & 0 deletions poi-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "poi-rs"
version = "0.1.0-alpha"
authors.workspace = true
edition.workspace = true
homepage.workspace = true
keywords = ["iota", "proof", "inclusion", "notarization"]
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Proof of Inclusion support for the IOTA Notarization Toolkit."

[features]
cli = ["dep:anyhow", "dep:clap", "dep:iota-config", "dep:reqwest", "serde_json/std"]

[dependencies]
anyhow = { workspace = true, optional = true }
async-trait.workspace = true
clap = { workspace = true, optional = true }
iota-grpc-client.workspace = true
iota-grpc-types.workspace = true
iota-config = { git = "https://github.com/iotaledger/iota.git", tag = "v1.26.1", optional = true }
iota-sdk-types.workspace = true
iota-types.workspace = true
reqwest = { workspace = true, optional = true }
serde.workspace = true
serde_json = { workspace = true, features = ["alloc"] }
thiserror.workspace = true
tokio.workspace = true

[dev-dependencies]
iota-config = { git = "https://github.com/iotaledger/iota.git", tag = "v1.26.1" }
test-cluster = { git = "https://github.com/iotaledger/iota.git", tag = "v1.26.1", package = "test-cluster" }

[[bin]]
name = "poi"
path = "src/bin/poi.rs"
required-features = ["cli"]
86 changes: 86 additions & 0 deletions poi-rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# IOTA Proof of Inclusion Rust Package

The Proof of Inclusion Rust package provides proof data types and offline verification for inclusion claims in the IOTA
Notarization Toolkit.

Use Proof of Inclusion when a verifier needs cryptographic evidence that a transaction, event, or object state is tied to
a certified IOTA checkpoint. `ProofBuilder` fetches the proof material, while `ProofVerifier` verifies that material
locally without trusting the source that supplied it.

## Proof Construction

`ProofBuilder` provides explicit constructors for the public IOTA networks. The builder does not select a default network,
so the calling application always chooses where it fetches proof material.

```rust,no_run
use iota_types::digests::TransactionDigest;
use poi_rs::ProofBuilder;

# async fn example() -> Result<(), Box<dyn std::error::Error>> {
let transaction_digest: TransactionDigest = todo!();
let proof = ProofBuilder::mainnet()?
.transaction(transaction_digest)
.build()
.await?;
# Ok(())
# }
```

Use `ProofBuilder::testnet()` or `ProofBuilder::devnet()` for the other public networks. Applications can pass a custom
`Source` to `ProofBuilder::new(source)` when they use a private node, archive, fixture, or local test cluster.

A builder can stack multiple object and event targets by calling `object()` and `event()` repeatedly or by using the
`objects()` and `events()` batch methods. Every target must belong to the same transaction. The builder ignores exact
duplicates, and the source reuses one transaction proof and one set of checkpoint evidence for the complete target set.

Network selection configures only the proof source. It does not make the returned proof trusted or select an authoritative
committee for verification.

## Proof Model

A `Proof` contains three layers of evidence:

- A `CertifiedCheckpointSummary` signed by the committee for the checkpoint epoch.
- A `TransactionProof` containing the checkpoint contents, transaction, effects, and optional events.
- `ProofTargets` describing the object, event, or committee claims the caller wants to authenticate.

The transaction proof is required. A Proof of Inclusion proves inclusion in a certified checkpoint, so the proof envelope
must carry the transaction evidence that links the target claim to the checkpoint contents.

## Verification

`ProofVerifier` is the public verification entry point. It receives the authoritative committee for the proof checkpoint
and verifies only the proof material passed by the caller.

Verification checks:

- the proof format version is supported
- the checkpoint summary is certified by the supplied committee
- the checkpoint contents match the certified checkpoint summary
- the transaction digest matches the transaction effects
- the transaction effects are included in the checkpoint contents
- packaged events match the event digest recorded in the effects
- requested event targets belong to the transaction and match the packaged event contents
- requested object targets match their object references and appear in the transaction effects
- requested committee targets match the next committee recorded in an end-of-epoch checkpoint

## Trust Boundaries

`ProofVerifier` is intentionally offline. It does not make RPC calls and does not decide which committee is authoritative.
Callers must provide the committee that should certify the checkpoint. `CommitteeResolver` can resolve committee history
before the caller invokes the verifier.

The verifier treats all proof payloads as untrusted until verification succeeds. After verification succeeds, callers can
trust the authenticated target claims relative to the supplied committee.

## Main Types

- `Proof`: Versioned Proof of Inclusion envelope.
- `ProofVersion`: Proof format version used for compatibility checks.
- `TransactionProof`: Transaction, effects, events, and checkpoint contents used to prove inclusion.
- `ProofTargets`: Object, event, and committee claims to authenticate.
- `ProofBuilder`: Network-aware or custom-source proof construction.
- `Source`: Extensible boundary for gRPC nodes, archives, fixtures, and other proof sources.
- `CommitteeResolver`: Trusted-node or anchored committee resolution.
- `ProofVerifier`: Offline verifier for `Proof` values.
- `VerifyError`, `SourceError`, `SerializationError`, and `VersionError`: Operation-specific errors.
Loading
Loading