Skip to content

Fix toStroops precision (#88), service isolation (#91), event data (#83), slug guard (#86) - #161

Merged
k-deejah merged 2 commits into
Stellar-Deejah:mainfrom
Spagero763:fix/all-open-issues
Jul 28, 2026
Merged

Fix toStroops precision (#88), service isolation (#91), event data (#83), slug guard (#86)#161
k-deejah merged 2 commits into
Stellar-Deejah:mainfrom
Spagero763:fix/all-open-issues

Conversation

@Spagero763

Copy link
Copy Markdown
Contributor

Summary

Closes #88
Closes #91
Closes #83
Closes #86

One PR for all four open issues. This supersedes #127 (which covered #88/#91 against an older main); #127 can be closed in favour of this.

#88toStroops floating-point precision (SDK) ✅ verified

toStroops used Math.round(amount * 10_000_000), which silently truncated
sub-stroop fractional amounts to 0n (e.g. toStroops(0.0000001)0n). It now:

  • accepts string | number;
  • parses the decimal digits directly (numbers via toFixed(7)), never multiplying the scaled value in floating point;
  • throws SDKError('INVALID_AMOUNT', …) for NaN, Infinity, malformed strings, sub-stroop precision, and i128 overflow.

Added sdk/tests/utils.test.ts cases: one-stroop precision (string and number), the guards, and fromStroops round-trips. 48 utils tests pass.

#91 — service test isolation (backend) ✅ verified

escrowService, enrollmentService, and queueService now expose factory functions (createEscrowService(store?), etc.) over an injected storage adapter, plus a default singleton and backward-compatible standalone re-exports (route handlers are unchanged). The service tests construct a fresh service over a new MemoryAdapter() per test, replacing the vi.resetModules() and import('…?t=' + Date.now()) workarounds that left tests order-dependent. docs/testing-strategy.md documents the pattern. 137 backend tests pass.

#83 — events carry data ✅ source, ⚠️ can't compile-verify (see below)

Every contract's emit() prefixed its data params with _ and published an empty () body, so events carried only namespace/kind/id. emit() now publishes the payload:

contract payload
lineproof-queue (identity, timestamp)
lineproof-escrow (identity, amount)
lineproof-identity (identity, timestamp)
lineproof-queue-factory (contract_id, version)

(lineproof-enrollment already emitted identity/timestamp/hash.) The typed interfaces in sdk/src/events.ts already declare these fields, so they now match what's emitted.

#86 — queue slug length guard ✅ verified (client + API), ⚠️ contract migration deferred

A slug longer than Soroban's 9-char Symbol limit panics on-chain with no actionable cause. Guarded at both boundaries so an invalid slug is rejected long before a transaction is built:

  • validateSlug(slug) added to @lineproof/sdk (lowercase alphanumeric words joined by single hyphens, ≤64 chars), exported and tested (6 cases).
  • Backend CreateQueueSchema slug validator tightened to the same shape (400 on invalid). Existing 137 backend tests still pass.
  • docs/concepts.md documents the format.

The complementary contract change (migrating the on-chain Symbol id/slug fields to soroban_sdk::String) is noted in the docs and left with the contract build repair below.

⚠️ Pre-existing, repo-wide breakage — out of scope, for the maintainers

main does not build or pass CI independent of this PR (all upstream workflows — Test, Lint, CodeQL, Docker, Security — are currently red). Specifically, the Soroban contract workspace is broadly broken against SDK 22:

  • Several contract libraries don't compile (BytesN::new / Address::new removed in SDK 22, a missing register_approved_hash trait method, mismatched types).
  • Several contract test files use the same removed APIs, and lineproof-queue-factory's tests call methods that no longer exist (deploy_queue, register_queue, …).
  • The wasm release build fails with a duplicate lang item panic_impl clash.

Because of this, I could not compile-verify the #83 emit() changes or the contract side of #86, and cargo test --workspace cannot pass yet. Those emit() edits are minimal and correct per #83's acceptance criteria; they will compile once the workspace is repaired. Repairing the entire contract build is a separate, large effort beyond these four issues and is left for the maintainers.

Also fixed in passing: the SDK client tests used a contract id with an invalid StrKey checksum (…F4H) that validateContractId rejects — replaced with the valid all-zeros id (…BSC4). Seven further SDK client-test failures remain from pre-existing @stellar/stellar-sdk account/source mocking, unrelated to these issues.

Verification

pnpm --filter @lineproof/sdk test utils      # 54 passed (toStroops + validateSlug)
pnpm --filter @lineproof/backend test        # 137 passed

Copilot AI review requested due to automatic review settings July 28, 2026 13:15
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

@Spagero763 is attempting to deploy a commit to the Deejah Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Stellar-Deejah#91)

instead of the lossy Math.round(amount * 10_000_000), which silently truncated
sub-stroop fractional amounts to 0. Guards NaN/Infinity, malformed strings,
sub-stroop precision, and i128 overflow with SDKError('INVALID_AMOUNT'). Added
utils tests covering one-stroop precision (string and number), the guards, and
fromStroops round-trips.

functions (createEscrowService/createEnrollmentService/createQueueService) over
an injected storage adapter, plus a default singleton and backward-compatible
standalone re-exports so route handlers are unchanged. Service tests construct a
fresh service over a new MemoryAdapter per test, replacing the vi.resetModules()
and import('...?t='+Date.now()) workarounds that left tests order-dependent.
docs/testing-strategy.md documents the pattern.

Also repaired a pre-existing broken test fixture: the SDK client tests used a
contract id with an invalid StrKey checksum ('...F4H') that validateContractId
rejects; replaced with the valid all-zeros contract id ('...BSC4').
…lar-Deejah#86)

Stellar-Deejah#83 — every contract's emit() prefixed its data params with `_` and published
an empty `()` body, so on-chain events carried only a namespace, kind, and id.
Auditors could not tell who enrolled, how much was deposited, or which position
advanced. emit() now publishes the data as the event payload:

  - lineproof-queue:         (identity, timestamp)
  - lineproof-escrow:        (identity, amount)
  - lineproof-identity:      (identity, timestamp)
  - lineproof-queue-factory: (contract_id, version)

(lineproof-enrollment already emitted identity/timestamp/hash.) The typed event
interfaces in sdk/src/events.ts already declare these fields, so they now match
what the contracts emit.

Stellar-Deejah#86 — a queue slug longer than Soroban's 9-char Symbol limit panics on-chain
with no actionable cause, and neither the SDK nor the backend guarded against
it. Added validateSlug() to @lineproof/sdk (lowercase alphanumeric words joined
by single hyphens, <=64 chars) with tests, and tightened the backend
CreateQueueSchema slug validator to the same shape so an invalid slug is
rejected with 400 before any transaction is built. docs/concepts.md documents
the format.

See the PR description for the pre-existing, repo-wide contract build breakage
(SDK-22 API drift in the contract libs and test files, missing trait methods,
the wasm panic_impl clash) that blocks compile-verifying the contract-side
changes and `cargo test --workspace`; that is out of scope here and tracked for
the maintainers.
@Spagero763
Spagero763 force-pushed the fix/all-open-issues branch from 25d15d7 to 679c1c3 Compare July 28, 2026 13:25
@Spagero763

Copy link
Copy Markdown
Contributor Author

Rebased onto the current main. Note: after the rebase, 6 backend test files fail to transform due to pre-existing breakage in main unrelated to this PRbackend/src/app.ts has import "dotenv/config" misplaced mid-file (line 19, a bad merge), and three __tests__/routes/*.route.test.ts files have duplicate res declarations / an unterminated file. These are identical to main (empty diff against upstream) and block the route-level tests; the service-level tests for #91 pass. My changed files are listed in the diff and touch none of these. Left for the maintainers alongside the contract build repair.

@Spagero763

Copy link
Copy Markdown
Contributor Author

@k-deejah seeeee

@k-deejah
k-deejah merged commit ff19f2a into Stellar-Deejah:main Jul 28, 2026
3 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants