120 unique, contributor-ready GitHub issues for the StarInvoice project.
Labels: feature, good first issue, core
Description:
The fund_invoice function is currently stubbed with a todo!() macro. This is the second step in the escrow flow and must be implemented before any downstream functions can work.
Acceptance Criteria:
- Verify the caller is the invoice's
clientfield usingrequire_auth() - Load the invoice by
invoice_idand assert its status isPending - Transfer
amounttokens from the client to the contract address using the Soroban token interface - Update the invoice status to
Funded - Emit the
fund_invoiceevent viaevents.rs - Add at least one passing test covering the happy path
References: contracts/invoice/src/lib.rs — fund_invoice
Labels: feature, good first issue, core
Description:
The mark_delivered function is stubbed. The freelancer must be able to signal that work is complete so the client can review and approve.
Acceptance Criteria:
- Verify the caller is the invoice's
freelancerusingrequire_auth() - Assert invoice status is
Funded - Update status to
Delivered - Emit the
mark_deliveredevent - Add tests for both the happy path and invalid-state transitions
References: contracts/invoice/src/lib.rs — mark_delivered
Labels: feature, good first issue, core
Description:
The approve_payment function is stubbed. The client must be able to approve delivered work before funds are released.
Acceptance Criteria:
- Verify the caller is the invoice's
clientusingrequire_auth() - Assert invoice status is
Delivered - Update status to
Approved - Emit the
approve_paymentevent - Add tests covering happy path and wrong-caller scenarios
References: contracts/invoice/src/lib.rs — approve_payment
Labels: feature, good first issue, core
Description:
The release_payment function is stubbed. This is the final step — transferring escrowed funds to the freelancer.
Acceptance Criteria:
- Assert invoice status is
Approved - Transfer escrowed tokens from the contract to the
freelanceraddress - Update status to
Completed - Emit the
release_paymentevent - Add tests verifying the token balance changes correctly
References: contracts/invoice/src/lib.rs — release_payment
Labels: feature, good first issue, core
Description:
The InvoiceStatus enum has a TODO comment suggesting Disputed and Cancelled states. These are important for real-world escrow flows.
Acceptance Criteria:
- Add
Disputedvariant — reachable fromFundedorDelivered - Add
Cancelledvariant — reachable fromPendingorFunded - Document valid state transitions in a comment or diagram
- Update any match expressions that need exhaustive handling
References: contracts/invoice/src/storage.rs — InvoiceStatus
Labels: feature, enhancement
Description:
Currently the Invoice struct has no token field, meaning the contract implicitly assumes a single token. Adding a token: Address field enables clients and freelancers to agree on any Stellar asset.
Acceptance Criteria:
- Add
token: Addressto theInvoicestruct - Pass
tokenas a parameter tocreate_invoice - Use
tokenwhen performing transfers infund_invoiceandrelease_payment - Update tests to supply a mock token address
References: contracts/invoice/src/storage.rs — Invoice TODO comment
Labels: feature, enhancement
Description:
Invoices should support an optional expiry/deadline so clients and freelancers have time-bound agreements. Soroban provides env.ledger().timestamp() for on-chain time.
Acceptance Criteria:
- Add
deadline: u64(Unix timestamp) toInvoice - Pass
deadlineas a parameter tocreate_invoice - In
fund_invoice, reject funding ifenv.ledger().timestamp() > deadline - Add tests for expired and non-expired invoices
References: contracts/invoice/src/storage.rs — Invoice TODO comment
Labels: feature, enhancement
Description:
Recording when an invoice was created helps with auditing and off-chain indexing. Use env.ledger().timestamp() at creation time.
Acceptance Criteria:
- Add
created_at: u64toInvoice - Populate it in
create_invoiceusingenv.ledger().timestamp() - No user-supplied input — always set by the contract
Labels: feature, enhancement
Description:
The current description field serves as the only human-readable label. A short title field would improve UX for frontends and indexers.
Acceptance Criteria:
- Add
title: StringtoInvoice - Accept
titleas a parameter increate_invoice - Keep
descriptionfor longer free-text content
Labels: feature, enhancement
Description:
There is no public way to query how many invoices exist. A invoice_count function would help frontends and indexers.
Acceptance Criteria:
- Add
pub fn invoice_count(env: Env) -> u64toInvoiceContract - Return the current value of
DataKey::InvoiceCount - Add a test verifying the count increments correctly
Labels: feature, enhancement
Description:
storage::get_invoice is a private helper. There is no public contract function to fetch an invoice by ID. Frontends and other contracts need this.
Acceptance Criteria:
- Add
pub fn get_invoice(env: Env, invoice_id: u64) -> InvoicetoInvoiceContract - Return the full
Invoicestruct - Add a test that creates an invoice and retrieves it via the public function
Labels: feature, refactor, error-handling
Description:
storage::get_invoice currently calls .expect("Invoice not found") which panics. Soroban contracts should use Result or a custom error enum for graceful error handling.
Acceptance Criteria:
- Define a
ContractErrorenum with at leastInvoiceNotFoundvariant - Change
get_invoiceto returnResult<Invoice, ContractError> - Propagate errors up through all callers
- Add a test that verifies the error is returned for a missing ID
Labels: feature, enhancement
Description:
There is no way to cancel an invoice once created. A cancel_invoice function would allow the freelancer or client to void a Pending invoice.
Acceptance Criteria:
- Add
pub fn cancel_invoice(env: Env, invoice_id: u64) - Allow cancellation only from
Pendingstatus - Require auth from either
freelancerorclient - Update status to
Cancelled(requires issue #5) - Emit a
cancelledevent - Add tests
Labels: feature, enhancement
Description:
Either party should be able to raise a dispute if there is a disagreement. This requires the Disputed status from issue #5.
Acceptance Criteria:
- Add
pub fn dispute_invoice(env: Env, invoice_id: u64) - Allow disputes from
FundedorDeliveredstatus - Require auth from either
freelancerorclient - Update status to
Disputed - Emit a
disputedevent - Add tests
Labels: feature, enhancement
Description: When an invoice is cancelled after funding, or a dispute is resolved in the client's favor, escrowed funds should be returnable to the client.
Acceptance Criteria:
- Add
pub fn refund_client(env: Env, invoice_id: u64) - Only callable when status is
Cancelled(post-funding) orDisputed - Transfer escrowed tokens back to
client - Update status to
Completedor a newRefundedvariant - Emit a
refundedevent - Add tests
Labels: feature, good first issue
Description:
events.rs has a TODO to add emitters for all state transitions. This issue covers the fund_invoice event.
Acceptance Criteria:
- Add
pub fn invoice_funded(env: &Env, invoice_id: u64, client: &Address, amount: i128)toevents.rs - Publish with topic
("INVOICE", "funded") - Call it from
fund_invoiceinlib.rs
References: contracts/invoice/src/events.rs — TODO comment
Labels: feature, good first issue
Description:
Add the event emitter for the mark_delivered state transition.
Acceptance Criteria:
- Add
pub fn invoice_delivered(env: &Env, invoice_id: u64, freelancer: &Address)toevents.rs - Publish with topic
("INVOICE", "delivered") - Call it from
mark_deliveredinlib.rs
Labels: feature, good first issue
Description:
Add the event emitter for the approve_payment state transition.
Acceptance Criteria:
- Add
pub fn invoice_approved(env: &Env, invoice_id: u64, client: &Address)toevents.rs - Publish with topic
("INVOICE", "approved") - Call it from
approve_paymentinlib.rs
Labels: feature, good first issue
Description:
Add the event emitter for the release_payment state transition.
Acceptance Criteria:
- Add
pub fn invoice_released(env: &Env, invoice_id: u64, freelancer: &Address, amount: i128)toevents.rs - Publish with topic
("INVOICE", "released") - Call it from
release_paymentinlib.rs
Labels: feature, enhancement
Description: Add an event emitter for invoice cancellation (depends on issue #13).
Acceptance Criteria:
- Add
pub fn invoice_cancelled(env: &Env, invoice_id: u64, cancelled_by: &Address) - Publish with topic
("INVOICE", "cancelled")
Labels: feature, enhancement
Description: Add an event emitter for invoice disputes (depends on issue #14).
Acceptance Criteria:
- Add
pub fn invoice_disputed(env: &Env, invoice_id: u64, raised_by: &Address) - Publish with topic
("INVOICE", "disputed")
Labels: feature, enhancement
Description: Add an event emitter for client refunds (depends on issue #15).
Acceptance Criteria:
- Add
pub fn invoice_refunded(env: &Env, invoice_id: u64, client: &Address, amount: i128) - Publish with topic
("INVOICE", "refunded")
Labels: refactor
Description:
InvoiceCount uses instance storage while Invoice records use persistent storage. This inconsistency could cause issues if the contract instance is upgraded. Evaluate and standardize storage type usage.
Acceptance Criteria:
- Document the rationale for each storage type used (
instancevspersistentvstemporary) - Migrate
InvoiceCounttopersistentif appropriate - Add a comment explaining the choice
Labels: feature, enhancement
Description: Soroban persistent storage entries expire unless their TTL is extended. The contract should extend TTL on every read/write to prevent invoice data from being evicted.
Acceptance Criteria:
- Call
env.storage().persistent().extend_ttl(key, threshold, extend_to)after everysave_invoiceandget_invoice - Choose sensible TTL values and document them as constants
- Add a test that verifies TTL extension is called
Labels: feature, refactor
Description:
Currently there is no way to check if an invoice exists without panicking. A has_invoice helper would allow safe existence checks.
Acceptance Criteria:
- Add
pub fn has_invoice(env: &Env, invoice_id: u64) -> booltostorage.rs - Use it in
get_invoiceto return aResultinstead of panicking (see issue #12)
Labels: refactor
Description: Status transition checks (e.g., "must be Funded to mark delivered") are currently inline in each function. Centralizing this logic reduces duplication and makes transitions easier to audit.
Acceptance Criteria:
- Add a
validate_transition(from: &InvoiceStatus, to: &InvoiceStatus) -> boolfunction - Use it in all state-changing contract functions
- Add unit tests for valid and invalid transitions
Labels: refactor, feature
Description: Each function that changes invoice status loads, mutates, and saves the invoice inline. A dedicated helper would reduce boilerplate.
Acceptance Criteria:
- Add
pub fn update_invoice_status(env: &Env, invoice_id: u64, new_status: InvoiceStatus) - Use it in all state-changing functions
- Ensure it calls
save_invoiceinternally
Labels: feature, enhancement
Description:
There is no way to look up all invoices for a given freelancer. An index mapping Address -> Vec<u64> would enable this.
Acceptance Criteria:
- Add
DataKey::InvoicesByFreelancer(Address)variant - Update
save_invoiceto append the invoice ID to the freelancer's list - Add
pub fn get_invoices_by_freelancer(env: &Env, freelancer: &Address) -> Vec<u64> - Add tests
Labels: feature, enhancement
Description: Similar to issue #28, add an index for looking up invoices by client address.
Acceptance Criteria:
- Add
DataKey::InvoicesByClient(Address)variant - Update
save_invoiceto append the invoice ID to the client's list - Add
pub fn get_invoices_by_client(env: &Env, client: &Address) -> Vec<u64> - Add tests
Labels: bug, security
Description:
next_invoice_id reads the count, increments it, and writes it back in two separate storage operations. While Soroban transactions are atomic per-transaction, document whether this is safe and add a comment explaining the guarantee.
Acceptance Criteria:
- Add a comment in
next_invoice_idexplaining Soroban's transaction atomicity model - If any risk exists, refactor to a single atomic operation
- Add a test that creates multiple invoices and verifies unique IDs
Labels: feature, bug
Description:
create_invoice accepts any i128 value for amount, including zero and negative numbers. These should be rejected.
Acceptance Criteria:
- Assert
amount > 0at the start ofcreate_invoice - Return or panic with a descriptive error for invalid amounts
- Add tests for zero and negative amounts
Labels: feature, enhancement
Description:
There is no limit on the description field length. Very long descriptions waste on-chain storage. Add a maximum length check.
Acceptance Criteria:
- Define a
MAX_DESCRIPTION_LENconstant (e.g., 256 bytes) - Validate
description.len() <= MAX_DESCRIPTION_LENincreate_invoice - Add tests for boundary values
Labels: test, good first issue
Description:
Once fund_invoice is implemented (issue #1), add a comprehensive test covering the happy path: client funds a pending invoice and status becomes Funded.
Acceptance Criteria:
- Mock token contract and client auth
- Assert invoice status is
Fundedafter the call - Assert token balances changed correctly
Labels: test, good first issue
Description:
Add tests for mark_delivered once implemented (issue #2).
Acceptance Criteria:
- Start from a
Fundedinvoice - Assert status becomes
Deliveredafter the call - Assert the correct event was emitted
Labels: test, good first issue
Description:
Add tests for approve_payment once implemented (issue #3).
Acceptance Criteria:
- Start from a
Deliveredinvoice - Assert status becomes
Approved - Assert the correct event was emitted
Labels: test, good first issue
Description:
Add tests for release_payment once implemented (issue #4).
Acceptance Criteria:
- Start from an
Approvedinvoice - Assert status becomes
Completed - Assert freelancer received the correct token amount
Labels: test, security
Description: Each function that requires auth should be tested with the wrong caller to ensure unauthorized access is rejected.
Acceptance Criteria:
- Test
fund_invoicecalled by the freelancer (should fail) - Test
mark_deliveredcalled by the client (should fail) - Test
approve_paymentcalled by the freelancer (should fail) - Each test should assert the call panics or returns an auth error
Labels: test
Description: Each state-changing function should reject calls when the invoice is in the wrong state.
Acceptance Criteria:
- Test
fund_invoiceon an already-Fundedinvoice - Test
mark_deliveredon aPendinginvoice - Test
approve_paymenton aFunded(not yet delivered) invoice - Test
release_paymenton aDelivered(not yet approved) invoice
Labels: test
Description:
Add a single integration test that walks through the entire flow: create_invoice → fund_invoice → mark_delivered → approve_payment → release_payment.
Acceptance Criteria:
- Single test function covering all five steps
- Assert status at each step
- Assert final token balances
Labels: test, bug
Description: Verify that creating multiple invoices always produces unique, incrementing IDs.
Acceptance Criteria:
- Create 10 invoices in a loop
- Assert each has a unique ID from 0 to 9
Labels: test, bug
Description: Verify that fetching a non-existent invoice ID returns an error rather than panicking unexpectedly (depends on issue #12).
Acceptance Criteria:
- Call
get_invoicewith an ID that was never created - Assert the expected error variant is returned
Labels: test
Description:
Add tests for the cancel_invoice function once implemented.
Acceptance Criteria:
- Test cancellation from
Pendingstatus by freelancer - Test cancellation from
Pendingstatus by client - Test that cancellation from
Fundedis rejected (or allowed, per spec)
Labels: test
Description:
Add tests for the dispute_invoice function once implemented.
Acceptance Criteria:
- Test dispute from
FundedandDeliveredstates - Test that dispute from
Pendingis rejected
Labels: test
Description:
Once the deadline field is added, verify that fund_invoice rejects funding after the deadline.
Acceptance Criteria:
- Create an invoice with a past deadline
- Assert
fund_invoicefails with an expiry error
Labels: test
Description:
Verify that create_invoice rejects invalid amounts.
Acceptance Criteria:
- Test with
amount = 0— should fail - Test with
amount = -100— should fail - Test with
amount = 1— should succeed
Labels: docs, good first issue
Description:
The README has a status table showing which functions are implemented. Once fund_invoice is complete, update the table.
Acceptance Criteria:
- Change
fund_invoicerow from🚧 TODOto✅ Implemented - This issue should be closed as part of the PR for issue #1
Labels: docs, good first issue
Description:
Update the README status table once mark_delivered is complete (issue #2).
Acceptance Criteria:
- Change
mark_deliveredrow from🚧 TODOto✅ Implemented
Labels: docs, good first issue
Description:
Update the README status table once approve_payment is complete (issue #3).
Labels: docs, good first issue
Description:
Update the README status table once release_payment is complete (issue #4).
Labels: docs, enhancement
Description:
The contract flow is described as a linear sequence, but the actual state machine (including Disputed, Cancelled) is more complex. A diagram would help contributors understand valid transitions.
Acceptance Criteria:
- Add a Mermaid state diagram to README showing all
InvoiceStatustransitions - Include
DisputedandCancelledstates (depends on issue #5)
Labels: docs, good first issue
Description:
create_invoice has a doc comment but the stub functions only have TODO comments. Once implemented, all public functions should have proper /// doc comments.
Acceptance Criteria:
- Add
///doc comments tofund_invoice,mark_delivered,approve_payment,release_payment - Document parameters, return values, and error conditions
- Run
cargo docand verify no warnings
Labels: docs, good first issue
Description:
storage.rs functions lack doc comments. Add /// comments to all public functions.
Acceptance Criteria:
- Document
next_invoice_id,save_invoice,get_invoice - Document the
Invoicestruct fields - Document the
InvoiceStatusvariants
Labels: docs, good first issue
Description:
events.rs has one function with no doc comment. Add /// comments to all event emitters.
Acceptance Criteria:
- Document
invoice_createdand all future event functions - Describe the event topic and data payload
Labels: docs, enhancement
Description: The README describes the contract flow but not the overall architecture (Soroban, Stellar token interface, storage model). A brief architecture section would help new contributors.
Acceptance Criteria:
- Add an "Architecture" section to README
- Explain the role of
lib.rs,storage.rs, andevents.rs - Briefly describe how Soroban token transfers work
Labels: docs, security
Description: Open-source smart contract projects should have a security policy so researchers know how to report vulnerabilities.
Acceptance Criteria:
- Create
SECURITY.mdat the repo root - Include contact method for reporting vulnerabilities
- Include scope (what is in/out of scope)
- Reference GitHub's security advisory feature
Labels: docs
Description: A changelog helps users and contributors track what changed between versions.
Acceptance Criteria:
- Create
CHANGELOG.mdfollowing Keep a Changelog format - Add an
[Unreleased]section listing current TODOs - Add a
[0.1.0]section for the initialcreate_invoiceimplementation
Labels: docs, community
Description: A code of conduct sets expectations for community behavior and is standard for open-source projects.
Acceptance Criteria:
- Add
CODE_OF_CONDUCT.mdusing the Contributor Covenant template - Reference it from
CONTRIBUTING.md
Labels: docs, enhancement
Description:
Contributors implementing fund_invoice and release_payment need to understand how to call the Soroban token interface. Add a section or comment explaining this.
Acceptance Criteria:
- Add a comment block in
lib.rsor adocs/token-interface.mdfile - Show a minimal example of calling
token::Client::new(&env, &token_address).transfer(...)
Labels: tooling, good first issue
Description:
Contributors currently need to remember multiple cargo commands. A Makefile would simplify the workflow.
Acceptance Criteria:
- Add
Makefilewith targets:build,test,fmt,lint,clean buildcompiles towasm32-unknown-unknown --releaselintrunscargo clippy -- -D warnings- Document targets in
CONTRIBUTING.md
Labels: tooling, ci
Description: There is no CI pipeline. A GitHub Actions workflow should run on every PR to catch regressions.
Acceptance Criteria:
- Create
.github/workflows/ci.yml - Run
cargo fmt --check,cargo clippy, andcargo teston push and PR - Target
ubuntu-latestwith the stable Rust toolchain - Cache
~/.cargofor faster runs
Labels: tooling, ci
Description: The contract must compile to WASM. CI should verify this, not just native compilation.
Acceptance Criteria:
- Add a CI step that runs
cargo build --target wasm32-unknown-unknown --release - Ensure the
wasm32-unknown-unknowntarget is installed in the CI environment
Labels: tooling, community
Description: Structured issue templates help contributors file better bug reports.
Acceptance Criteria:
- Create
.github/ISSUE_TEMPLATE/bug_report.md - Include fields: description, steps to reproduce, expected behavior, actual behavior, environment
Labels: tooling, community
Description: Add a feature request issue template.
Acceptance Criteria:
- Create
.github/ISSUE_TEMPLATE/feature_request.md - Include fields: problem statement, proposed solution, alternatives considered
Labels: tooling, community
Description: A PR template ensures contributors include necessary information when opening pull requests.
Acceptance Criteria:
- Create
.github/pull_request_template.md - Include: description, related issue, testing done, checklist (fmt, clippy, tests pass)
Labels: tooling
Description:
A rustfmt.toml ensures consistent formatting across all contributors' environments.
Acceptance Criteria:
- Create
rustfmt.tomlat the repo root - Set at minimum:
edition = "2021",max_width = 100 - Document in
CONTRIBUTING.mdthatcargo fmtmust pass before merging
Labels: tooling
Description: Configuring Clippy ensures consistent lint rules across contributors.
Acceptance Criteria:
- Create
clippy.tomlor add[lints.clippy]toCargo.toml - Enable
pedanticlints or document which lints are explicitly allowed - Ensure CI runs
cargo clippy -- -D warnings
Labels: tooling, good first issue
Description:
An .editorconfig file ensures consistent indentation and line endings across editors.
Acceptance Criteria:
- Create
.editorconfigat the repo root - Set:
indent_style = space,indent_size = 4,end_of_line = lf,charset = utf-8
Labels: tooling, security, ci
Description:
cargo-audit checks dependencies against the RustSec advisory database. This should run in CI.
Acceptance Criteria:
- Add a CI job that installs and runs
cargo audit - Fail the build on any high-severity advisories
- Document how to run it locally in
CONTRIBUTING.md
Labels: tooling
Description: Without a pinned toolchain, different contributors may use different Rust versions, causing inconsistent behavior.
Acceptance Criteria:
- Create
rust-toolchain.tomlspecifying the stable channel and version - Add
wasm32-unknown-unknownas a required target component
Labels: tooling, security
Description:
cargo-deny can enforce allowed licenses and ban specific crates. Useful for a project that may be used in production.
Acceptance Criteria:
- Add
deny.tomlconfiguration - Configure allowed licenses (e.g., MIT, Apache-2.0)
- Add a CI step running
cargo deny check
Labels: tooling, ci
Description: When a version tag is pushed, CI should build the WASM artifact and attach it to a GitHub Release.
Acceptance Criteria:
- Create
.github/workflows/release.yml - Trigger on
v*tags - Build
--target wasm32-unknown-unknown --release - Upload the
.wasmfile as a release asset
Labels: tooling, enhancement
Description:
The Soroban CLI includes a contract optimize command that shrinks WASM binary size. This should be part of the build process.
Acceptance Criteria:
- Add
soroban contract optimizeto theMakefilebuildtarget - Document the command in README under "Build"
- Add it to the CI release workflow (issue #71)
Labels: security, bug
Description:
If fund_invoice does not strictly check the Pending status, a client could fund the same invoice twice, locking double the tokens in escrow.
Acceptance Criteria:
- Add an explicit status check at the start of
fund_invoice - Add a test that calls
fund_invoicetwice and asserts the second call fails
Labels: security, bug
Description:
release_payment must only execute when status is Approved. Verify this check is enforced and cannot be bypassed.
Acceptance Criteria:
- Add a test calling
release_paymenton aDelivered(not yet approved) invoice - Assert the call fails with the correct error
Labels: security, docs
Description:
Soroban's execution model prevents traditional reentrancy, but contributors should understand why. Add a comment in fund_invoice and release_payment explaining Soroban's reentrancy guarantees.
Acceptance Criteria:
- Add a
// SAFETY:comment near each token transfer call - Reference the Soroban documentation on cross-contract call semantics
Labels: security, bug
Description:
Creating an invoice where client == freelancer is nonsensical and could lead to unexpected behavior. Add a validation check.
Acceptance Criteria:
- Assert
freelancer != clientincreate_invoice - Add a test verifying this check
Labels: security, bug
Description:
amount is i128. While Soroban enables overflow checks in release builds (via overflow-checks = true in Cargo.toml), document this explicitly and add a test with a very large amount.
Acceptance Criteria:
- Add a comment referencing
overflow-checks = trueinCargo.toml - Add a test with
amount = i128::MAXto verify behavior
Labels: security
Description:
Every function that modifies state on behalf of a user must call require_auth(). Audit all functions and document which address is being authenticated and why.
Acceptance Criteria:
- Review all state-changing functions
- Add a comment above each
require_auth()call explaining which role is being verified - Open follow-up issues for any missing auth checks
Labels: security, bug
Description:
Soroban Address types cannot be zero in practice, but document this assumption and add a note for future contributors.
Acceptance Criteria:
- Add a comment in
create_invoicenoting thatAddressis always a valid account - Reference Soroban's address validation guarantees
Labels: security, enhancement
Description: Very large invoice amounts could be used to lock significant funds. Consider adding a configurable maximum.
Acceptance Criteria:
- Define
MAX_INVOICE_AMOUNT: i128constant - Validate
amount <= MAX_INVOICE_AMOUNTincreate_invoice - Add tests for boundary values
#81 — [security] Ensure token address in fund_invoice matches the invoice's token field (depends on #6)
Labels: security, bug
Description:
Once multi-token support is added (issue #6), fund_invoice must verify the token being transferred matches the token recorded on the invoice.
Acceptance Criteria:
- Add a check that the token used in the transfer matches
invoice.token - Add a test attempting to fund with a different token
Labels: security, feature
Description: When a dispute is raised, there needs to be a mechanism for resolution. An admin or arbitrator address should be able to resolve disputes.
Acceptance Criteria:
- Add an
admin: Addressfield stored in contract instance storage - Add
set_adminfunction callable only by the current admin - Add
resolve_dispute(invoice_id, winner: Address)callable only by admin - Add tests
Labels: security, feature
Description:
The contract has no initialization function. An initialize function should set the admin address and prevent re-initialization.
Acceptance Criteria:
- Add
pub fn initialize(env: Env, admin: Address) - Store admin in instance storage
- Panic if already initialized
- Add tests for initialization and re-initialization attempt
Labels: refactor
Description:
todo!() and unimplemented!() both panic, but todo!() signals "not yet done" while unimplemented!() signals "not planned." Once functions are implemented, ensure no todo!() macros remain.
Acceptance Criteria:
- Search for all
todo!()calls in the codebase - Replace each with a proper implementation or a
ContractError(see issue #12) - Add a CI lint step that fails if any
todo!()remains in non-test code
Labels: refactor
Description: As constants are added (max amount, max description length, TTL values), they should live in a dedicated module rather than scattered across files.
Acceptance Criteria:
- Create
contracts/invoice/src/constants.rs - Move all constants there
- Import them where needed
Labels: refactor
Description:
As the contract grows, lib.rs will become large. Consider splitting into logical modules (e.g., escrow.rs, views.rs).
Acceptance Criteria:
- Evaluate whether splitting is warranted after all core functions are implemented
- If yes, create separate files and re-export from
lib.rs - Ensure all tests still pass
Labels: refactor
Description:
The stub functions use _env and _invoice_id prefixed with _ to suppress dead code warnings. Once implemented, remove the underscores.
Acceptance Criteria:
- After each function is implemented, rename
_env→envand_invoice_id→invoice_id - Ensure no unused variable warnings remain
Labels: refactor, best-practice
Description:
Soroban provides panic_with_error! which encodes error codes into the contract's return value, making errors inspectable off-chain. Replace raw panic! calls.
Acceptance Criteria:
- Define a
#[contracterror]enum - Replace all
panic!and.expect()calls withpanic_with_error! - Add tests that verify the correct error code is returned
Labels: refactor, best-practice
Description:
Soroban supports contractmeta! for embedding metadata in the WASM binary. This helps tools and explorers identify the contract.
Acceptance Criteria:
- Add
soroban_sdk::contractmeta!(key = "Description", val = "StarInvoice escrow contract") - Add
soroban_sdk::contractmeta!(key = "Version", val = "0.1.0")
Labels: refactor
Description:
lib.rs re-exports Invoice from storage. Evaluate whether this is needed for the public contract interface or if it can be removed.
Acceptance Criteria:
- Check if
Invoiceneeds to be part of the public ABI - Remove the re-export if it is not needed
- Document the decision in a comment
Labels: refactor, dx
Description:
Invoice and InvoiceStatus do not derive Debug, making test failure messages less informative.
Acceptance Criteria:
- Add
#[derive(Debug)]to both types (if compatible withcontracttype) - Verify tests still compile and run
Labels: refactor, test
Description: As tests grow, common setup code (creating env, registering contract, generating addresses) will be duplicated. Extract into shared helpers.
Acceptance Criteria:
- Create
contracts/invoice/src/tests/helpers.rs(or use a#[cfg(test)]module) - Add
setup_env()andcreate_test_invoice()helpers - Refactor existing tests to use them
Labels: refactor, test
Description:
The existing test uses 1000 as the invoice amount. Replace magic numbers with named constants for clarity.
Acceptance Criteria:
- Define
const TEST_AMOUNT: i128 = 1000in the test module - Replace all magic number amounts in tests
Labels: refactor, code-quality
Description:
Running cargo clippy -- -W clippy::pedantic may reveal additional code quality issues. Fix them all.
Acceptance Criteria:
- Run
cargo clippy -- -W clippy::pedantic - Fix all warnings or explicitly
#[allow(...)]with a justification comment - Add pedantic lints to CI
Labels: refactor
Description:
As new InvoiceStatus variants are added (issues #5), all match expressions must handle them. Add a CI check or comment to catch this.
Acceptance Criteria:
- Search for all
matchonInvoiceStatus - Ensure none use a wildcard
_arm that would silently ignore new variants - Add a comment warning contributors to update matches when adding variants
Labels: refactor
Description:
fund_invoice and release_payment both perform token transfers. Extract this into a shared helper to avoid duplication.
Acceptance Criteria:
- Add
fn transfer_tokens(env: &Env, token: &Address, from: &Address, to: &Address, amount: i128)in a suitable module - Use it in both
fund_invoiceandrelease_payment
Labels: community, tooling
Description: Define a standard set of GitHub issue labels so all issues are consistently categorized.
Acceptance Criteria:
- Create
.github/labels.ymlwith labels:bug,feature,docs,refactor,test,security,tooling,good first issue,help wanted,ci,enhancement,community - Add a GitHub Actions workflow to sync labels using
actions/github-scriptorEndBug/add-and-delete-labels
Labels: community
Description: Allow the community to financially support the project.
Acceptance Criteria:
- Create
.github/FUNDING.yml - Add at least one funding platform (GitHub Sponsors, Open Collective, etc.)
Labels: community, docs, good first issue
Description:
New contributors need clear guidance on where to start. The existing table in CONTRIBUTING.md is a good start but could be expanded.
Acceptance Criteria:
- Add a "Good First Issues" section listing issues #1–#7 and documentation issues
- Include estimated difficulty and required background knowledge for each
Labels: community
Description:
Enable GitHub Discussions for Q&A, ideas, and community conversation. Add a reference in CONTRIBUTING.md.
Acceptance Criteria:
- Enable Discussions in the GitHub repo settings (document the step)
- Add categories:
Q&A,Ideas,Show and Tell - Reference Discussions in
CONTRIBUTING.mdunder "Questions?"
Labels: community, docs
Description: A roadmap helps contributors understand the project's direction and prioritize their contributions.
Acceptance Criteria:
- Add a "Roadmap" section to README
- List v0.1 (core escrow), v0.2 (disputes/cancellation), v0.3 (multi-token, deadlines) milestones
- Link to relevant issues
Labels: community, tooling
Description: GitHub Milestones help track progress toward releases. Create milestones for the first two versions.
Acceptance Criteria:
- Create
v0.1.0milestone: issues #1–#4 (core escrow functions) - Create
v0.2.0milestone: issues #5, #13, #14, #15 (disputes and cancellation) - Assign relevant issues to milestones
Labels: community, docs
Description:
Recognize contributors by maintaining a CONTRIBUTORS.md file.
Acceptance Criteria:
- Create
CONTRIBUTORS.mdwith a table: Name, GitHub handle, Contribution - Add the initial author(s)
- Reference it from
CONTRIBUTING.md
Labels: community, docs, good first issue
Description:
The current CONTRIBUTING.md says "comment to claim it" but doesn't explain the process in detail.
Acceptance Criteria:
- Add a "Claiming Issues" section explaining: comment on the issue, wait for maintainer acknowledgment, start work within 7 days or the issue is re-opened
- Add a note about not opening PRs for unclaimed issues
Labels: community, tooling
Description: Stale issues and PRs accumulate over time. A stale bot keeps the backlog clean.
Acceptance Criteria:
- Create
.github/stale.ymlor useactions/stale - Mark issues stale after 30 days of inactivity
- Close stale issues after 7 more days
- Exempt issues with
pinnedorsecuritylabels
Labels: community, docs
Description:
A SUPPORT.md file tells users where to get help, reducing noise in the issue tracker.
Acceptance Criteria:
- Create
SUPPORT.md - Direct users to GitHub Discussions for questions
- Direct users to the issue tracker only for bugs and feature requests
Labels: community, docs
Description: Link to related Stellar/Soroban projects and resources to help contributors get context.
Acceptance Criteria:
- Add a "Related Projects & Resources" section to README
- Link to: Soroban docs, Stellar developer docs, example Soroban contracts, Stellar token interface docs
Labels: community, docs
Description: A visual identity makes the project more recognizable and professional.
Acceptance Criteria:
- Create a simple SVG or PNG logo for StarInvoice
- Add it to the top of
README.md - Store it in
assets/or.github/
Labels: feature, enhancement
Description: Currently invoices are all-or-nothing. Some freelance arrangements involve milestone-based partial payments. Add support for partial funding and release.
Acceptance Criteria:
- Add
amount_funded: i128andamount_released: i128fields toInvoice - Allow
fund_invoiceto accept a partial amount - Allow
release_paymentto release a partial amount - Update status logic accordingly
- Add tests
Labels: feature, enhancement
Description:
Clients and freelancers may need to amend an invoice (e.g., change amount or description) before funding. Add an amend_invoice function.
Acceptance Criteria:
- Add
pub fn amend_invoice(env: Env, invoice_id: u64, new_amount: i128, new_description: String) - Only callable when status is
Pending - Require auth from both
freelancerandclient(or just freelancer, document the choice) - Emit an
amendedevent - Add tests
Labels: feature, enhancement
Description:
Frontends need to filter invoices by status (e.g., show all Pending invoices). Add a view function for this.
Acceptance Criteria:
- Add
pub fn get_invoices_by_status(env: Env, status: InvoiceStatus) -> Vec<u64> - This may require maintaining a status index in storage
- Add tests
Labels: feature, enhancement
Description:
A real-world escrow protocol may charge a small platform fee on release_payment. Add configurable fee support.
Acceptance Criteria:
- Add
fee_bps: u32(basis points) to contract instance storage, set duringinitialize - Deduct fee from
amountduringrelease_paymentand send to admin address - Add tests verifying correct fee calculation and transfer
Labels: feature, enhancement
Description: Once deadlines are supported, allow the freelancer and client to mutually agree to extend the deadline.
Acceptance Criteria:
- Add
pub fn extend_deadline(env: Env, invoice_id: u64, new_deadline: u64) - Require auth from both parties
- Assert
new_deadline > invoice.deadline - Emit a
deadline_extendedevent - Add tests
Labels: feature, enhancement
Description: Allow clients to send an optional tip to the freelancer on top of the invoice amount.
Acceptance Criteria:
- Add
pub fn tip(env: Env, invoice_id: u64, tip_amount: i128) - Only callable when status is
Completed - Transfer
tip_amountdirectly from client to freelancer - Emit a
tippedevent - Add tests
Labels: feature, security
Description:
Soroban supports contract upgrades via env.deployer().update_current_contract_wasm(). Add an admin-controlled upgrade function.
Acceptance Criteria:
- Add
pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) - Require auth from admin (depends on issue #83)
- Call
env.deployer().update_current_contract_wasm(new_wasm_hash) - Add a test using
env.deployer()
Labels: feature, enhancement
Description: Store a URI pointing to off-chain invoice details (PDF, IPFS hash, etc.) to keep on-chain storage minimal.
Acceptance Criteria:
- Add
metadata_uri: StringtoInvoice(optional, can be empty) - Accept it as a parameter in
create_invoice - Add length validation (max 512 bytes)
- Add tests
Labels: feature, enhancement
Description: Large projects are often broken into milestones. Add support for invoices with multiple milestones, each with its own amount and status.
Acceptance Criteria:
- Design a
Milestonestruct withid,amount,status,description - Add
milestones: Vec<Milestone>toInvoice(or a separate storage key) - Add functions to fund, deliver, approve, and release individual milestones
- Add tests
Labels: feature, enhancement
Description: Allow querying invoices within a specific amount range for analytics and frontend filtering.
Acceptance Criteria:
- Add
pub fn get_invoices_by_amount_range(env: Env, min: i128, max: i128) -> Vec<u64> - This may require a sorted index or full scan (document the trade-off)
- Add tests
Labels: docs, feature
Description: Contributors building frontends need to know how to index contract events. Add a guide explaining how to use Horizon or a custom indexer to listen for StarInvoice events.
Acceptance Criteria:
- Create
docs/indexing-events.md - Explain the event topic structure used in
events.rs - Provide a minimal JavaScript/TypeScript example using
stellar-sdkto subscribe to events - Reference from README
Labels: feature, enhancement
Description: Provide a typed JS/TS client library that wraps the Soroban contract, making it easy for frontend developers to integrate StarInvoice.
Acceptance Criteria:
- Create a
sdk/directory with a TypeScript package - Use
@stellar/stellar-sdkand the generated contract bindings - Export typed functions:
createInvoice,fundInvoice,markDelivered,approvePayment,releasePayment - Add a
README.mdinsdk/with usage examples - Add basic tests using Jest or Vitest
| Range | Category | Count |
|---|---|---|
| #1–#5 | Core Escrow Functions | 5 |
| #6–#15 | Invoice Data Model | 10 |
| #16–#22 | Events | 7 |
| #23–#32 | Storage & State Management | 10 |
| #33–#45 | Testing | 13 |
| #46–#58 | Documentation | 13 |
| #59–#72 | Developer Experience & Tooling | 14 |
| #73–#83 | Security & Access Control | 11 |
| #84–#96 | Refactoring & Code Quality | 13 |
| #97–#108 | Community & Project Health | 12 |
| #109–#120 | Advanced Features | 12 |
| Total | 120 |