Skip to content

feat(wallet): implement Soroban simulate-sign-submit-poll pipeline an… - #1541

Open
Babigdk wants to merge 1 commit into
OpenKnight-Foundation:mainfrom
Babigdk:feat/soroban-contract-invocation
Open

Babigdk wants to merge 1 commit into
OpenKnight-Foundation:mainfrom
Babigdk:feat/soroban-contract-invocation

Conversation

@Babigdk

@Babigdk Babigdk commented Oct 22, 2026

Copy link
Copy Markdown

feat(wallet): implement Soroban simulate-sign-submit-poll pipeline and typed contract clients

  • Replace deprecated soroban-client with @stellar/stellar-sdk rpc module
  • Implement full contract invocation flow in walletContext: simulate -> assemble -> sign (Freighter) -> submit -> poll
  • Support simulateOnly for read-only contract queries
  • Implement generated typed contract clients for Staking, Puzzle Rewards, AI NFTs, and Arbiter Escrow
  • Add typed contract registry and getContractClient helper in wallet context
  • Add comprehensive unit test suite covering full invocation lifecycle and typed clients

What changed and why

Problem

Previously, frontend/context/walletContext.tsx dynamically imported the deprecated soroban-client package and instantiated an RPC client that unconditionally threw an error ("invokeSorobanContract: implement contract-specific invocation (ABI required)"). As a result, any application feature requiring smart contract interactions—such as liquidity staking (yield_staking), puzzle rewards (game_contract), AI companion NFTs (ai_nft), and arbiter escrow releases (arbiter_escrow)—failed immediately at runtime.

Solution

  1. Migration to @stellar/stellar-sdk: Removed deprecated soroban-client and upgraded walletContext.tsx to use the official @stellar/stellar-sdk's rpc and Horizon modules.
  2. Complete Invocations Pipeline (simulate → sign → submit → poll):
    • Parameter Encoding: Recursively encodes JavaScript primitives, BigInts, and Stellar public/contract addresses (G.../C...) into Soroban xdr.ScVal.
    • Simulation: Simulates the invocation against the Soroban RPC via rpcServer.simulateTransaction(tx) to compute footprint, resource fees, and authorization entries.
    • Read-Only Invocations: Added options.simulateOnly support which extracts and decodes the return value directly from the simulation result without prompting Freighter or incurring gas fees.
    • Transaction Assembly: Assembles simulated resource data and footprint into the transaction envelope using rpc.assembleTransaction(tx, sim).build().
    • Signing (Freighter): Hands the assembled transaction XDR to @stellar/freighter-api (with graceful fallback to window-injected Freighter providers) and parses the signed envelope into a Stellar Transaction.
    • Submission: Dispatches the signed transaction to Soroban RPC with rpcServer.sendTransaction(signedTx).
    • Polling: Continuously polls rpcServer.pollTransaction(hash) until reaching terminal status (SUCCESS or FAILED), then decodes the returnValue back to native JavaScript structures.
  3. Generated Typed Contract Clients: Created strongly typed, idiomatic TypeScript contract clients under frontend/lib/contracts/:
    • YieldStakingContractClient: Handles pool staking, unstaking, yield harvesting, and escrow claims.
    • PuzzleRewardsContractClient: Handles claiming individual and batch puzzle completion rewards and verifying on-chain puzzle balances.
    • AiNftContractClient: Handles companion NFT minting, transfers, metadata queries, and burning.
    • ArbiterEscrowContractClient: Handles match escrow creation, funding, settling payouts/refunds, dispute filing, and arbiter voting.
  4. Contract Client Registry & Factory: Added getContractClient to useAppContext and implemented in-memory client registration to prefer typed clients across the UI.

Issue: Closes the wallet context contract helper issue (simulate -> sign -> submit -> poll).

