# USC SDK

## Getting Started with the USC SDK <a href="#getting-started-with-the-usc-sdk" id="getting-started-with-the-usc-sdk"></a>

The `@gluwa/usc-sdk` is a TypeScript/JavaScript SDK for verifying cross-chain transactions on the Creditcoin network. It lets you generate inclusion proofs for transactions on supported source chains (e.g. Ethereum Sepolia) and verify them on-chain via Creditcoin's precompile contracts.

### Installation <a href="#installation" id="installation"></a>

```sh
npm install @gluwa/usc-sdk
# or
yarn add @gluwa/usc-sdk
```

The SDK requires [ethers.js v6](https://docs.ethers.org/v6/) as a peer dependency.

***

### Core concepts <a href="#core-concepts" id="core-concepts"></a>

A **transaction inclusion proof** answers the question: *"Did this transaction really happen on chain X?"* It is made of two parts:

| Part                 | What it proves                                                                            |
| -------------------- | ----------------------------------------------------------------------------------------- |
| **Merkle proof**     | The transaction is included in a specific block's transaction tree                        |
| **Continuity proof** | That block is part of a sequence of blocks anchored to an attestation point on Creditcoin |

The SDK provides three main components you will work with:

* **`ProverAPIProofGenerator`** — fetches pre-computed proofs from a hosted API (recommended starting point)
* **`PrecompileChainInfoProvider`** — queries attestation state from Creditcoin
* **`PrecompileBlockProver`** — submits proofs to Creditcoin's on-chain verifier

***

### Setting up providers <a href="#setting-up-providers" id="setting-up-providers"></a>

You need two JSON-RPC providers: one for the **source chain** (where the transaction happened) and one for **Creditcoin** (where proofs are verified).

```typescript
import { JsonRpcProvider } from 'ethers';
import { chainInfo, blockProver, proofGenerator } from '@gluwa/usc-sdk';

// Source chain (e.g. Ethereum Sepolia)
const sourceProvider = new JsonRpcProvider('https://sepolia.infura.io/v3/<api_key>'); //or other providers

// Creditcoin USC v2 Testnet, or CC3 Testnet
const creditcoinProvider = new JsonRpcProvider('https://rpc.usc-testnet.creditcoin.network'); //or CC3 Tesnet RPC, https://rpc.cc3-testnet.creditcoin.network
```

***

### Step 1: Query supported chains <a href="#step-1-query-supported-chains" id="step-1-query-supported-chains"></a>

Use `PrecompileChainInfoProvider` to see which source chains are currently supported and find the `chainKey` for the chain you want to prove transactions from.

```typescript
const chainInfoProvider = new chainInfo.PrecompileChainInfoProvider(creditcoinProvider);

const supportedChains = await chainInfoProvider.getSupportedChains();
console.log(supportedChains);
// [{ chainKey: 1, chainId: 11155111, chainName: 'Ethereum Sepolia', chainEncoding: 1 }, ...]
```

The `chainKey` is a Creditcoin-internal identifier for a source chain — it is **not** the same as the chain's EVM `chainId`. You will need it in every subsequent call.

***

### Step 2: Wait for attestation <a href="#step-2-wait-for-attestation" id="step-2-wait-for-attestation"></a>

Before a proof can be generated, the block containing your transaction must be **attested** on Creditcoin. Attestation happens periodically and automatically; you just need to wait for it.

```typescript
const txHash = '0x6fe777442b70a5511f3c443176ae860e50445bd93b663711717996a70c5022ab';
const chainKey = 1; // from Step 1

// Find which block the transaction is in
const tx = await sourceProvider.getTransaction(txHash);
const blockNumber = tx!.blockNumber!;

// Wait until Creditcoin has attested that block
await chainInfoProvider.waitUntilHeightAttested(chainKey, blockNumber);
console.log(`Block ${blockNumber} is attested — ready to generate proof`);
```

`waitUntilHeightAttested` polls Creditcoin at a configurable interval (default: 5 s) and resolves once the target height is confirmed. It will throw after a configurable timeout (default: 60 s).

***

### Step 3: Generate a proof with the Prover <a href="#step-3-generate-a-proof-with-the-proof-gen-api" id="step-3-generate-a-proof-with-the-proof-gen-api"></a>

`ProverAPIProofGenerator` is the simplest way to get a proof. It calls a hosted API that computes and caches proofs on your behalf — no RPC-heavy local computation required.

```typescript
const apiProvider = new proofGenerator.api.ProverAPIProofGenerator(
  chainKey,
  'https://prover.usc-testnet.creditcoin.network',
  5000, // request timeout in ms (optional, default: 5000)
);

const result = await apiProvider.generateProof(txHash);

if (!result.success) {
  throw new Error(`Proof generation failed: ${result.error}`);
}

const proofData = result.data!;
console.log('Block number:', proofData.headerNumber);
console.log('Transaction bytes:', proofData.txBytes);
```

The returned `proofData` object contains everything needed for on-chain verification:

| Field             | Type                     | Description                                               |
| ----------------- | ------------------------ | --------------------------------------------------------- |
| `chainKey`        | `number`                 | Source chain identifier                                   |
| `headerNumber`    | `number`                 | Block number the transaction was in                       |
| `txHash`          | `string`                 | Transaction hash                                          |
| `txBytes`         | `string`                 | ABI-encoded transaction                                   |
| `merkleProof`     | `TransactionMerkleProof` | Siblings in the block's transaction Merkle tree           |
| `continuityProof` | `ContinuityProof`        | Chain of Merkle roots linking the block to an attestation |
| `cached`          | `boolean`                | Whether the proof was served from cache                   |

#### Batch proof generation <a href="#batch-proof-generation" id="batch-proof-generation"></a>

If you need proofs for multiple transactions at once, use `generateBatchProof`. All transactions in a batch share a single continuity proof, which makes on-chain batch verification more efficient.

```typescript
const batchResult = await apiProvider.generateBatchProof([txHash1, txHash2]);

if (!batchResult.success) {
  throw new Error(`Batch proof generation failed: ${batchResult.error}`);
}

const batchData = batchResult.data!;
```

***

### Step 4: Verify the proof on-chain <a href="#step-4-verify-the-proof-on-chain" id="step-4-verify-the-proof-on-chain"></a>

`PrecompileBlockProver` submits proofs to Creditcoin's verifier precompile.

#### Single transaction <a href="#single-transaction" id="single-transaction"></a>

```typescript
const prover = new blockProver.PrecompileBlockProver(creditcoinProvider);

const verified = await prover.verifySingle(
  proofData.chainKey,
  proofData.headerNumber,
  proofData.txBytes,
  proofData.merkleProof,
  proofData.continuityProof,
);

console.log('Verification result:', verified ? 'SUCCESS' : 'FAILED');
```

#### Batch of transactions <a href="#batch-of-transactions" id="batch-of-transactions"></a>

When using batch proofs, you need to flatten the proof data into parallel arrays:

```typescript
const headers: number[] = [];
const txBytesArr: string[] = [];
const merkleProofs = [];

for (const [headerNumber, proofsMap] of batchData.merkleProofs.entries()) {
  for (const [, proofEntry] of proofsMap.entries()) {
    headers.push(headerNumber);
    txBytesArr.push(proofEntry.txBytes);
    merkleProofs.push(proofEntry.merkleProof);
  }
}

const batchVerified = await prover.verifyBatch(
  batchData.chainKey,
  headers,
  txBytesArr,
  merkleProofs,
  batchData.continuityProof,
);

console.log('Batch verification result:', batchVerified ? 'SUCCESS' : 'FAILED');
```

***

### Complete end-to-end example <a href="#complete-end-to-end-example" id="complete-end-to-end-example"></a>

```typescript
import { JsonRpcProvider } from 'ethers';
import { chainInfo, blockProver, proofGenerator } from '@gluwa/usc-sdk';

async function proveTransaction(txHash: string) {
  // Providers
  const sourceProvider = new JsonRpcProvider('https://sepolia.infura.io/v3/<api_key>'); //or other providers
  const creditcoinProvider = new JsonRpcProvider('https://rpc.usc-testnet2.creditcoin.network');  //or CC3 Tesnet RPC, https://rpc.cc3-testnet.creditcoin.network

  const chainInfoProvider = new chainInfo.PrecompileChainInfoProvider(creditcoinProvider);
  const prover = new blockProver.PrecompileBlockProver(creditcoinProvider);

  // Resolve chain key
  const chainKey = 1; // Ethereum Sepolia on USC Testnet2 and CC3 Testnet

  // Find block and wait for attestation
  const tx = await sourceProvider.getTransaction(txHash);
  await chainInfoProvider.waitUntilHeightAttested(chainKey, tx!.blockNumber!);

  // Generate proof via API
  const apiProvider = new proofGenerator.api.ProverAPIProofGenerator(
    chainKey,
    'https://prover.usc-testnet.creditcoin.network',
  );
  const result = await apiProvider.generateProof(txHash);

  if (!result.success || !result.data) {
    throw new Error(`Proof generation failed: ${result.error}`);
  }

  const { chainKey: ck, headerNumber, txBytes, merkleProof, continuityProof } = result.data;

  // Verify on-chain
  const verified = await prover.verifySingle(ck, headerNumber, txBytes, merkleProof, continuityProof);
  console.log('Proof verification:', verified ? 'SUCCESS' : 'FAILED');

  return verified;
}
```

***

### Alternative: Raw proof generator <a href="#alternative-raw-proof-generator" id="alternative-raw-proof-generator"></a>

For advanced use cases where you need full control (e.g. running your own indexer, offline proof computation, or custom block providers), the SDK also ships a `RawProofGenerator` that computes proofs locally by fetching data directly from source chain RPCs.

```typescript
import { EncodingVersion } from '@gluwa/usc-sdk/encoding';

const blockProvider = new proofGenerator.raw.blockProvider.SimpleBlockProvider(sourceProvider);
const rawGenerator = new proofGenerator.raw.RawProofGenerator(
  chainKey,
  blockProvider,
  chainInfoProvider,
  EncodingVersion.V1,
);

const result = await rawGenerator.generateProof(txHash);
```

Both `RawProofGenerator` and `ProverAPIProofGenerator` implement the same `ProofGenerator` interface and produce identical output, so you can swap between them without changing any downstream code.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.creditcoin.org/usc/dapp-builder-infrastructure/usc-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
