Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Go to -> https://docs.trustlesswork.com/trustless-work/developer-resources/request-api-key
NEXT_PUBLIC_API_KEY=""

# Crossmint demo (optional, required for /crossmint Crossmint mode)
NEXT_PUBLIC_CROSSMINT_API_KEY=

# ROZO Integration (server-side only — NEVER expose in frontend)
# Get credentials from Trustless Work team — see issue #26
ROZO_API_KEY=
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,33 @@ Make sure to set up the following environment variable in your `.env` file:
# TRUSTLESS WORK -> See API KEY Video
NEXT_PUBLIC_API_KEY=""

# CROSSMINT (Required for /crossmint route)
NEXT_PUBLIC_CROSSMINT_API_KEY="your_client_key_here"

```

The wallets are required to interact with the platform.\
---

## Crossmint Integration Spike (Issue #31)

This project contains a dedicated integration spike located at `/crossmint`. It explores using Crossmint's embedded wallet infrastructure to manage the Trustless Work escrow lifecycle.

### Key Finding: The "C vs G" Address Blocker

The spike successfully bridged the Crossmint and Trustless Work SDKs, but identified a critical architectural mismatch:

- **Crossmint** exclusively provides **Soroban Smart Wallets** on Stellar (addresses starting with `C...`).
- **Trustless Work API** currently expects **Traditional Accounts** (addresses starting with `G...`).
- **Result**: Attempting to deploy an escrow returns a `400 Bad Request` with an `invalid version byte` error.

For full technical details, compatibility notes, and next steps, see the **[Crossmint Findings Report](./docs/CROSSMINT_FINDINGS.md)**.

### Accessing the Demo

1. Set `NEXT_PUBLIC_CROSSMINT_API_KEY` in your `.env`.
2. Navigate to `/crossmint`.
3. Log in with email/social.
4. Attempt an escrow deployment to see the terminal state and error logs.

---

Expand Down
30 changes: 30 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Architecture: Crossmint Integration Spike

## Current State
The application implements a dedicated Crossmint-powered transaction flow for the integration spike. It uses a flexible executor abstraction that allows Trustless Work escrow actions to be performed using Crossmint's wallet infrastructure.

### Core Pieces
- `TransactionExecutor`: A wallet-agnostic interface for signing and submitting an unsigned XDR.
- `useCrossmintExecutor`: The primary executor for this spike. It uses the Crossmint Stellar wallet API to sign and submit XDRs generated by Trustless Work.
- `ExecutorProvider`: Orchestrates the active executor. For the spike, it is locked to "crossmint" mode on the demo route.
- `useEscrowsMutations`: Builds unsigned transactions through the Trustless Work SDK, then delegates the terminal execution (signing and submission) to the Crossmint executor.
- `TrustlessWorkCrossmintBridge`: A provider wrapper that initializes the Crossmint SDK, Auth, and Wallet providers along with the Trustless Work adapters.

## Transaction Flow
1. **Request**: The app requests an action (e.g., Deploy) from the Trustless Work SDK.
2. **Build**: Trustless Work returns an unsigned XDR + required metadata (like `contractId`).
3. **Delegate**: The app sends the XDR and metadata to the `useCrossmintExecutor`.
4. **Execute**: The executor uses `StellarWallet.from(wallet).sendTransaction()` to sign and submit to the Stellar network.
5. **Confirm**: The executor returns a terminal execution result containing the transaction `hash`.
6. **Sync**: The app updates its local state and indexer using the returned hash.

## Integration Path
| Component | Responsibility |
| :--- | :--- |
| **Trustless Work SDK** | Smart contract logic, XDR generation |
| **Crossmint SDK** | Key management, transaction signing, network submission |
| **Executor Abstraction** | Bridging the two SDKs without tight coupling |

## Key Decisions
- **Pure Crossmint Flow**: To ensure a clean validation of the spike, the demo route exclusively uses the Crossmint wallet flow, removing fallback dependencies on local browser wallets.
- **Contract ID Routing**: Crossmint requires a `contractId` for all Stellar transactions. The executor maps Trustless Work's returned contract IDs (or Factory IDs for deployments) to this requirement.
66 changes: 66 additions & 0 deletions docs/CROSSMINT_FINDINGS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Crossmint Stellar Integration Findings

## 1. Verified SDK Support & APIs

The following packages have been installed and inspected:

- `@crossmint/client-sdk-react-ui`: Provides the React providers and `useWallet` hook.
- `@crossmint/client-sdk-base`: Base functionality for Crossmint interactions.
- `@crossmint/wallets-sdk`: (Sub-dependency) Contains the `StellarWallet` class and core wallet logic.

### Verified Exports

- **`useWallet`**: Returns `CrossmintWalletBaseContext` which includes:
- `wallet`: A generic `Wallet<Chain>` instance.
- `status`: `"not-loaded" | "in-progress" | "loaded" | "error"`.
- **`StellarWallet`**: A specialized class for Stellar interactions.
- `static from(wallet: Wallet<Chain>): StellarWallet`: Converts a generic wallet to a Stellar wallet.
- `sendTransaction(params: StellarTransactionInput)`: The primary method for transaction submission.

## 2. Key Discovery: Address Format Incompatibility (CRITICAL)

During the runtime validation of this spike, a critical technical blocker was identified:

- **Finding**: Crossmint's Stellar integration exclusively provides **Soroban Smart Wallets** (addresses starting with `C...`).
- **Blocker**: The current version of the Trustless Work API expects **Traditional Stellar Accounts** (addresses starting with `G...`, version byte 48).
- **Error**: Attempting to deploy an escrow using a Crossmint `C...` address results in a `400 Bad Request`:
> `"message": "invalid version byte. expected 48, got 16"`

### Technical Root Cause
The Trustless Work API uses legacy Stellar address decoding logic, which expects an Ed25519 Public Key (version byte 48). Soroban Contract IDs, which Crossmint uses for its account-abstracted Stellar wallets, use version byte 16.

### Investigated Workarounds
- **Wallet Toggling**: Tried forcing `type: "standard"`, `type: "mpc"`, and `accountType: "custodial-eoa"`. Crossmint documentation confirms that Stellar wallets are always Soroban smart contract wallets.
- **Signer Extraction**: Attempted to find an underlying `G...` signer address within the Crossmint `wallet` object. The object is fully abstracted and does not expose a public key compatible with the legacy `G...` format.

## 3. Verified Transaction Workflow (Theoretical)

The following flow was implemented to bridge the two SDKs:

1. **Initialize**: Wrap the application in `CrossmintProvider`, `CrossmintAuthProvider`, and `CrossmintWalletProvider`.
2. **Access**: Use `const { wallet } = useWallet()` to get the generic wallet instance.
3. **Build**: Send the wallet address to Trustless Work SDK to get an unsigned XDR.
4. **Specialize**: Convert to a specialized instance: `const stellarWallet = StellarWallet.from(wallet)`.
5. **Execute**: Call `await stellarWallet.sendTransaction({ transaction: unsignedXdr, contractId: targetId })`.

## 4. Unsupported Assumptions & Known Limitations

- **Raw Signature Export**: CONFIRMED. There is no API to return just a signed XDR without submission.
- **Legacy API Incompatibility**: The current Trustless Work API is not compatible with modern Stellar Smart Wallets (Account Abstraction).

## 5. Recommended Next Steps

1. **Trustless Work API Update**: The server-side validation must be updated to support Soroban Contract IDs (`C...`) as valid signers and role holders.
2. **Crossmint Coordination**: Verify if a "Legacy" Stellar EOA account type can be enabled for specific Project IDs by Crossmint support.
3. **Indexer Updates**: Ensure the Trustless Work indexer can correctly track events emitted by or directed to `C...` addresses.

## Validation Matrix

| Flow | Implemented | Tested | Successful |
| ----------------- | ----------- | ------ | ---------- |
| Deploy Escrow | Yes | Yes | **NO** (400) |
| Update Milestone | Yes | No | No |
| Approve Milestone | Yes | No | No |
| Release Funds | Yes | No | No |

**Conclusion**: The integration is technically sound in terms of SDK bridging, but is blocked by a version-byte address format mismatch on the Trustless Work API.
31 changes: 31 additions & 0 deletions docs/KNOWN_LIMITATIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Known Limitations

## 1. Signed XDR Export

Crossmint's primary model is **Sign + Submit**. It does not currently provide a standard client-side API to return a _signed_ XDR without also submitting it. This means the Trustless Work indexer must rely on the transaction hash returned by Crossmint rather than having the application submit the signed XDR via `sendTransaction`.

## 2. Multi-Wallet Scenarios

While Crossmint supports multiple chains, a single user session is typically tied to one identity (e.g., email). Managing multiple Stellar wallets for different roles (Funder, Approver) within the same browser session may require frequent re-authentication or complex session management.

## 3. Testnet Dependencies

All initial findings and PoC work are targeted at **Stellar Testnet**. Production migration will require updated API keys and potentially different Soroban contract IDs for USDC and other assets.

## 4. Soroban Resource Limits

Crossmint's transaction API handles resource increments and fee bidding. We need to ensure that Trustless Work's generated XDRs are compatible with Crossmint's automated fee management.

## Crossmint Integration Limitations

5. **API Key Requirement**: Crossmint execution requires a valid publishable API key (`NEXT_PUBLIC_CROSSMINT_API_KEY`) to be configured in environment variables.

6. **Contract ID Dependency**: The Crossmint executor requires a `contractId` in the transaction metadata for all escrow operations. This is currently sourced from the payload (`payload.contractId`) or the factory ID for deployments.

7. **Executor Provider Dependency**: Crossmint execution requires the `ExecutorProvider` to be present in the component tree with mode set to "crossmint". This is currently enforced on the `/crossmint` demo route.

8. **Wallet Connection Requirement**: Crossmint execution specifically requires a Crossmint-connected wallet (via email/social login).

9. **Factory Contract ID**: For deploy escrow operations, the Factory contract ID is used as the `contractId` parameter. While this follows Crossmint documentation for tracking factory-based deployments, it should be monitored for any edge cases in escrow-specific deployments.

10. **Transaction Metadata**: The current implementation passes only `contractId` in execution metadata. Additional contextual information (like escrow ID, operation type) could be valuable for debugging and analytics.
115 changes: 115 additions & 0 deletions docs/NEXT_STEPS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Next Steps

## Immediate Actions for Issue #31 Validation

To complete the validation of Issue #31 (Crossmint × Trustless Work Integration Spike), the following steps are required:

### 1. Configure Crossmint API Key

- Obtain a valid Crossmint **publishable** API key (starting with "ck*")
- Add it to `.env.local`: `NEXT_PUBLIC_CROSSMINT_API_KEY="ck_staging_..."`
- Restart the development server

### 2. Runtime Validation Checklist

Execute the following tests to validate each escrow lifecycle flow. Note that until the Trustless Work API supports Soroban Contract IDs (`C...` addresses), terminal success is currently blocked.

#### Deploy Escrow Validation

**Current Expected Failure Behavior:**
1. Navigate to `/crossmint` route.
2. Connect wallet using email/social login.
3. Observe the wallet address starts with `C...`.
4. Submit the escrow deployment form.
5. **Verify Failure**:
- A toast notification appears: "Platform Mismatch Detected".
- Console shows: `invalid version byte. expected 48, got 16`.
- This confirms the system correctly identifies the address format blocker.

**Future Success Criteria (Post-API Fix):**
1. Submit the escrow deployment form.
2. Verify:
- Success toast notification appears.
- Transaction hash is displayed and copied to clipboard.
- Hash links to Stellar testnet explorer.
- Escrow appears in "My Escrows" tab.

#### Update Milestone Status Validation

**Current Expected Failure Behavior:**
1. Since Deployment is blocked, this action cannot be tested via the standard flow.
2. If manually triggered with a `C...` address, observe the `400 invalid version byte` rejection.

**Future Success Criteria (Post-API Fix):**
1. Modify escrow details and submit.
2. Verify:
- Success toast notification appears.
- Transaction hash is displayed.
- UI reflects updated state.

#### Approve Milestone Validation

**Current Expected Failure Behavior:**
1. Blocked by Deployment. Observe rejection if manually attempted with `C...` address.

**Future Success Criteria (Post-API Fix):**
1. Click "Approve Milestone".
2. Verify:
- Success toast notification appears.
- Milestone status changes to "approved" in UI.

#### Release Funds Validation

**Current Expected Failure Behavior:**
1. Blocked by Deployment. Observe rejection if manually attempted with `C...` address.

**Future Success Criteria (Post-API Fix):**
1. Click "Release Funds".
2. Verify:
- Success toast notification appears.
- Funds are transferred on-chain.
- Escrow status updates.

### 3. Evidence Collection

For each validated flow, collect:

- Transaction hash
- Timestamp
- Network confirmation (Stellar testnet)
- Screenshot of successful transaction in explorer
- Console logs showing Crossmint execution path

### 4. Acceptance Criteria Confirmation

Once all flows are validated with transaction hashes, update:

- CROSSMINT_FINDINGS.md validation matrix (set Tested and Successful to Yes)
- Update documentation with actual transaction evidence
- Confirm Issue #31 completion criteria are met

## Future Enhancements (Post-Validation)

These items should be addressed after validating the core integration:

### Production Pilot

- Migrate a small subset of production traffic to Crossmint wallets
- Monitor reliability, latency, and error rates

### Multi-Role Wallet Management

- Investigate Crossmint "Sub-wallets" or "Managed Wallets" for multi-role escrows

### Crossmint Onramp Integration

- Integrate Crossmint's fiat-to-crypto onramp for direct escrow funding

### Security Enhancements

- Implement Webhook listeners for Crossmint-processed transactions
- Use Policy Engines to restrict transaction types for specific wallets

### UI Polishing

- Migrate wallet UI components to use Crossmint's native React UI components
55 changes: 55 additions & 0 deletions docs/TRANSACTION_FLOW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Transaction Flow: Trustless Work × Crossmint

## Sequence Diagram

```mermaid
sequenceDiagram
participant User
participant App
participant TW_SDK as Trustless Work SDK
participant Executor as CrossmintExecutor
participant Crossmint as Crossmint Wallet Infrastructure
participant Stellar as Stellar Network

