Add SDK appeal, batch submission, and LP fund-queue methods - #511
Merged
Levi-Ojukwu merged 3 commits intoJul 25, 2026
Merged
Conversation
(closes Invoice-Liquidity-Network#462) (closes Invoice-Liquidity-Network#463) appealInvoice(client, invoiceId, evidenceHash) wraps appeal_default. Validates the invoice is currently Defaulted client-side (via getInvoice) before submitting, and maps AlreadyAppealed/AppealWindowClosed/ NotDefaulted through the existing ILNError.fromError (these are invoice_liquidity ContractError codes, same contract ILNError is already scoped to — no collision, unlike the governance/insurance contracts in prior batches). resolveAppeal(client, invoiceId, upheld) wraps resolve_appeal. Security note called out in the JSDoc: despite resolve_appeal's doc comment ("Access: Admin only"), the current contract (contracts/invoice_liquidity/src/lib.rs:1891) never actually calls require_admin or any other auth check on this function — any account can currently call it and manipulate a payer's reputation score. This is a pre-existing contract-level bug, out of scope for this SDK-wrapper issue (fixing it would mean changing a live contract's access control, which needs its own careful review), so it's flagged rather than silently worked around. Adds tests for both, including the appeal-window/status validation paths and the error-code mapping.
(closes Invoice-Liquidity-Network#467) submitInvoicesBatch(client, invoices[]) wraps submit_invoices_batch, validating batch size (1-10) client-side and returning the new invoice IDs in submission order. Encodes each item as the contract's InvoiceParams struct by hand-building an alphabetically-key-sorted ScVal map (amount, discount_rate, due_date, freelancer, payer, referral_code, token) — matching soroban_sdk's #[contracttype] struct wire encoding, same approach submitInvoice.ts already uses for the ReferralCode enum. Scope note (documented in the file header): the contract requires require_auth() from every distinct freelancer address in the batch. This method signs with a single client.signer, so it only supports batches where every item's freelancer matches that signer — the "high-volume freelancer submits their own batch" case the issue calls out. Batches spanning multiple freelancers would need multiple signers on the same transaction, out of scope here. Adds tests covering the happy path, batch-too-large/empty-batch validation, and error-code mapping.
(closes Invoice-Liquidity-Network#466) joinFundQueue(client, lpAddress, invoiceId) wraps join_fund_queue, requiring the LP's own signature. resolveFundQueue(client, invoiceId) wraps resolve_fund_queue (callable by anyone per the contract) and returns the approved LP's address. Maps AlreadyInQueue/NotApprovedFunder through the existing ILNError.fromError (invoice_liquidity ContractError codes, no collision). Adds tests covering both happy paths and the two error codes.
|
@circleboyslimited Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#462/#463 — appeal flow.
appealInvoice(client, invoiceId, evidenceHash)wrapsappeal_default, validating the invoice is currentlyDefaultedclient-side (viagetInvoice) before submitting.resolveAppeal(client, invoiceId, upheld)wrapsresolve_appeal. Both mapAlreadyAppealed/AppealWindowClosed/NotDefaulted/etc. through the existingILNError.fromError— these areinvoice_liquidityContractErrorcodes, the same contractILNErroris already scoped to, so no collision like the governance/insurance contracts hit in earlier batches.**
resolve_appeal's doc comment says "Access: Admin only", butcontracts/invoice_liquidity/src/lib.rs:1891never actually callsrequire_adminor any other auth check — any account can currently callresolve_appealand manipulate a payer's reputation score. This is a pre-existing contract-level access-control bug, out of scope for this SDK-wrapper issue (fixing a live contract's auth needs its own careful review/redeploy plan), so I'm surfacing it here and in the code's JSDoc rather than silently working around it or fabricating a client-side restriction that wouldn't actually be enforceable.#467 — batch submission.
submitInvoicesBatch(client, invoices[])wrapssubmit_invoices_batch, validating batch size (1-10) client-side and returning the new invoice IDs. Each item is hand-encoded as the contract'sInvoiceParamsstruct (alphabetically-sorted ScVal map) — same techniquesubmitInvoice.tsalready uses for theReferralCodeenum. Scope note: the contract requiresrequire_auth()from every distinct freelancer in the batch, but this method signs with a singleclient.signer, so it only supports batches where every item's freelancer matches that signer (the "high-volume freelancer submits their own batch" case the issue calls out) — documented in the file header.#466 — LP fund queue.
joinFundQueue(client, lpAddress, invoiceId)andresolveFundQueue(client, invoiceId)wrapjoin_fund_queue/resolve_fund_queue, mappingAlreadyInQueue/NotApprovedFunder.Closes #462
Closes #463
Closes #466
Closes #467
Test plan
npx vitest runinsdk/: 18 new tests pass acrossappeal.test.ts/submitInvoicesBatch.test.ts/fundQueue.test.ts, covering happy paths, client-side validation (appeal status, batch size), and error-code mapping; 11 pre-existing unrelated failures (getTokenDecimals.test.ts,nft.test.ts) confirmed to already exist onmainnpx tsc --noEmitinsdk/: zero new errors; one pre-existing unrelated error inxdrDecoder.ts