For the complete documentation index, see llms.txt. This page is also available as Markdown.
Attestcoin SDK (USC SDK)
This page describes the SDK developed by Gluwa to seamlessly interact with the Attestcoin Protocol in a reliable and efficient manner
The term USC (Universal Smart Contract) was replaced with the term Attestcoin Protocol. But repository names and other resources have yet to be updated. The usc-sdk is one such resource.
Getting Started
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
npminstall@gluwa/usc-sdk# oryarnadd@gluwa/usc-sdk
The SDK requires ethers.js v6 as a peer dependency.
Core concepts
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:
ProofBuilder — fetches pre-computed proofs from a hosted builder service (recommended starting point)
PrecompileChainInfoProvider — queries attestation state from Creditcoin
PrecompileBlockProver — submits proofs to Creditcoin's on-chain verifier
Step by step guide
First you'll need two JSON-RPC providers: one for the source chain (where the transaction happened) and one for Creditcoin (where proofs are verified).
Step 1: Query supported chains
Use PrecompileChainInfoProvider to see which source chains are currently supported and find the chainKey for the chain you want to prove transactions from.
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
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.
waitUntilHeightAttested polls the proofBuilder service at a configurable interval (default: 15s) and resolves once the necessary attestation is present in the prover cache. It will throw after a configurable timeout (default: 15m).
Step 3: Generate a proof with the Prover
ProofBuilder 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.
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
If you need proofs for multiple transactions at once, use getBatchProof. All transactions in a batch share a single continuity proof, which makes on-chain batch verification more efficient. The current MAX_BATCH_SIZE is 10 proofs, and these must be within a MAX_BATCH_RANGE of 1000 blocks.
Step 4: Verify the proof on-chain
PrecompileBlockProver submits proofs to Creditcoin's verifier precompile.
Single transaction
Batch of transactions
When using batch proofs, you need to flatten the proof data into parallel arrays:
Complete end-to-end example
Alternative: Raw proof generator
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 RawProofBuilder that computes proofs locally by fetching data directly from source chain RPCs.
Both RawProofBuilder and ProofBuilder implement the same ProofProvider interface and produce identical output, so you can swap between them without changing any downstream code.
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!;
// We create a connection to the proof builder service. We listen
// for new attestations to be cached here rather than listening for
// them directly on-chain. This prevents request timing issues.
const proofBuilder = new proofProvider.service.ProofBuilder(
chainKey,
'https://prover.cc3-testnet.creditcoin.network',
5000, // request timeout in ms (optional, default: 5000)
);
// Wait until Creditcoin has attested that block
await proofBuilder.waitUntilHeightAttested(chainKey, blockNumber);
console.log(`Block ${blockNumber} is attested — ready to generate proof`);
const result = await proofBuilder.getProof(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);