User->>App: Click "Deploy Escrow"
App->>TW_SDK: Request initialize escrow XDR
TW_SDK-->>App: Return unsigned XDR + contractId
App->>Executor: execute(unsignedXdr, { contractId })
Executor->>Crossmint: StellarWallet.sendTransaction({ transaction, contractId })
Crossmint->>Stellar: Sign and Submit
Stellar-->>Crossmint: Success (hash)
Crossmint-->>Executor: Return Terminal Transaction Result
Executor-->>App: Return normalized ExecutionResult
App->>User: Show success and refresh escrows
```

## Step-by-Step Flow

### 1. Request XDR
When a user initiates an escrow action (Deploy, Fund, Approve, etc.), the app calls the corresponding method in the Trustless Work SDK.

### 2. Receive Unsigned Transaction
The Trustless Work SDK returns an unsigned XDR envelope and the `contractId` of the target smart contract.

### 3. Delegate to Crossmint
The app passes the XDR and `contractId` to the `useCrossmintExecutor`. This executor is specifically designed to bridge Trustless Work XDRs with the Crossmint Stellar Wallet API.

### 4. Crossmint Execution
The executor converts the generic Crossmint wallet to a `StellarWallet` and calls `sendTransaction`. Crossmint handles:
- Securely signing the transaction with the user's embedded wallet.
- Submitting the signed transaction to the Stellar Testnet.
- Managing fees and sequence numbers.

### 5. Confirm and Sync
Once the transaction is confirmed on-chain, Crossmint returns the transaction hash. The app then:
- Displays a success message to the user.
- Triggers the Trustless Work indexer to sync the new state using the hash.
- Refreshes the local UI to reflect the updated escrow status.

## Current Status of Transaction Flow
The Crossmint execution flow is planned and supported by implementation for the following actions, though terminal success is currently blocked by the "C vs G" address mismatch on the Trustless Work API:

- **Deploy Escrow**: Tested (failing with `invalid version byte`).
- **Milestone Updates**: Untested (blocked by deployment).
- **Approvals**: Untested (blocked by deployment).
- **Fund Releases**: Untested (blocked by deployment).
Loading