Skip to content

Add TypeScript contract bindings generation and Soroban integration for apps/web#280

Closed
Bug-Hunter-X wants to merge 199 commits into
Vatix-Protocol:mainfrom
Bug-Hunter-X:feature/275-add-typescript-bindings
Closed

Add TypeScript contract bindings generation and Soroban integration for apps/web#280
Bug-Hunter-X wants to merge 199 commits into
Vatix-Protocol:mainfrom
Bug-Hunter-X:feature/275-add-typescript-bindings

Conversation

@Bug-Hunter-X

Copy link
Copy Markdown

Overview

This PR adds TypeScript contract bindings generation and Soroban integration for apps/web. It implements the script to build WASM and generate TS client types, adds necessary environment variables, replaces setTimeout mocks in DepositForm/WithdrawForm, and adds the build:bindings step to CI.

Related Issue

Closes #275

Changes

📜 Script

  • [MODIFY] scripts/generate-bindings.ts
    • Fixed the script to point to correct wasm32v1-none build output path

🌐 Apps/Web Integration

  • [MODIFY] apps/web/package.json
    • Added @stellar/stellar-sdk as a dependency
  • [MODIFY] apps/web/context/WalletContext.tsx
    • Added deposit() and withdraw() functions with Soroban RPC integration
    • Implemented real transaction signing with Freighter wallet
    • Added proper type definitions
  • [MODIFY] apps/web/components/DepositForm.tsx
    • Replaced setTimeout mock with real deposit() call
    • Added error handling
  • [MODIFY] apps/web/components/WithdrawForm.tsx
    • Replaced setTimeout mock with real withdraw() call
    • Added error handling

🔧 Environment

  • [EXISTS] apps/web/.env.example
    • Already includes NEXT_PUBLIC_MARKET_CONTRACT_ID, NEXT_PUBLIC_SOROBAN_NETWORK_PASSPHRASE, NEXT_PUBLIC_SOROBAN_RPC_URL

🚀 CI

  • [EXISTS] .github/workflows/ci.yml
    • Already includes pnpm build:bindings step!

Verification Results

Acceptance Criteria Status
Script to build WASM and generate TS bindings
NEXT_PUBLIC_MARKET_CONTRACT_ID and network passphrase in env
setTimeout mocks replaced in DepositForm/WithdrawForm
CI includes pnpm build:bindings
TypeScript compilation passes

How to Test

# 1. Confirm you're on the branch
git branch --show-current

# 2. Run web typecheck
pnpm --filter web lint

# 3. Verify the web app builds
pnpm --filter web build

# 4. Optional: inspect the changed files
git diff -- scripts/generate-bindings.ts apps/web/

aji70 and others added 30 commits February 25, 2026 11:19
* feature/withdraw-unused-collateral

* feature/withdraw-unused-collateral

* feature/withdraw-unused-collateral
Co-authored-by: Yusuf Habib <109147010+manlikeHB@users.noreply.github.com>
* feature/resolve-market-oracle

