Skip to content

Fix: Build multi-signature co-signer approval UI with invitation flow and status tracking - #944

Open
Mosimi25 wants to merge 1 commit into
Stellar-split:mainfrom
Mosimi25:simple/383
Open

Mosimi25 wants to merge 1 commit into
Stellar-split:mainfrom
Mosimi25:simple/383

Conversation

@Mosimi25

Copy link
Copy Markdown

Closes #383

Issues

#383 Build multi-signature co-signer approval UI with invitation flow and status tracking

Overview

When an invoice requires N-of-M co-signer approvals before release, the UI must let the creator invite co-signers, track who has approved, and let co-signers approve from a dedicated page.

Requirements

  • Extend /invoice/new form with optional "Require co-signer approvals" section: add co-signer addresses, set threshold
  • /invoice/[id]/cosigners page: shows list of required co-signers with approval status (pending / approved / threshold met)
  • Co-signer can approve from this page using their connected Freighter wallet
  • Real-time status updates via useInvoiceStream
  • Email/address invitation copy button for sharing the co-signer link
  • Mobile-responsive layout
  • Write unit tests for the co-signer status component

Acceptance Criteria

  • Invoice creation with co-signers works end-to-end
  • Co-signer status page shows correct approval states
  • Approve button works for connected co-signer wallets
  • Real-time updates via event stream
  • Mobile-responsive on all screen sizes
  • npm run lint passes with zero errors
  • TypeScript compiles with zero errors
  • npm run build succeeds

Definition of Done

All CI checks must pass before the PR is reviewed.

Summary

The /invoice/new page already imports CoSignerSection and tracks cosigners/cosignerThreshold in payloadForApi; verify that component exists and is wired to useInvoiceForm state, otherwise create src/components/invoice/CoSignerSection.tsx. The cosigners page currently uses raw fetch and a local wallet check; replace with the shared useWalletContext/useWallet hook and the new API helpers for consistency. Ensure the approval flow signs with Freighter before PATCHing splitMeta, and that useInvoiceStream's new event type is backward compatible with existing consumers. Run lint, tsc --noEmit, and next build after implementation.

Changes

  • Extend the invoice creation form hook to support an optional co-signer section: add co-signer address list state, threshold state, address validation (Stellar public key format), threshold bounds (1..N), and include cosigners + cosignerThreshold in the create payload. Expose helpers to add/remove co-signers and reset the section. (src/hooks/useInvoiceForm.ts)
  • Add the optional co-signer section to the /invoice/new page: render a CoSignerSection (address inputs + threshold selector) wired to useInvoiceForm state, validate addresses/threshold before advancing steps, and ensure the cosigners + cosignerThreshold are included in the create payload sent to the API (payloadForApi). Show inline validation errors and keep the section collapsible/optional. (src/app/invoice/new/page.tsx)
  • Add co-signer API helpers: fetchCoSigners(invoiceId) to GET /api/invoices/:id and return splitMeta.cosigners + cosignerThreshold, and submitCoSignerApproval(invoiceId, address, signature?) to PATCH /api/invoices/:id with updated splitMeta. Include typed CoSigner/CoSignerStatus interfaces and handle non-OK responses with classified errors. (src/lib/api.ts)
  • Add co-signer approval signing helper: signCoSignerApproval(invoiceId, address) that builds the approval payload/message and signs it via Freighter (signWithFreighter / signTransaction), returning the signature for submission. Guard against SSR and surface wallet-not-connected errors. (src/lib/freighter.ts)
  • Add a 'cosigner_approval_failed' / 'not_a_cosigner' error kind and matching patterns to classifyError so the co-signer page can render friendly messages when a wallet is not a designated co-signer or approval signing fails. (src/lib/errors.ts)
  • Create a CoSignerStatus component that renders each required co-signer with truncated address, pending/approved status badge, approved-at timestamp, and an overall threshold-met indicator. Include an Approve button gated on the connected wallet matching a co-signer address (disabled/hidden otherwise), a loading state while approving, and responsive Tailwind classes (stack on mobile, row on sm+). Accept props for cosigners, threshold, connectedAddress, approving, onApprove, and error. (src/components/CoSignerStatus.tsx)
  • Create unit tests for the CoSignerStatus component covering: rendering all co-signers with pending/approved states, threshold-met indicator when approved count >= threshold, Approve button enabled only when connectedAddress matches a co-signer, disabled/hidden when wallet is not a co-signer or already approved, and onApprove callback invocation. Use the project's existing test setup (React Testing Library). (src/components/tests/CoSignerStatus.test.tsx)
  • Build the /invoice/[id]/cosigners page: fetch splitMeta cosigners/threshold via the new API helper, render CoSignerStatus, wire the Approve action to sign via Freighter and submit the approval, subscribe to useInvoiceStream to refresh status in real time (re-fetch on latestEvent/invoice changes), use CopyLinkButton for the invitation link, show loading/error/empty states, and use responsive Tailwind layout for mobile. (src/app/invoice/[id]/cosigners/page.tsx)
  • Extend useInvoiceStream to expose co-signer approval updates: add a 'CoSignerApproved' event type parsed from contract events and include co-signer state in the returned result (or trigger a refresh callback) so the co-signers page updates in real time when an approval is recorded. (src/hooks/useInvoiceStream.ts)

Co-authored-by: Simple Agent <agent@simple.dev>
@vercel

vercel Bot commented Oct 17, 2026

Copy link
Copy Markdown

@Mosimi25 is attempting to deploy a commit to the kingsman-99's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@Mosimi25 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! 🚀

Learn more about application limits

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build multi-signature co-signer approval UI with invitation flow and status tracking

1 participant