Summary of changes:

  • frontend/package.json & package-lock.json: Removed deprecated soroban-client and installed @stellar/stellar-sdk v17.
  • frontend/context/walletContext.tsx: Replaced stubbed invokeSorobanContract with full simulate → assemble → sign → submit → poll pipeline and added getContractClient factory.
  • frontend/lib/api.ts: Centralized contract ID environment variables (CONTRACT_STAKING, CONTRACT_GAME_ESCROW, CONTRACT_ELO_REGISTRY, CONTRACT_TOURNAMENT, CONTRACT_AI_NFT).
  • frontend/lib/contracts/: Added types.ts, baseClient.ts, stakingClient.ts, puzzleRewardsClient.ts, nftClient.ts, escrowClient.ts, registry.ts, and index.ts.
  • frontend/__tests__/walletContractInvocation.test.ts: Created 13 unit tests covering unconnected wallet protection, full lifecycle invocation, simulateOnly queries, error handling (simulation, submission, execution, timeout), and typed contract clients.
  • frontend/vitest.config.ts & vitest.setup.ts: Configured dependency inlining and cross-realm Uint8Array / localStorage support for jsdom test runner compatibility.

How it was tested

  • Unit tests pass (npm test):
    • npx vitest run __tests__/walletContractInvocation.test.ts passed (13/13 unit tests).
    • All existing test suites pass (306+ tests across 34 suites).
  • Static Type Check:
    • npx tsc --noEmit executed with 0 type errors.
  • Linter:
    • npm run lint executed with 0 ESLint warnings and 0 errors.
  • Production Bundle Build:
    • npm run build completed successfully, verifying Next.js page generation and client bundle code splitting.

Contributor Checklist

  • Style / Lint clean: Code follows project style guides (npm run lint passed with 0 warnings/errors).
  • Tests added/passing: New unit tests added in __tests__/walletContractInvocation.test.ts covering invocation lifecycle and typed clients; all passing.
  • Target branch correct: PR targets main branch.
  • No plagiarism: All code is original and adheres to project licenses.
  • Documentation updated: Added TypeScript docstrings, centralized environment configs in frontend/lib/api.ts, and updated type definitions.
  • Secrets not committed: No secret keys or private network credentials committed; only public testnet configurations and env defaults used.
  • Breaking changes noted: Fully backwards-compatible; preserves existing invokeSorobanContract(contractId, functionName, args) signature while adding typed options and returns.

Additional context

Soroban Invocation Lifecycle Flow

sequenceDiagram
    autonumber
    participant App as Component / Caller
    participant WC as WalletContext (invokeSorobanContract)
    participant RPC as Soroban RPC
    participant F as Freighter Wallet

    App->>WC: invokeSorobanContract(contractId, fn, args, options)
    WC->>WC: Convert args to xdr.ScVal & build tx
    WC->>RPC: simulateTransaction(tx)
    alt simulateOnly is true
        RPC-->>WC: Simulation Result (retval)
        WC-->>App: Return decoded retval
    else Mutating Contract Call
        RPC-->>WC: Simulation Data & Footprint
        WC->>WC: assembleTransaction(tx, sim)
        WC->>F: signTransaction(preparedTxXDR)
        F-->>WC: signedEnvelopeXDR
        WC->>RPC: sendTransaction(signedTx)
        RPC-->>WC: SendTransactionResponse (hash, status)
        loop Poll until confirmed
            WC->>RPC: pollTransaction(hash)
            RPC-->>WC: GetTransactionResponse (status, returnValue)
        end
        WC-->>App: Return { status: "SUCCESS", hash, returnValue }
    end

Closes #1352
Loading

…d typed contract clients

- Replace deprecated soroban-client with @stellar/stellar-sdk rpc module
- Implement full contract invocation flow in walletContext: simulate -> assemble -> sign (Freighter) -> submit -> poll
- Support simulateOnly for read-only contract queries
- Implement generated typed contract clients for Staking, Puzzle Rewards, AI NFTs, and Arbiter Escrow
- Add typed contract registry and getContractClient helper in wallet context
- Add comprehensive unit test suite covering full invocation lifecycle and typed clients
@drips-wave

drips-wave Bot commented Oct 22, 2026

Copy link
Copy Markdown

@Babigdk 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.

1 participant