* feature/resolve-market-oracle
onboarding fixes for expiration, deposit, withdraw docs, and positions errors
- Define ValidationFailedEvent in events.rs with context and error_code fields
- Add emit_validation_failed() helper function
- Add test asserting event emission and field values
Replace flat Symbol constants (MARKETS_KEY, POSITIONS_KEY, ADMIN_KEY,
COUNTER_KEY) with a contracttype StorageKey enum. No behavior change.
Add TODO(#issue) references near each emit_* call site explaining
potential future improvements to the event payloads.
- Assert all error discriminant values match their documented ranges
- Assert equality and inequality between variants
- Assert ordering across error categories
Explicitly reject withdrawals when total_deposited is zero before
computing locked collateral, preventing silent unwrap_or(0) fallthrough.
Adds test_withdraw_zero_deposited_rejected to cover the rejection.
…rams

HarnessError variants carry doc comments explaining the failure cause.
MarketParams::default_valid provides a reusable baseline for integration
tests, removing the need for repeated boilerplate setup.
Documents all arguments, return value, error variants, emitted event,
and includes an inline example showing typical usage.
…ejected

Defines PositionLimitExceededEvent in events.rs with market_id, user,
and side_yes (which share side would go negative). update_position now
emits the event before returning ShareBalanceBelowZero.
Adds test_update_position_limit_exceeded_emits_event to assert emission.
Adds a Next.js frontend under apps/web, plus scripts to generate/publish 375 onboarding issues across the three Vatix repos. Updates CI and docs to include the new frontend workflow.
 Add a no-layout-shift loading skeleton
…contract-improvements

Onboarding/contract improvements
Mimah97 and others added 23 commits June 3, 2026 13:00
…142-ci-comment-jsdoc-error-messages

feat: issue 140, 141, 142
- Fix missing Vec import and Position PartialEq derive in market contract
- Remove unused ContractError import from positions module
- Delete TypeScript test files lacking test dependencies and not run by CI
- Contract now compiles successfully (4 pre-existing test failures remain)
- Web app builds and lints successfully
Ran cargo fmt to standardize code formatting across market contract source files and removed conflicting pnpm version specification in GitHub Actions workflow. The pnpm version is now sourced from package.json's packageManager field.
- Add #[allow(dead_code)] to unused event structs and functions (ValidationFailedEvent, OracleSignatureVerifiedEvent, and their emit functions)
- Simplify boolean expression in position_limit_exceeded_side: new_yes < 0 || new_no < 0
- Use range contains for market price validation: !(0..=10_000).contains(&price)
…code in test

- Fixed position_limit_exceeded_side to properly return boolean value instead of unit type
- Updated test_initialize_market_non_admin_fails to expect correct error code Vatix-Protocol#41 (NotAdmin) instead of Vatix-Protocol#40 (Unauthorized)
- This brings total passing tests from 112 to 113
…thdraw edge case events

- Fixed test_collateral_deposit_emits_event: register mock StellarAssetClient token and mint tokens to user
- Fixed test_withdraw_success_updates_position_and_transfers: move token mint after mock_all_auths for proper authorization
- Fixed test_withdraw_edge_case_emits_event: query events inside as_contract block and simplify to check event count

All 116 tests now passing
…tion-tests

 Implement workspace integration tests using tests/helpers harness
…ontract

- Add ContractError::AlreadyInitialized (Vatix-Protocol#42) to error.rs to guard
  against re-initialization replay attacks on the admin slot

- Add storage::has_admin() helper that returns true when the ADMIN_KEY
  persistent slot is populated; used by initialize() to enforce one-time
  bootstrap semantics

- Add ContractInitializedEvent and emit_contract_initialized() to events.rs
  so off-chain indexers can confirm which address owns a freshly deployed
  contract

- Expose MarketContract::initialize(env, admin) in lib.rs:
    1. admin.require_auth()  — cryptographic proof of ownership
    2. Guard: if has_admin() -> Err(AlreadyInitialized)  — prevents hijack
    3. storage::set_admin()  — persists the admin address
    4. emit_contract_initialized()  — publishes the bootstrap event

  This closes the dependency gap described in Vatix-Protocol#245: previously the admin
  slot could only be written by test-only as_contract bypasses, making
  the deployed contract unusable (initialize_market panics on missing
  admin). The new function gives deployers a safe, authorized on-chain
  path to bootstrap the contract.

- Add tests in test.rs covering:
    * test_initialize_sets_admin_and_emits_event
    * test_initialize_allows_subsequent_market_creation
    * test_initialize_twice_fails_with_already_initialized
    * test_initialize_second_admin_fails

- Extend storage test: test_admin_storage now asserts has_admin() returns
  false before set_admin() and true after

- Extend events test: test_emit_contract_initialized verifies topic symbol
  and admin address topic

Closes Vatix-Protocol#245
…ic ordering

Soroban contractevent macro only prepends the struct-name symbol as
topic[0] when the event has both topic fields AND data fields. A struct
with only topic fields emits them starting at index 0 with no name
symbol prefix, so the assertion:

  assert_eq!(topic0, Symbol::new(env, contract_initialized_event))

was comparing the name symbol against the admin Address, causing the
test to fail.

Fix: add initialized_at: u64 as a data field. This gives the macro a
non-topic payload to serialize, which causes it to emit the name symbol
at topic[0] as expected. The field is also useful context for indexers.

Update test_emit_contract_initialized to assert the initialized_at
data field as well.
…ayout

 Add settle_position public API with SAC token payout transfer
…initialize-admin-entry-point

feat(contracts): add initialize(admin) deploy entry point for MarketContract
@Mimah97

Mimah97 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

@Bug-Hunter-X bug filled commit check and push again

The merge from main added NoCollateralToWithdraw and
WithdrawalExceedsUnlockedCollateral, shifting position error codes.
Update discriminants and overselling panic expectation so CI passes.
@Bug-Hunter-X

Copy link
Copy Markdown
Author

@Mimah97 Fixed and pushed in 195417e.

The merge from main shifted position error codes, so two tests were still expecting the old values. Updated them — cargo test (124 passed), fmt, clippy, and web lint/build all pass locally. CI should be green now.

Bug-Hunter-X added 3 commits June 22, 2026 10:14
Resolve conflicts in storage, lib, events, and validation by keeping
the StorageKey enum and feature-branch APIs while integrating treasury
and fee-bps admin functions from main.
Frontend CI failed because stellar was missing and bindings looked for
WASM under contracts/market/target instead of the workspace target dir.
main() is synchronous so main().catch() threw after bindings
generation succeeded, failing the CI bindings step.
@Mimah97 Mimah97 closed this Jun 23, 2026
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.