Reject a submitted milestone. Only the project owner may call this.
fn reject_milestone(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
milestone_id: soroban_sdk::String,
approver: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
Approve a submitted milestone. Only the project owner may call this.
fn approve_milestone(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
milestone_id: soroban_sdk::String,
approver: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
Register a project reference owned by owner.
Requires owner auth. Errors with [Error::ProjectExists] if the id is
taken — deliberately, rather than upserting, so a client can treat that
error as "already registered" and carry on.
fn create_project_ref(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
owner: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
Read the current record for a milestone.
Unauthenticated: an anchored hash is public by design, and that is what makes it evidence a third party can check.
fn get_milestone_status(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
milestone_id: soroban_sdk::String,
) -> Result
Attach a proof hash to a milestone and move it to [MilestoneStatus::Submitted].
Requires submitter auth. The milestone does not need to exist beforehand;
an unseen milestone is implicitly Proposed. A milestone that has already
been approved is terminal and cannot be re-submitted.
fn submit_milestone_proof(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
milestone_id: soroban_sdk::String,
submitter: soroban_sdk::Address,
proof_hash: soroban_sdk::BytesN<32>,
) -> Result<(), soroban_sdk::Error>
Hand a registered project to a new owner.
Both parties must sign. current_owner proves the right to give the
project away; new_owner proves the destination is an address someone
actually controls. Requiring only the first would let this function
recreate the exact problem it exists to solve — a project pinned to an
address nobody can sign for — and there is no admin path to undo that.
What this does and does not fix: it recovers a project registered to the
wrong but still controlled address, and it makes planned handovers
and key rotation possible. It cannot recover a lost key, because a
lost key cannot sign as current_owner. Nothing in this contract can;
that is the cost of having no admin address, and it is deliberate.
Milestone records are untouched. submitter is a historical fact about
who submitted, and approve/reject read the owner from storage at call
time, so they follow the new owner without any migration.
fn transfer_project_owner(
env: soroban_sdk::Env,
project_id: soroban_sdk::String,
current_owner: soroban_sdk::Address,
new_owner: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>