Title: Crossmint × Trustless Work Integration Spike#33
Conversation
|
Warning Review limit reached
More reviews will be available in 37 minutes and 3 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR implements a complete Crossmint wallet integration for Trustless Work escrow flows on Stellar testnet. It introduces type contracts for transaction execution, dual executor implementations (Wallet Kit and Crossmint), provider infrastructure to route between them, updates all escrow mutations to use the executor abstraction, and delivers demo and PoC pages with comprehensive documentation of findings, transaction flow, and integration limitations. ChangesCrossmint × Trustless Work Integration Spike
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 16
🧹 Nitpick comments (1)
src/components/tw-blocks/escrows/multi-release/initialize-escrow/dialog/useInitializeEscrow.ts (1)
157-161: ⚡ Quick winAvoid
as unknown as ...for mutation response; enforce response contract.This cast drops compile-time safety and can let
response.contractIdbecomeundefinedsilently if the mutation output shape drifts. Prefer typingdeployEscrowat the mutation source and add a runtime contract check before success handling.Suggested hardening
- const response = (await deployEscrow.mutateAsync({ + const response = await deployEscrow.mutateAsync({ payload: finalPayload, type: "multi-release", address: walletAddress || "", - })) as unknown as InitializeMultiReleaseEscrowResponse; + }); + + if (!response || typeof response !== "object" || !("contractId" in response) || !response.contractId) { + throw new Error("Deploy escrow response is missing contractId"); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/tw-blocks/escrows/multi-release/initialize-escrow/dialog/useInitializeEscrow.ts` around lines 157 - 161, The code unsafely forces the mutation result using "as unknown as InitializeMultiReleaseEscrowResponse"; instead, update the deployEscrow mutation's type signature so mutateAsync already returns InitializeMultiReleaseEscrowResponse, remove the "as unknown as" cast in the call to deployEscrow.mutateAsync, and add a runtime check after the call that verifies response.contractId exists (throw or handle error and avoid proceeding to success handling) before using it. Ensure you reference deployEscrow.mutateAsync, the InitializeMultiReleaseEscrowResponse type, and response.contractId when implementing these changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.env.example:
- Line 5: Remove the quotes from the empty environment variable assignment for
NEXT_PUBLIC_CROSSMINT_API_KEY to satisfy dotenv-linter's QuoteCharacter rule;
locate the line containing the variable name NEXT_PUBLIC_CROSSMINT_API_KEY and
change the assignment from a quoted empty string to an unquoted empty value so
it reads NEXT_PUBLIC_CROSSMINT_API_KEY=.
In `@docs/NEXT_STEPS.md`:
- Around line 15-66: The validation checklist in NEXT_STEPS.md currently mixes
expected-success tests (Deploy Escrow Validation, Update Milestone Status
Validation, Approve Milestone Validation, Release Funds Validation) with
behavior that is currently blocked by the version-byte mismatch error; update
the document to split each section into two subsections: "Current expected
failure behavior" (describe the C... vs G... version-byte mismatch, the `400
invalid version byte` response, and steps to reproduce and verify the failure)
and "Future success criteria" (keep the existing success-oriented acceptance
steps under titles like Deploy/Update/Approve/Release once backend/API is
fixed); ensure each validation block (Deploy Escrow Validation, Update Milestone
Status Validation, Approve Milestone Validation, Release Funds Validation) is
updated accordingly so testers know what to expect now vs after the backend
change.
- Around line 9-10: The docs currently instruct users to obtain a Crossmint API
key and place it into NEXT_PUBLIC_CROSSMINT_API_KEY but wrongly allow secret
keys (sk*); update the text to require only publishable client keys (ck*) for
the NEXT_PUBLIC_CROSSMINT_API_KEY variable and remove any mention or acceptance
of sk* keys so the example becomes explicit about using a publishable key (e.g.,
"Obtain a valid Crossmint publishable API key (starting with 'ck*') and add it
to `.env.local` as NEXT_PUBLIC_CROSSMINT_API_KEY").
In `@docs/TRANSACTION_FLOW.md`:
- Around line 50-54: Update the heading text that currently reads "The Crossmint
execution flow is verified for:" in docs/TRANSACTION_FLOW.md so it no longer
claims verification; replace with wording such as "The Crossmint execution flow
is planned/supported by implementation for:" or explicitly reflect actual
validation status (e.g., "Deploy tested (failing); Milestone, Approvals, Fund
Releases: untested") and update the four bullets (Deploy Escrow, Milestone
Updates, Approvals, Fund Releases) to match the chosen phrasing so the document
aligns with the findings matrix rather than claiming verification.
In `@src/app/crossmint-poc/page.tsx`:
- Around line 28-29: TW_FACTORY_CONTRACT_ID is set to a non-functional
placeholder ("CAE5F6...") and is always passed into sendTransaction; make it
configurable and validate it before use. Replace the hardcoded placeholder with
a value loaded from configuration (e.g. an environment variable like
NEXT_PUBLIC_TW_FACTORY_CONTRACT_ID) and update references that pass
TW_FACTORY_CONTRACT_ID into sendTransaction, adding a runtime check (throw or
surface a clear error) if the ID is empty or still contains the placeholder
string (e.g. contains "..." or "CAE5F6"), so the app fails fast with a helpful
message instead of attempting the transaction. Ensure both the declaration of
TW_FACTORY_CONTRACT_ID and the call sites that pass it to sendTransaction are
updated to use the configurable value and include the validation.
- Around line 18-20: The client-side gate currently accepts server keys; update
the validation for CROSSMINT_API_KEY so HAS_VALID_CROSSMINT_KEY only returns
true for client keys (use startsWith("ck_") or equivalent) and explicitly reject
any value that starts with "sk_" — locate the CROSSMINT_API_KEY and
HAS_VALID_CROSSMINT_KEY constants in the client page and change the logic to
allow only ck_ prefixed keys and not sk_ keys.
In `@src/app/crossmint/page.tsx`:
- Around line 178-179: The current expressions const numericAmount =
Number(amount) || 10 and const numericPlatformFee = Number(platformFee) || 5
convert valid zero values to the fallbacks; replace them with checks that only
use the fallback when the parsed value is NaN, e.g. parse Number(amount) into a
temp (v = Number(amount)) and set numericAmount = Number.isNaN(v) ? 10 : v, and
do the same for numericPlatformFee with platformFee and fallback 5; update the
expressions referencing amount/platformFee to use these names (numericAmount,
numericPlatformFee) so zero is preserved.
- Around line 113-115: The debug payload is using unsafe any casts on
crossmintWallet; remove the casts and ensure crossmintWallet is typed so you can
safely access publicKey, owner, and signer. Define or import a proper
CrossmintWallet interface (including publicKey, owner, signer) and annotate the
crossmintWallet variable or its source with that type, then replace
(crossmintWallet as any)?.publicKey / owner / signer with
crossmintWallet?.publicKey / owner / signer to satisfy linting and restore type
safety in the debug payload.
- Around line 55-57: The environment key validation currently accepts
server-side prefixes; update the CHECK so the public key constant
CROSSMINT_API_KEY is only considered valid if it matches the browser-safe
Crossmint prefix (use the exact client prefix, e.g. "ck_") and remove any
allowance for server-side prefixes like "sk"; update the HAS_VALID_CROSSMINT_KEY
expression to only check CROSSMINT_API_KEY.startsWith("ck_") (and keep the
existing fallback to empty string) so no server secret prefixes are treated as
valid in frontend code.
In `@src/components/crossmint-demo/CrossmintMyEscrowsTab.tsx`:
- Around line 79-83: The list rendering in CrossmintMyEscrowsTab uses
escrow.contractId as the React key but pending escrows may lack contractId;
update the filteredEscrows.map callback (where CrossmintEscrowCard is rendered)
to compute a stableKey (use escrow.contractId || escrow.id || another stable
unique field if present) and fall back to a deterministic generated key using
the map index combined with a stable escrow attribute (e.g., createdAt or a
client-side id) if necessary; pass that stableKey as the key prop to
CrossmintEscrowCard and ensure you accept the map index parameter (e.g.,
(escrow, idx) => ...) when generating the fallback.
In `@src/components/providers/TrustlessWorkCrossmintBridge.tsx`:
- Around line 16-17: The check currently allows secret-key prefixes by using
CROSSMINT_API_KEY.startsWith("ck") || CROSSMINT_API_KEY.startsWith("sk"), so
update the validation to only accept publishable keys: ensure the code
references the public env var (NEXT_PUBLIC_CROSSMINT_API_KEY or the variable
used to expose the key to the client) and change HAS_VALID_CROSSMINT_KEY to only
check startsWith("ck"); remove any acceptance of "sk" and add a clear failure
path (log/warn or disable client usage) when the key is not a publishable key so
secret keys are never treated as valid for browser exposure.
- Around line 44-63: The ExecutorProvider is instantiated outside the Crossmint
provider tree so CrossmintEnabledExecutorProvider unconditionally calling
useCrossmintExecutor() runs without a wallet context; move ExecutorProvider
inside the branch where HAS_VALID_CROSSMINT_KEY is true (i.e., inside
CrossmintSdkProvider / CrossmintWalletProvider / CrossmintProvider) so
useCrossmintExecutor() can access useWallet(); keep the crossmintEnabled prop
behavior by only rendering ExecutorProvider with
crossmintEnabled={HAS_VALID_CROSSMINT_KEY} inside the Crossmint branch and leave
the non-crossmint branch rendering children without ExecutorProvider.
In `@src/components/tw-blocks/providers/TrustlessWork.tsx`:
- Around line 25-31: The useEffect in TrustlessWork.tsx is logging provider
details (React.useEffect block that references development, apiKey,
apiKeyPrefix) on every mount; wrap or remove this debug log so it only runs in
development by gating the console.log behind a check for process.env.NODE_ENV
=== "development" (or delete the entire console.log) to avoid exposing
apiKeyPrefix and noisy production logs.
In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts`:
- Around line 203-215: Change both catch clauses in useEscrowsMutations (replace
catch(error: any) with catch(error: unknown)) and add explicit narrowing before
accessing error.response/status/data: detect an Axios-like error (e.g., typeof
error === "object" && error !== null && "response" in error), assert response is
an object, and safely extract response.status and response.data?.message|error;
fallback to a safe string if fields are missing, use that when calling
toast.error and when throwing the new Error. Target the catch blocks in
useEscrowsMutations.ts that handle deploy errors and the second similar block so
all access to error.response and response.data are guarded.
In `@src/components/tw-blocks/wallet-kit/validators.ts`:
- Line 8: The validator is too permissive: isValidWallet currently accepts any
56-char address starting with "G" or "C" which allows Soroban "C" addresses that
the backend rejects; change isValidWallet so it only accepts "C" addresses when
running in the Crossmint integration mode (e.g., when an
integrationMode/isCrossmint flag or current route indicates "/crossmint") and
otherwise require addresses to start with "G" only; locate the isValidWallet
function in this file and add a conditional around the (wallet[0] !== "C")
acceptance that checks the existing integration flag or route helper (or add a
small isCrossmint boolean passed into the validator) so default escrow flows
continue to reject "C" addresses while Crossmint paths remain supported.
In `@src/lib/executors/useExecutors.ts`:
- Around line 31-37: The code currently calls sendTransaction(signedTxXdr) even
when signTransaction may return an empty string; add an explicit guard after
obtaining signedTxXdr in the same block (the signTransaction call) to check for
a falsy/empty value and handle it early (throw a clear error or log and return)
before calling sendTransaction; update the flow around signedTxXdr,
sendTransaction and the subsequent extraction of hash so that sendTransaction is
only invoked with a non-empty signedXdr and the error path reports that signing
produced an empty XDR (reference signedTxXdr, signTransaction and
sendTransaction).
---
Nitpick comments:
In
`@src/components/tw-blocks/escrows/multi-release/initialize-escrow/dialog/useInitializeEscrow.ts`:
- Around line 157-161: The code unsafely forces the mutation result using "as
unknown as InitializeMultiReleaseEscrowResponse"; instead, update the
deployEscrow mutation's type signature so mutateAsync already returns
InitializeMultiReleaseEscrowResponse, remove the "as unknown as" cast in the
call to deployEscrow.mutateAsync, and add a runtime check after the call that
verifies response.contractId exists (throw or handle error and avoid proceeding
to success handling) before using it. Ensure you reference
deployEscrow.mutateAsync, the InitializeMultiReleaseEscrowResponse type, and
response.contractId when implementing these changes.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 65b08199-98ca-41e7-8bee-5b9f872fba93
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (32)
.env.exampleREADME.mddocs/ARCHITECTURE.mddocs/CROSSMINT_FINDINGS.mddocs/KNOWN_LIMITATIONS.mddocs/NEXT_STEPS.mddocs/TRANSACTION_FLOW.mdpackage.jsonsrc/app/crossmint-poc/page.tsxsrc/app/crossmint/layout.tsxsrc/app/crossmint/page.tsxsrc/app/page.tsxsrc/components/crossmint-demo/CrossmintEscrowCard.tsxsrc/components/crossmint-demo/CrossmintMyEscrowsTab.tsxsrc/components/providers/CrossmintProvider.tsxsrc/components/providers/ExecutorProvider.tsxsrc/components/providers/TrustlessWorkCrossmintBridge.tsxsrc/components/tw-blocks/escrows/multi-release/initialize-escrow/dialog/useInitializeEscrow.tssrc/components/tw-blocks/escrows/multi-release/initialize-escrow/form/useInitializeEscrow.tssrc/components/tw-blocks/escrows/multi-release/update-escrow/dialog/useUpdateEscrow.tssrc/components/tw-blocks/escrows/multi-release/update-escrow/form/useUpdateEscrow.tssrc/components/tw-blocks/escrows/single-release/initialize-escrow/dialog/useInitializeEscrow.tssrc/components/tw-blocks/escrows/single-release/initialize-escrow/form/useInitializeEscrow.tssrc/components/tw-blocks/escrows/single-release/update-escrow/dialog/useUpdateEscrow.tssrc/components/tw-blocks/escrows/single-release/update-escrow/form/useUpdateEscrow.tssrc/components/tw-blocks/providers/TrustlessWork.tsxsrc/components/tw-blocks/tanstack/useEscrowsMutations.tssrc/components/tw-blocks/wallet-kit/validators.tssrc/lib/crossmint/escrowAdapter.types.tssrc/lib/crossmint/useCrossmintEscrow.tssrc/lib/executors/types.tssrc/lib/executors/useExecutors.ts
…rk#33 - Isolate crossmint useWallet() to executor context only - Route mutations through executor abstraction - Clean up debug logs and dead code paths
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/components/tw-blocks/tanstack/useEscrowsMutations.ts (1)
177-206: 💤 Low valueConsider extracting the Axios error narrowing logic into a type guard.
The pattern
typeof (error as any).response === "object"works but usesanyas an intermediate cast. A dedicated type guard would improve type safety and reusability across the similar catch blocks.function isAxiosLikeError(error: unknown): error is { response: { status: number; data?: unknown } } { return typeof error === "object" && error !== null && "response" in error && typeof (error as { response?: unknown }).response === "object"; }This is optional for a spike but would help if the pattern spreads further.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts` around lines 177 - 206, The error type narrowing logic in the catch block uses an `any` cast which reduces type safety and the pattern is not reusable. Extract the Axios error checking logic (typeof error === "object" && error !== null && "response" in error && typeof (error as any).response === "object") into a dedicated type guard function called isAxiosLikeError that properly narrows the type without using `any`, then replace the inline condition in the catch block with a call to this type guard.src/app/crossmint-poc/page.tsx (1)
86-94: Add explicit status check before accessingresult.hashfor consistency with codebase patterns.The
sendTransactionmethod returns an object with astatusfield. Other parts of the codebase (e.g.,src/lib/executors/useExecutors.ts) explicitly checkif (response.status === "SUCCESS")before accessing the hash. Apply the same pattern here to make the success condition explicit rather than relying on the type comment.Suggested change
const result = await stellarWallet.sendTransaction({ transaction: unsignedTransaction, contractId: TW_FACTORY_CONTRACT_ID, }); console.log("[PoC] Crossmint Result:", result); - // Result is guaranteed to have hash if status is successful based on types - setLastTxHash(result.hash); + if (result.status === "SUCCESS" && result.hash) { + setLastTxHash(result.hash); + } else { + throw new Error("Transaction did not return success status"); + } toast.success("PoC Success! XDR signed and submitted by Crossmint.");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/crossmint-poc/page.tsx` around lines 86 - 94, Add an explicit status check on the result object returned from the stellarWallet.sendTransaction call before accessing result.hash. Check if result.status equals "SUCCESS" (following the same pattern used in other parts of the codebase like useExecutors.ts) before calling setLastTxHash(result.hash) and displaying the success toast. This makes the success condition explicit in the code rather than relying on the type comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/app/crossmint-poc/page.tsx`:
- Around line 86-94: Add an explicit status check on the result object returned
from the stellarWallet.sendTransaction call before accessing result.hash. Check
if result.status equals "SUCCESS" (following the same pattern used in other
parts of the codebase like useExecutors.ts) before calling
setLastTxHash(result.hash) and displaying the success toast. This makes the
success condition explicit in the code rather than relying on the type comment.
In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts`:
- Around line 177-206: The error type narrowing logic in the catch block uses an
`any` cast which reduces type safety and the pattern is not reusable. Extract
the Axios error checking logic (typeof error === "object" && error !== null &&
"response" in error && typeof (error as any).response === "object") into a
dedicated type guard function called isAxiosLikeError that properly narrows the
type without using `any`, then replace the inline condition in the catch block
with a call to this type guard.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 747d4577-35f7-4c75-a4aa-2231cc17be56
📒 Files selected for processing (12)
.env.exampledocs/NEXT_STEPS.mddocs/TRANSACTION_FLOW.mdsrc/app/crossmint-poc/page.tsxsrc/app/crossmint/page.tsxsrc/components/crossmint-demo/CrossmintMyEscrowsTab.tsxsrc/components/providers/CrossmintProvider.tsxsrc/components/providers/TrustlessWorkCrossmintBridge.tsxsrc/components/tw-blocks/providers/TrustlessWork.tsxsrc/components/tw-blocks/tanstack/useEscrowsMutations.tssrc/components/tw-blocks/wallet-kit/validators.tssrc/lib/executors/useExecutors.ts
✅ Files skipped from review due to trivial changes (3)
- docs/TRANSACTION_FLOW.md
- docs/NEXT_STEPS.md
- .env.example
🚧 Files skipped from review as they are similar to previous changes (5)
- src/components/providers/TrustlessWorkCrossmintBridge.tsx
- src/components/crossmint-demo/CrossmintMyEscrowsTab.tsx
- src/components/tw-blocks/providers/TrustlessWork.tsx
- src/lib/executors/useExecutors.ts
- src/app/crossmint/page.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/tw-blocks/tanstack/useEscrowsMutations.ts (1)
112-115:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPreserve the caller-provided signer when Wallet Kit runs through
ExecutorProvider.With an executor context present, this branch ignores
address; in"wallet-kit"mode the upstream executor signs withwalletAddressfrom context instead. That makes provider-wrapped routes behave differently from the fallback path and can sign with the wrong/stale wallet when callers pass a role-specific signer address.🔧 Minimal local fix
- // Use the executor from context if available (handles both crossmint and wallet-kit modes) - if (executorContext) { + // Use the executor from context if available. In wallet-kit mode, keep honoring + // the explicit signer address passed by mutation callers. + if (executorContext && !(executorContext.mode === "wallet-kit" && address)) { return executorContext.executor.execute(unsignedTransaction, metadata); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts` around lines 112 - 115, The executorContext.executor.execute() call in the conditional branch ignores the caller-provided address parameter, which causes the function to use the walletAddress from context instead of the signer specified by the caller. This creates inconsistent behavior between the executor-context path and the fallback path. Pass the address parameter to the execute call to preserve the caller-provided signer and ensure consistent behavior across both code paths, particularly for role-specific signer addresses in "wallet-kit" mode.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts`:
- Around line 46-59: The getAxiosErrorMessage function currently exposes raw API
response bodies through JSON.stringify(data) and uses a hard-coded
operation-generic fallback message. Remove the JSON.stringify(data) fallback to
prevent surfacing arbitrary backend payloads in user-facing toasts. Modify the
function signature to accept an operation-specific fallback parameter (for
example, deploy vs update) and use that instead of the hard-coded "Deploy
failed" string. Update all call sites of getAxiosErrorMessage to pass the
appropriate operation-specific fallback text.
---
Outside diff comments:
In `@src/components/tw-blocks/tanstack/useEscrowsMutations.ts`:
- Around line 112-115: The executorContext.executor.execute() call in the
conditional branch ignores the caller-provided address parameter, which causes
the function to use the walletAddress from context instead of the signer
specified by the caller. This creates inconsistent behavior between the
executor-context path and the fallback path. Pass the address parameter to the
execute call to preserve the caller-provided signer and ensure consistent
behavior across both code paths, particularly for role-specific signer addresses
in "wallet-kit" mode.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6f1d54a4-c4d9-42d8-9989-eebd7b4cd386
📒 Files selected for processing (1)
src/components/tw-blocks/tanstack/useEscrowsMutations.ts
Summary
This PR implements the integration spike for using Crossmint wallet infrastructure with Trustless Work escrows on Stellar. While the technical bridging of the two SDKs is fully implemented, a critical architectural mismatch was identified that currently blocks terminal execution on the Trustless Work API.
Changes
/crossmintdemo route with escrow lifecycle UICvsG) blockerdocs/CROSSMINT_FINDINGS.mdKey Deliverables
/crossmintpage where users can log in via email/social and attempt the escrow lifecycle.CROSSMINT_FINDINGS.md(/docs/CROSSMINT_FINDINGS.md) documenting the discovery, root cause, and recommended next steps.Critical Finding: The "C vs G" Address Blocker
During runtime validation, we discovered that Crossmint exclusively provides Soroban Smart Wallets (
C... addresses) on Stellar. The current Trustless Work API strictly requires Traditional Accounts (G... addresses). This results in a400Bad Request with an invalid version byte error.This spike successfully proves the integration path but highlights the need for the Trustless Work API to be updated to support Soroban Contract IDs as valid signers/roles.
How to Test
NEXT_PUBLIC_CROSSMINT_API_KEYin your.env./crossmint.Deploy Escrowto observe the platform mismatch detection and terminal error logs.Documentation Updated
docs/ARCHITECTURE.mddocs/TRANSACTION_FLOW.mddocs/KNOWN_LIMITATIONS.mddocs/CROSSMINT_FINDINGS.md(New)README.md(Spike summary added)Closes #31
Summary by CodeRabbit
NEXT_PUBLIC_CROSSMINT_API_KEYto environment examples.