feat: generate TypeScript bindings for Soroban smart contracts#517
feat: generate TypeScript bindings for Soroban smart contracts#517Josue19-08 wants to merge 4 commits intoboundlessfi:mainfrom
Conversation
Generate TypeScript client bindings for all 4 core Soroban contracts (Bounty Registry, Core Escrow, Reputation Registry, Project Registry) using the stellar CLI. Add lib/contracts/index.ts with configured client factories (environment-based address config, network-aware RPC URLs) and lib/contracts/transaction.ts with simulateContract, buildTransaction, and submitTransaction helpers. Update .env.example with contract address vars.
|
@Josue19-08 is attempting to deploy a commit to the Threadflow Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughAdds four generated TypeScript Soroban contract client packages (bounty-registry, core-escrow, reputation-registry, project-registry), a central contracts entrypoint and transaction helpers, and four NEXT_PUBLIC_* env vars for contract addresses (testnet defaults with mainnet override guidance). Changes
Sequence Diagram(s)sequenceDiagram
participant ClientCode as Client
participant ContractsModule as ContractsIndex
participant RPC as SorobanRPC
participant Network as StellarNetwork
ClientCode->>ContractsModule: createXClient(publicKey?)
ClientCode->>ContractsModule: getRpcUrl(), getNetworkPassphrase()
ClientCode->>ContractsModule: client.method(...)\nreturns AssembledTransaction
ClientCode->>ContractsModule: simulateContract(tx)
ContractsModule->>RPC: /simulate (tx)
RPC-->>ContractsModule: simulation result
ContractsModule-->>ClientCode: decoded simulation result
ClientCode->>ContractsModule: buildTransaction(tx)
ContractsModule->>RPC: /simulate (populate)
RPC-->>ContractsModule: populated tx metadata
ContractsModule-->>ClientCode: unsigned XDR
ClientCode->>Network: sign XDR (external wallet)
ClientCode->>ContractsModule: submitTransaction(signedXdr)
ContractsModule->>RPC: /send (signedXdr)
RPC-->>ContractsModule: submission response (hash/status)
ContractsModule->>RPC: /getTransaction(hash) [poll until found]
RPC-->>ContractsModule: final transaction result
ContractsModule-->>ClientCode: SubmitTransactionResult (hash + response)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (14)
lib/contracts/project-registry/.gitignore (1)
1-2: Includedist/in.gitignorefor this package.Current ignore rules miss the compiled output directory used by TypeScript builds.
Proposed change
node_modules/ out/ +dist/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/project-registry/.gitignore` around lines 1 - 2, Add the compiled output directory to this package's ignore rules: update the .gitignore in the project-registry package to include "dist/" (alongside existing entries like "node_modules/" and "out/") so TypeScript build artifacts are not committed; ensure the entry uses a trailing slash ("dist/") to clearly ignore the directory..env.example (2)
34-38: Avoid dual sources of truth for contract ID defaults.These values are duplicated in
lib/contracts/index.ts(Lines 31-46). Keeping defaults in both places can drift over time; prefer a single canonical default source and keep the other as documentation/placeholders.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env.example around lines 34 - 38, The .env.example currently hardcodes NEXT_PUBLIC_BOUNTY_REGISTRY_CONTRACT_ID, NEXT_PUBLIC_CORE_ESCROW_CONTRACT_ID, NEXT_PUBLIC_REPUTATION_REGISTRY_CONTRACT_ID, and NEXT_PUBLIC_PROJECT_REGISTRY_CONTRACT_ID which duplicate defaults defined in lib/contracts/index.ts; pick one canonical source for those default contract IDs (prefer lib/contracts/index.ts as the runtime/default source) and remove the hardcoded defaults from .env.example (leave placeholder keys or comment indicating they are defined in lib/contracts/index.ts), or alternatively move the canonical defaults into .env.example and have lib/contracts/index.ts read from process.env; update references to NEXT_PUBLIC_* keys accordingly so only one place holds the truth.
38-38: Add a trailing newline to satisfy dotenv linting.Minor file-hygiene fix to clear the
EndingBlankLinewarning.Proposed change
NEXT_PUBLIC_PROJECT_REGISTRY_CONTRACT_ID="CCG4QM2GZKBN7GBRAE3PFNE3GM2B6QRS7FOKLHGV2FT2HHETIS7JUVYT" +🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env.example at line 38, The file ends without a trailing newline causing dotenv lint warnings; edit .env.example so the final line (the declaration NEXT_PUBLIC_PROJECT_REGISTRY_CONTRACT_ID="CCG4QM2GZKBN7GBRAE3PFNE3GM2B6QRS7FOKLHGV2FT2HHETIS7JUVYT") is followed by a single trailing newline (i.e., an empty line at EOF) and commit that change.lib/contracts/reputation-registry/.gitignore (1)
1-2: Adddist/to ignore rules for generated build output.This package ignores
node_modules/andout/, but missesdist/, which is the expected TypeScript build output folder.Proposed change
node_modules/ out/ +dist/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/reputation-registry/.gitignore` around lines 1 - 2, The .gitignore in the reputation-registry package is missing the TypeScript build output folder; update the .gitignore (currently containing "node_modules/" and "out/") to also include "dist/" so generated build artifacts are ignored; add a new line with dist/ alongside the existing entries in the same file.lib/contracts/bounty-registry/.gitignore (1)
1-2: Ignoredist/artifacts in this package as well.
node_modules/andout/are ignored, but TypeScript output is typically emitted todist/in these generated contract packages.Proposed change
node_modules/ out/ +dist/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/bounty-registry/.gitignore` around lines 1 - 2, Update the package .gitignore to also ignore TypeScript build artifacts by adding the "dist/" pattern alongside the existing "node_modules/" and "out/" entries; modify the bounty-registry package .gitignore to include a new line with "dist/" so compiled output is not committed.lib/contracts/core-escrow/.gitignore (1)
1-2: Adddist/to ignored paths.This avoids tracking generated JavaScript/declaration artifacts from package builds.
Proposed change
node_modules/ out/ +dist/🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/core-escrow/.gitignore` around lines 1 - 2, The .gitignore currently lists node_modules/ and out/ but omits dist/, so add the dist/ entry to the file to ensure build output (generated JavaScript and declaration files) is not committed; update the file named core-escrow .gitignore by appending a single line "dist/" (matching the style of existing entries) so that generated artifacts from package builds are ignored alongside node_modules/ and out/.lib/contracts/bounty-registry/package.json (1)
12-12: Use caret version range for thebufferdependency.The exact pin
"6.0.3"prevents patch updates and can cause dependency resolution conflicts. Change to"^6.0.3"to allow compatible updates.📦 Proposed fix
- "buffer": "6.0.3" + "buffer": "^6.0.3"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/bounty-registry/package.json` at line 12, The dependency "buffer" in package.json is pinned to an exact version "6.0.3"; update the version string to a caret range "^6.0.3" so patch/minor compatible updates are allowed and to reduce dependency resolution conflicts—edit the "buffer" entry in lib/contracts/bounty-registry/package.json to use "^6.0.3" instead of "6.0.3".lib/contracts/project-registry/package.json (1)
12-12: Use caret version range for thebufferdependency.The
bufferpackage is pinned to exactly6.0.3without a caret (^). This prevents npm from resolving patch and minor updates, which can lead to dependency conflicts in consuming projects if other packages require a newer patch version ofbuffer.Consider changing to
"buffer": "^6.0.3"to allow compatible updates.📦 Proposed fix
- "buffer": "6.0.3" + "buffer": "^6.0.3"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/project-registry/package.json` at line 12, The package.json currently pins the buffer dependency to an exact version ("buffer": "6.0.3"); change it to a caret range so npm can install compatible minor/patch updates by updating the dependency value to "buffer": "^6.0.3" in the lib/contracts/project-registry package.json (look for the "buffer" entry in dependencies).lib/contracts/reputation-registry/tsconfig.json (2)
72-74: Consider enabling full strict mode instead of only strictNullChecks.Currently only
strictNullChecksis enabled (line 74). Enabling the full"strict": trueoption provides stronger type safety by activating all strict type-checking flags together (noImplicitAny,strictFunctionTypes,strictBindCallApply, etc.), which helps catch more potential bugs at compile time.🔒 Proposed enhancement
/* Type Checking */ - // "strict": true, /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, + // "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/reputation-registry/tsconfig.json` around lines 72 - 74, Enable full TypeScript strict mode by setting "strict": true in tsconfig.json and removing or un-commenting the individual flags (e.g., the commented "strict" and "noImplicitAny") so that the compiler enables all strict checks instead of only "strictNullChecks"; update the config entry that currently has "strictNullChecks": true to either replace it with "strict": true or add "strict": true alongside it to ensure flags like noImplicitAny, strictFunctionTypes, strictBindCallApply, etc. are active.
66-66: Consider enabling isolatedModules for better bundler compatibility.The
isolatedModulesoption is currently commented out. Enabling it ensures each file can be transpiled independently, which is important for compatibility with modern bundlers (like Next.js's bundler) and can catch certain TypeScript features that don't work well in isolated compilation scenarios.⚙️ Proposed enhancement
/* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/reputation-registry/tsconfig.json` at line 66, Enable the TypeScript "isolatedModules" option in the tsconfig by uncommenting and setting "isolatedModules": true so each file can be transpiled independently for better bundler compatibility; locate the "isolatedModules" entry in tsconfig.json (the line currently commented as // "isolatedModules": true) and restore it as an active compiler option.lib/contracts/bounty-registry/tsconfig.json (2)
72-74: Consider enabling full strict mode instead of only strictNullChecks.Enable
"strict": true(line 72) to activate all strict type-checking options for better type safety. This is preferable to enabling individual strict flags piecemeal.🔒 Proposed enhancement
/* Type Checking */ - // "strict": true, /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, + // "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/bounty-registry/tsconfig.json` around lines 72 - 74, Enable full TypeScript strict mode by setting the "strict" compiler option to true (uncomment or add the "strict": true key) instead of only relying on "strictNullChecks"; keep or remove the individual flags as needed (TypeScript will derive them from "strict") so update the tsconfig entry where "strictNullChecks" and the commented "strict" appear to ensure "strict": true is present and consistent with "strictNullChecks".
66-66: Consider enabling isolatedModules for better bundler compatibility.Enabling
isolatedModulesensures compatibility with modern bundlers and can help catch issues earlier in the development process.⚙️ Proposed enhancement
/* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/bounty-registry/tsconfig.json` at line 66, Uncomment or add "isolatedModules": true inside the tsconfig's compilerOptions (the "isolatedModules" flag) so the project is compiled per-file for bundler compatibility; update the tsconfig.json to set that option to true and run the type/build tests to ensure no code patterns (e.g., const enums or non-isolated constructs) need adjusting.lib/contracts/core-escrow/package.json (1)
12-12: Use caret version range for thebufferdependency.Change from exact
"6.0.3"to"^6.0.3"to allow compatible patch updates.📦 Proposed fix
- "buffer": "6.0.3" + "buffer": "^6.0.3"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/core-escrow/package.json` at line 12, Update the buffer dependency in package.json from the fixed version "6.0.3" to a caret range so compatible patch/minor updates are allowed; locate the "buffer" entry in lib/contracts/core-escrow/package.json and change its version string to "^6.0.3" (ensuring the JSON remains valid).lib/contracts/index.ts (1)
13-14: Expose the other generated bindings from the central entrypoint too.
lib/contractscurrently forwards the bounty bindings only. That means named exports from core escrow, reputation, and project registry still require deep imports, which undercuts this file as the single contracts entrypoint.♻️ Suggested namespaced re-exports
export * from './bounty-registry/src/index'; +export * as coreEscrowBindings from './core-escrow/src/index'; +export * as reputationRegistryBindings from './reputation-registry/src/index'; +export * as projectRegistryBindings from './project-registry/src/index'; export * from './transaction';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/index.ts` around lines 13 - 14, The central contracts entrypoint currently only re-exports './bounty-registry/src/index' and './transaction', so generated bindings for core escrow, reputation, and project registry remain available only via deep imports; update lib/contracts/index.ts to also export the generated modules for those bindings (e.g., add export * from './core-escrow/src/index'; export * from './reputation/src/index'; export * from './project-registry/src/index' or appropriate module names used in the repo) so consumers can import all contract bindings from this single entrypoint (or alternatively provide namespaced re-exports if you prefer grouping).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/contracts/bounty-registry/package.json`:
- Line 5: The package.json "exports" currently points to "./dist/index.js" but
the consumer in lib/contracts/index.ts appears to import the source module
directly, so the compiled dist output is never used; either change the consumer
imports in lib/contracts/index.ts (and any other consumers) to import the
package root so Node/resolver picks up the "exports" (thus using the built
./dist/index.js), or change the package.json "exports" to point at the source
entry used by consumers (e.g., the src index) so imports continue to resolve to
source—update whichever side you choose so import paths and the "exports" field
consistently reference the same entry point.
In `@lib/contracts/bounty-registry/README.md`:
- Line 47: The README example references networks.futurenet but the project uses
testnet; update the example to use networks.testnet and ensure it matches the
exported symbol networks (verify the export named networks that contains
testnet) so the example aligns with the codebase and generation/PR notes.
In `@lib/contracts/bounty-registry/tsconfig.json`:
- Line 47: The build outputs to "outDir": "./dist" but consumers may be
importing source files (see lib/contracts/index.ts importing
"./bounty-registry/src/index") while package.json points to "./dist/index.js";
fix by aligning imports/exports: update lib/contracts/index.ts to import the
built artifact (e.g., from "./bounty-registry/dist/index" or "./bounty-registry"
if package.json main/exports point there) or change package.json/tsconfig so the
published entry matches the source import; ensure the unique symbols affected
are the tsconfig.json outDir setting, package.json exports "./dist/index.js",
and the import in lib/contracts/index.ts.
In `@lib/contracts/core-escrow/package.json`:
- Line 5: The package.json "exports" entry points to "./dist/index.js" but the
project and consumers appear to import source files directly (e.g.,
"./core-escrow/src/index"), leaving the dist build unused; either change the
"exports" value to point to the actual consumed entry (or remove it) or update
the build pipeline and consumers to compile and import from the dist output.
Locate the "exports" field in package.json and either update it to the correct
entrypoint that consumers use or ensure a build step produces ./dist/index.js
and update import paths in consuming code to reference the packaged entry;
finally run the build and verify consumers import the packaged entry instead of
source.
In `@lib/contracts/core-escrow/README.md`:
- Line 47: The README example is inconsistent: it references networks.futurenet
while the project uses testnet elsewhere; update the example to use the actual
exported constant from src/index.ts (e.g., replace networks.futurenet with
networks.testnet) or, if you intend to keep futurenet, update the generation
command and other examples to match; verify the exported symbol name "networks"
in src/index.ts and make the README example match that exact exported property.
In `@lib/contracts/index.ts`:
- Around line 33-46: CONTRACT_ADDRESSES currently hardcodes testnet IDs which
mismatch when STELLAR_NETWORK/NEXT_PUBLIC_STELLAR_NETWORK='public'; update
CONTRACT_ADDRESSES to choose defaults based on the network env (e.g. check
process.env.NEXT_PUBLIC_STELLAR_NETWORK or STELLAR_NETWORK) so that each key
(bountyRegistry, coreEscrow, reputationRegistry, projectRegistry) uses mainnet
fallback IDs when network === 'public' and testnet IDs otherwise (or remove
fallbacks and require NEXT_PUBLIC_*_CONTRACT_ID to be set); adjust the constant
CONTRACT_ADDRESSES accordingly so factories that read these values get the
proper network-specific IDs.
In `@lib/contracts/project-registry/package.json`:
- Line 11: Update the dependency entry for "@stellar/stellar-sdk" in
package.json from "^14.5.0" to "^14.6.1" to pull in the Soroban
assembleTransaction bug fix; after editing the "@stellar/stellar-sdk" version
string, run your package manager to update the lockfile (npm install or yarn
install) and run the test suite and any Soroban-related integration checks to
ensure no regressions.
In `@lib/contracts/project-registry/README.md`:
- Around line 43-49: The README example uses non-existent symbols; update it to
import Client (not Contract) from the package and reference the actual exported
networks entry (networks.testnet) — e.g., change the import to use Client and
networks, and instantiate new Client({ ...networks.testnet, rpcUrl: '...' }) so
the example matches the generated API (look for Client and networks.testnet in
lib/contracts/project-registry/src/index.ts).
In `@lib/contracts/reputation-registry/README.md`:
- Line 47: The README example references networks.futurenet while the CLI
example uses testnet—verify the exported network identifiers in src/index.ts
(look for the networks export and names like testnet or futurenet) and update
the README example to use the correct exported symbol (e.g., networks.testnet)
so the example matches the actual export; if the library should expose futurenet
instead, update the export in src/index.ts to include networks.futurenet and
ensure the README and CLI samples are consistent.
In `@lib/contracts/reputation-registry/tsconfig.json`:
- Line 47: The project compiles reputation-registry into "./dist" (tsconfig.json
outDir) but consumers import the source path ("./reputation-registry/src/index")
from lib/contracts/index.ts so the built output is never used; either update the
consumer import to reference the compiled output or stop emitting a separate
dist. Fix by changing the import in lib/contracts/index.ts from
"./reputation-registry/src/index" to the compiled entry (e.g.,
"./reputation-registry/dist/index" or "./reputation-registry" if package.json
exports point to dist/index.js), or alternatively update package.json exports to
point to the source and remove/outDir or adjust tsconfig.json to emit to the
path the consumers expect; locate tsconfig.json (outDir), package.json exports,
and the import in lib/contracts/index.ts to make the paths consistent.
In `@lib/contracts/transaction.ts`:
- Around line 24-40: The function buildTransaction currently builds and
simulates a TransactionBuilder result stored in builtTx but returns tx.toXDR(),
so the constructed/simulated transaction is never returned; change the return to
use the built transaction (builtTx.toXDR()) or otherwise convert the actual
built/simulated Transaction object to XDR before returning; update the return
statement in buildTransaction to return builtTx.toXDR() (or assign builtTx back
to tx if you intend to mutate tx) so the sequence number/timeout/simulation are
reflected in the returned XDR.
- Around line 47-72: The submitTransaction helper currently polls
server.getTransaction in submitTransaction with no deadline and only returns the
hash, which can hang indefinitely and discards useful write-method results;
update submitTransaction to accept a configurable timeout/deadline (or use a
fixed maxRetries) and break the polling loop with a clear error when exceeded
(use sendResponse, getResponse, SorobanRpc.Api.GetTransactionStatus.NOT_FOUND
and server.getTransaction to locate the code), and change the return value to
include the original sendResponse and the final getResponse (e.g., return an
object containing hash, sendResponse, and getResponse) so callers of write
methods (create_bounty, create_pool, register_project) can access
contract-returned values instead of just the transaction hash.
---
Nitpick comments:
In @.env.example:
- Around line 34-38: The .env.example currently hardcodes
NEXT_PUBLIC_BOUNTY_REGISTRY_CONTRACT_ID, NEXT_PUBLIC_CORE_ESCROW_CONTRACT_ID,
NEXT_PUBLIC_REPUTATION_REGISTRY_CONTRACT_ID, and
NEXT_PUBLIC_PROJECT_REGISTRY_CONTRACT_ID which duplicate defaults defined in
lib/contracts/index.ts; pick one canonical source for those default contract IDs
(prefer lib/contracts/index.ts as the runtime/default source) and remove the
hardcoded defaults from .env.example (leave placeholder keys or comment
indicating they are defined in lib/contracts/index.ts), or alternatively move
the canonical defaults into .env.example and have lib/contracts/index.ts read
from process.env; update references to NEXT_PUBLIC_* keys accordingly so only
one place holds the truth.
- Line 38: The file ends without a trailing newline causing dotenv lint
warnings; edit .env.example so the final line (the declaration
NEXT_PUBLIC_PROJECT_REGISTRY_CONTRACT_ID="CCG4QM2GZKBN7GBRAE3PFNE3GM2B6QRS7FOKLHGV2FT2HHETIS7JUVYT")
is followed by a single trailing newline (i.e., an empty line at EOF) and commit
that change.
In `@lib/contracts/bounty-registry/.gitignore`:
- Around line 1-2: Update the package .gitignore to also ignore TypeScript build
artifacts by adding the "dist/" pattern alongside the existing "node_modules/"
and "out/" entries; modify the bounty-registry package .gitignore to include a
new line with "dist/" so compiled output is not committed.
In `@lib/contracts/bounty-registry/package.json`:
- Line 12: The dependency "buffer" in package.json is pinned to an exact version
"6.0.3"; update the version string to a caret range "^6.0.3" so patch/minor
compatible updates are allowed and to reduce dependency resolution
conflicts—edit the "buffer" entry in lib/contracts/bounty-registry/package.json
to use "^6.0.3" instead of "6.0.3".
In `@lib/contracts/bounty-registry/tsconfig.json`:
- Around line 72-74: Enable full TypeScript strict mode by setting the "strict"
compiler option to true (uncomment or add the "strict": true key) instead of
only relying on "strictNullChecks"; keep or remove the individual flags as
needed (TypeScript will derive them from "strict") so update the tsconfig entry
where "strictNullChecks" and the commented "strict" appear to ensure "strict":
true is present and consistent with "strictNullChecks".
- Line 66: Uncomment or add "isolatedModules": true inside the tsconfig's
compilerOptions (the "isolatedModules" flag) so the project is compiled per-file
for bundler compatibility; update the tsconfig.json to set that option to true
and run the type/build tests to ensure no code patterns (e.g., const enums or
non-isolated constructs) need adjusting.
In `@lib/contracts/core-escrow/.gitignore`:
- Around line 1-2: The .gitignore currently lists node_modules/ and out/ but
omits dist/, so add the dist/ entry to the file to ensure build output
(generated JavaScript and declaration files) is not committed; update the file
named core-escrow .gitignore by appending a single line "dist/" (matching the
style of existing entries) so that generated artifacts from package builds are
ignored alongside node_modules/ and out/.
In `@lib/contracts/core-escrow/package.json`:
- Line 12: Update the buffer dependency in package.json from the fixed version
"6.0.3" to a caret range so compatible patch/minor updates are allowed; locate
the "buffer" entry in lib/contracts/core-escrow/package.json and change its
version string to "^6.0.3" (ensuring the JSON remains valid).
In `@lib/contracts/index.ts`:
- Around line 13-14: The central contracts entrypoint currently only re-exports
'./bounty-registry/src/index' and './transaction', so generated bindings for
core escrow, reputation, and project registry remain available only via deep
imports; update lib/contracts/index.ts to also export the generated modules for
those bindings (e.g., add export * from './core-escrow/src/index'; export * from
'./reputation/src/index'; export * from './project-registry/src/index' or
appropriate module names used in the repo) so consumers can import all contract
bindings from this single entrypoint (or alternatively provide namespaced
re-exports if you prefer grouping).
In `@lib/contracts/project-registry/.gitignore`:
- Around line 1-2: Add the compiled output directory to this package's ignore
rules: update the .gitignore in the project-registry package to include "dist/"
(alongside existing entries like "node_modules/" and "out/") so TypeScript build
artifacts are not committed; ensure the entry uses a trailing slash ("dist/") to
clearly ignore the directory.
In `@lib/contracts/project-registry/package.json`:
- Line 12: The package.json currently pins the buffer dependency to an exact
version ("buffer": "6.0.3"); change it to a caret range so npm can install
compatible minor/patch updates by updating the dependency value to "buffer":
"^6.0.3" in the lib/contracts/project-registry package.json (look for the
"buffer" entry in dependencies).
In `@lib/contracts/reputation-registry/.gitignore`:
- Around line 1-2: The .gitignore in the reputation-registry package is missing
the TypeScript build output folder; update the .gitignore (currently containing
"node_modules/" and "out/") to also include "dist/" so generated build artifacts
are ignored; add a new line with dist/ alongside the existing entries in the
same file.
In `@lib/contracts/reputation-registry/tsconfig.json`:
- Around line 72-74: Enable full TypeScript strict mode by setting "strict":
true in tsconfig.json and removing or un-commenting the individual flags (e.g.,
the commented "strict" and "noImplicitAny") so that the compiler enables all
strict checks instead of only "strictNullChecks"; update the config entry that
currently has "strictNullChecks": true to either replace it with "strict": true
or add "strict": true alongside it to ensure flags like noImplicitAny,
strictFunctionTypes, strictBindCallApply, etc. are active.
- Line 66: Enable the TypeScript "isolatedModules" option in the tsconfig by
uncommenting and setting "isolatedModules": true so each file can be transpiled
independently for better bundler compatibility; locate the "isolatedModules"
entry in tsconfig.json (the line currently commented as // "isolatedModules":
true) and restore it as an active compiler option.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e9df28ce-5e14-4559-a0d5-33e068969213
📒 Files selected for processing (23)
.env.examplelib/contracts/bounty-registry/.gitignorelib/contracts/bounty-registry/README.mdlib/contracts/bounty-registry/package.jsonlib/contracts/bounty-registry/src/index.tslib/contracts/bounty-registry/tsconfig.jsonlib/contracts/core-escrow/.gitignorelib/contracts/core-escrow/README.mdlib/contracts/core-escrow/package.jsonlib/contracts/core-escrow/src/index.tslib/contracts/core-escrow/tsconfig.jsonlib/contracts/index.tslib/contracts/project-registry/.gitignorelib/contracts/project-registry/README.mdlib/contracts/project-registry/package.jsonlib/contracts/project-registry/src/index.tslib/contracts/project-registry/tsconfig.jsonlib/contracts/reputation-registry/.gitignorelib/contracts/reputation-registry/README.mdlib/contracts/reputation-registry/package.jsonlib/contracts/reputation-registry/src/index.tslib/contracts/reputation-registry/tsconfig.jsonlib/contracts/transaction.ts
- Fix buildTransaction to simulate AssembledTransaction and return its XDR
- Add timeout/deadline to submitTransaction polling loop
- Return { hash, getResponse } from submitTransaction for access to results
- Fix CONTRACT_ADDRESSES to throw on mainnet when env var is not set
- Add namespaced re-exports for core-escrow, reputation, project registries
- Update all READMEs: futurenet → testnet, fix Contract → Client in project-registry
- Add dist/ to .gitignore in each contract package
- Update @stellar/stellar-sdk to ^14.6.1 in contract package.json files
- Change buffer pin 6.0.3 → ^6.0.3 in contract package.json files
- Enable strict mode and isolatedModules in contract tsconfig.json files
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
lib/contracts/index.ts (2)
24-32: Consider using stricter types for network configuration maps.Using
Record<string, string>allows arbitrary keys, but these maps are only ever accessed with'testnet'or'public'.♻️ Optional: Use literal union type
-const RPC_URLS: Record<string, string> = { +type StellarNetwork = 'testnet' | 'public'; + +const RPC_URLS: Record<StellarNetwork, string> = { testnet: 'https://soroban-testnet.stellar.org', public: 'https://mainnet.sorobanrpc.com', }; -const NETWORK_PASSPHRASES: Record<string, string> = { +const NETWORK_PASSPHRASES: Record<StellarNetwork, string> = { testnet: 'Test SDF Network ; September 2015', public: 'Public Global Stellar Network ; September 2015', }; + +const STELLAR_NETWORK: StellarNetwork = ...🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/index.ts` around lines 24 - 32, RPC_URLS and NETWORK_PASSPHRASES are typed as Record<string,string>, allowing arbitrary keys; tighten their types by introducing a union type (e.g., Network = 'testnet' | 'public') and change both declarations to use Record<Network,string> or directly type them as { testnet: string; public: string } (or mark them as const with that literal type) so only 'testnet' and 'public' keys are accepted; update any usages of RPC_URLS or NETWORK_PASSPHRASES accordingly to satisfy the new type.
78-84: Consider using const arrow functions per coding guidelines.Multiple function declarations could be converted to const arrow functions for consistency with coding guidelines.
♻️ Optional: Convert to arrow functions
-export function getRpcUrl(): string { - return RPC_URLS[STELLAR_NETWORK]; -} +export const getRpcUrl = (): string => RPC_URLS[STELLAR_NETWORK]; -export function getNetworkPassphrase(): string { - return NETWORK_PASSPHRASES[STELLAR_NETWORK]; -} +export const getNetworkPassphrase = (): string => NETWORK_PASSPHRASES[STELLAR_NETWORK]; -function baseClientOptions(contractId: string): ContractClientOptions { +const baseClientOptions = (contractId: string): ContractClientOptions => ({ - return { - contractId, - networkPassphrase: getNetworkPassphrase(), - rpcUrl: getRpcUrl(), - }; -} + contractId, + networkPassphrase: getNetworkPassphrase(), + rpcUrl: getRpcUrl(), +}); -export function createBountyRegistryClient( - publicKey?: string -): BountyRegistryClient { +export const createBountyRegistryClient = ( + publicKey?: string +): BountyRegistryClient => { return new BountyRegistryClient({ ...baseClientOptions(CONTRACT_ADDRESSES.bountyRegistry), ...(publicKey ? { publicKey } : {}), }); -} +};Apply similar pattern to the other factory functions.
As per coding guidelines: "Prefer const arrow functions with explicit type annotations over function declarations".
Also applies to: 86-92, 100-107, 113-118, 124-131, 137-144
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/index.ts` around lines 78 - 84, Replace the function declarations getRpcUrl and getNetworkPassphrase with const arrow functions that include explicit return type annotations (e.g., const getRpcUrl = (): string => RPC_URLS[STELLAR_NETWORK]; and const getNetworkPassphrase = (): string => NETWORK_PASSPHRASES[STELLAR_NETWORK];) and apply the same conversion pattern to the other factory functions in this module so all follow the "const arrow function with explicit type" guideline.lib/contracts/transaction.ts (1)
9-14: Consider using const arrow functions per coding guidelines.The guidelines prefer const arrow functions with explicit type annotations over function declarations.
♻️ Optional refactor to arrow functions
-export async function simulateContract<T>( - tx: AssembledTransaction<T> -): Promise<T> { +export const simulateContract = async <T>( + tx: AssembledTransaction<T> +): Promise<T> => { await tx.simulate(); return tx.result; -} +}; -export async function buildTransaction<T>( - tx: AssembledTransaction<T> -): Promise<string> { +export const buildTransaction = async <T>( + tx: AssembledTransaction<T> +): Promise<string> => { await tx.simulate(); return tx.toXDR(); -} +}; -export async function submitTransaction( - signedXdr: string, - maxWaitSeconds = 30 -): Promise<SubmitTransactionResult> { +export const submitTransaction = async ( + signedXdr: string, + maxWaitSeconds = 30 +): Promise<SubmitTransactionResult> => {As per coding guidelines: "Prefer const arrow functions with explicit type annotations over function declarations".
Also applies to: 21-26, 39-42
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/contracts/transaction.ts` around lines 9 - 14, Change the exported function declaration simulateContract to a const arrow function with an explicit type annotation (e.g., export const simulateContract: <T>(tx: AssembledTransaction<T>) => Promise<T> = async (tx) => { ... }) and return tx.result as before; apply the same refactor to the other exported functions in this file that use function declarations (the other occurrences mentioned in the review) so they follow the coding guideline of const arrow functions with explicit types. Ensure names (simulateContract and the other exported functions) and their generic/type signatures remain identical and preserve existing behavior and exports.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@lib/contracts/index.ts`:
- Around line 21-22: The STELLAR_NETWORK resolution in lib/contracts/index.ts
currently treats any non-'public' value (including 'mainnet') as 'testnet';
update the logic that sets the STELLAR_NETWORK constant so it treats 'mainnet'
as a synonym for 'public' (matching the pattern in lib/wallet-utils.ts) — e.g.,
normalize process.env.NEXT_PUBLIC_STELLAR_NETWORK and check for both 'public'
and 'mainnet' (or map 'mainnet' → 'public') before falling back to 'testnet', so
functions/classes that use STELLAR_NETWORK get the intended network.
---
Nitpick comments:
In `@lib/contracts/index.ts`:
- Around line 24-32: RPC_URLS and NETWORK_PASSPHRASES are typed as
Record<string,string>, allowing arbitrary keys; tighten their types by
introducing a union type (e.g., Network = 'testnet' | 'public') and change both
declarations to use Record<Network,string> or directly type them as { testnet:
string; public: string } (or mark them as const with that literal type) so only
'testnet' and 'public' keys are accepted; update any usages of RPC_URLS or
NETWORK_PASSPHRASES accordingly to satisfy the new type.
- Around line 78-84: Replace the function declarations getRpcUrl and
getNetworkPassphrase with const arrow functions that include explicit return
type annotations (e.g., const getRpcUrl = (): string =>
RPC_URLS[STELLAR_NETWORK]; and const getNetworkPassphrase = (): string =>
NETWORK_PASSPHRASES[STELLAR_NETWORK];) and apply the same conversion pattern to
the other factory functions in this module so all follow the "const arrow
function with explicit type" guideline.
In `@lib/contracts/transaction.ts`:
- Around line 9-14: Change the exported function declaration simulateContract to
a const arrow function with an explicit type annotation (e.g., export const
simulateContract: <T>(tx: AssembledTransaction<T>) => Promise<T> = async (tx) =>
{ ... }) and return tx.result as before; apply the same refactor to the other
exported functions in this file that use function declarations (the other
occurrences mentioned in the review) so they follow the coding guideline of
const arrow functions with explicit types. Ensure names (simulateContract and
the other exported functions) and their generic/type signatures remain identical
and preserve existing behavior and exports.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 269a5ee4-04f3-49c2-aa5e-fd9fbf733d13
📒 Files selected for processing (18)
lib/contracts/bounty-registry/.gitignorelib/contracts/bounty-registry/README.mdlib/contracts/bounty-registry/package.jsonlib/contracts/bounty-registry/tsconfig.jsonlib/contracts/core-escrow/.gitignorelib/contracts/core-escrow/README.mdlib/contracts/core-escrow/package.jsonlib/contracts/core-escrow/tsconfig.jsonlib/contracts/index.tslib/contracts/project-registry/.gitignorelib/contracts/project-registry/README.mdlib/contracts/project-registry/package.jsonlib/contracts/project-registry/tsconfig.jsonlib/contracts/reputation-registry/.gitignorelib/contracts/reputation-registry/README.mdlib/contracts/reputation-registry/package.jsonlib/contracts/reputation-registry/tsconfig.jsonlib/contracts/transaction.ts
✅ Files skipped from review due to trivial changes (14)
- lib/contracts/bounty-registry/.gitignore
- lib/contracts/core-escrow/.gitignore
- lib/contracts/project-registry/.gitignore
- lib/contracts/reputation-registry/.gitignore
- lib/contracts/core-escrow/tsconfig.json
- lib/contracts/reputation-registry/package.json
- lib/contracts/project-registry/README.md
- lib/contracts/bounty-registry/README.md
- lib/contracts/reputation-registry/tsconfig.json
- lib/contracts/core-escrow/package.json
- lib/contracts/bounty-registry/tsconfig.json
- lib/contracts/reputation-registry/README.md
- lib/contracts/core-escrow/README.md
- lib/contracts/project-registry/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (2)
- lib/contracts/project-registry/package.json
- lib/contracts/bounty-registry/package.json
| const STELLAR_NETWORK = | ||
| process.env.NEXT_PUBLIC_STELLAR_NETWORK === 'public' ? 'public' : 'testnet'; |
There was a problem hiding this comment.
'mainnet' is not recognized as a valid network value.
Unlike lib/wallet-utils.ts which handles 'mainnet' as a synonym for 'public', this file's network resolution silently falls back to 'testnet' if someone sets NEXT_PUBLIC_STELLAR_NETWORK='mainnet'. This could cause unexpected testnet behavior when mainnet was intended.
🔧 Proposed fix to align with wallet-utils.ts pattern
-const STELLAR_NETWORK =
- process.env.NEXT_PUBLIC_STELLAR_NETWORK === 'public' ? 'public' : 'testnet';
+const rawNetwork = process.env.NEXT_PUBLIC_STELLAR_NETWORK || 'testnet';
+const STELLAR_NETWORK =
+ rawNetwork === 'public' || rawNetwork === 'mainnet' ? 'public' : 'testnet';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@lib/contracts/index.ts` around lines 21 - 22, The STELLAR_NETWORK resolution
in lib/contracts/index.ts currently treats any non-'public' value (including
'mainnet') as 'testnet'; update the logic that sets the STELLAR_NETWORK constant
so it treats 'mainnet' as a synonym for 'public' (matching the pattern in
lib/wallet-utils.ts) — e.g., normalize process.env.NEXT_PUBLIC_STELLAR_NETWORK
and check for both 'public' and 'mainnet' (or map 'mainnet' → 'public') before
falling back to 'testnet', so functions/classes that use STELLAR_NETWORK get the
intended network.
Description
Implements on-chain read and transaction-building capabilities for the frontend by generating TypeScript client bindings for the four core Soroban contracts.
@stellar/stellar-sdkwas already present as a dependency — this PR wires it up for direct Soroban contract interaction.Changes
stellar contract bindings typescriptfor all 4 contracts intolib/contracts/<contract-name>/:bounty-registry— Bounty CRUD, applications, submissions, approvalscore-escrow— Fund pools, release slots, fee calculationreputation-registry— Spark Credits, reputation scoringproject-registry— Project details for bounty sponsorslib/contracts/index.ts— Client factories (createBountyRegistryClient,createCoreEscrowClient,createReputationRegistryClient,createProjectRegistryClient) with environment-based address config and network-aware RPC URLs (testnet / mainnet)lib/contracts/transaction.ts— Helpers:simulateContract<T>,buildTransaction(returns unsigned XDR for wallet signing),submitTransaction(polls until confirmed).env.example— AddedNEXT_PUBLIC_*_CONTRACT_IDvars for all 4 contracts with testnet defaultsAcceptance Criteria
simulateContract(e.g.get_bounty,get_application)buildTransactionnpm run type-checkpassesnpm run buildpassesCloses
Closes #139
Summary by CodeRabbit
New Features
Documentation
Chores