Repository navigation
Implement Invoice model #38
Description
Activity
- addedGrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Campaign: Official Campaign | FWC26
on Jul 20, 2026 Hello! I'd love to pick this one up. I'd like to take this on (Implement
Invoicemodel). I'll implement it to spec and add tests. I'll open a PR referencing this shortly once assigned.Hi, I would like to work on this issue.
I have experience working with blockchain data structures, smart contract integrations, and strongly typed model implementations. I’m familiar with mapping on-chain data types to application models, handling Decimal conversions for financial values, timestamp conversions, enum-based states, and validation logic.
I can implement the Invoice model with Soroban contract field mapping, status handling, computed properties, and ensure all acceptance criteria are satisfied.
grantfox-oss commented
on Jul 21, 2026 grantfox-ossboton Jul 21, 2026 – with GrantFox OSSMore actions🦊 GrantFox — @sainath5001 has been assigned to this issue as part of the Official Campaign | FWC26 campaign!
Next steps:
- Open a Pull Request referencing this issue (e.g.,
Closes #38) - Your PR will be reviewed by the ShadeProtocol maintainers
Good luck! Track your progress on GrantFox.
- Open a Pull Request referencing this issue (e.g.,
Hello @sainath5001
What is the update with this task?Hi, I'm Karen, a developer working with Stellar/Soroban integrations, data modeling, and typed SDK architectures
If this issue is open for contributors, I can take on implementing theInvoicemodel undersrc/shade/models/invoice.py. I can start by setting up theInvoiceStatusenum and mapping the Soroban contract types (convertingi128to PythonDecimalandu64Unix timestamps todatetime). I'll implement the computed properties (is_paid,is_expired,outstanding) and the_from_contract_dictdeserializer, backed by unit tests covering every conversion and edge case listed in the acceptance criteria- addedGrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignCampaign: Third Campaignand removedMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardGrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Campaign: Official Campaign | FWC26
on Aug 21, 2026 grantfox-oss commented
on Aug 21, 2026 grantfox-ossboton Aug 21, 2026 – with GrantFox OSSMore actions🦊 GrantFox — @KaruG1999 has been assigned to this issue as part of the Third Campaign campaign!
Next steps:
- Open a Pull Request referencing this issue (e.g.,
Closes #38) - Your PR will be reviewed by the ShadeProtocol maintainers
Good luck! Track your progress on GrantFox.
Reacted by Karen Giannetto- Open a Pull Request referencing this issue (e.g.,
grantfox-oss commented
on Aug 24, 2026 grantfox-ossboton Aug 24, 2026 – with GrantFox OSSMore actions🎉 This issue has been marked as completed on GrantFox as part of the Third Campaign campaign!
@KaruG1999's PR #56 was approved and merged by @codebestia.
🏆 @KaruG1999: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (465 total points). Track your full progress on GrantFox.
👏 Great work, @KaruG1999! Keep contributing to ShadeProtocol.
The Python
Invoicemodel must be a faithful mirror of the Soroban smart contract struct. There are no line items — the contract models an invoice as a singledescription + amount + tokentuple. All monetary fields (amount,amount_paid,amount_refunded) map to PythonDecimal(from i128). All timestamp fields (date_created,date_paid,expires_at) map to Pythondatetime(converted from u64 Unix timestamps). Theidfield is the u64 on-chain invoice ID, mapped to Pythonint.Proposed Steps:
src/shade/models/invoice.py.InvoiceStatusas aStrEnumwith values:pending,paid,expired,partially_paid,refunded.Invoice(ShadeObject)with fields:id: int,description: str,amount: Decimal,token: str,status: InvoiceStatus,merchant_id: int,payer: Optional[str],date_created: datetime,date_paid: Optional[datetime],amount_paid: Decimal,amount_refunded: Decimal,expires_at: Optional[datetime].is_paid: bool,is_expired: bool,outstanding: Decimal._from_contract_dict(data: dict)classmethod for u64 → int and i128 → Decimal conversions.Acceptance Criteria:
Invoice.from_dict(contract_response)populates all fields correctly.invoice.amountis aDecimal, not anintorfloat.invoice.date_createdis adatetime, not an int.invoice.payerisNonefor an unpaid invoice.invoice.is_expiredreturnsTruewhenexpires_atis in the past.invoice.outstandingequalsamount - amount_paidfor a partially paid invoice.line_items,customer_email,payment_url, ortotalfields.