@solshield/sdk
v0.3.0
Published
SolShield L2 SDK — Confidential transactions on Solana with Pedersen commitments
Maintainers
Readme
@solshield/sdk
SolShield L2 SDK — Confidential transactions on Solana.
Send private transactions where amounts are hidden by Pedersen commitments and recipients are encrypted. Gas paid exclusively in $SHIELD.
Installation
npm install @solshield/sdk
# or
yarn add @solshield/sdk
# or
pnpm add @solshield/sdkRequirements: Node.js ≥ 18.0.0
Quick Start
import { SolShieldClient, PedersenCommitment } from '@solshield/sdk';
// Connect to testnet
const client = SolShieldClient.testnet();
// Check connectivity
const online = await client.isOnline();
console.log('Sequencer online:', online);
// Send a confidential transaction
// Amount is hidden — only sender knows it's 500 SHIELD
const commitment = PedersenCommitment.commit(500);
const txId = await client.sendConfidential({
commitment: commitment.toHex(),
encryptedRecipient: '0xabc123...', // encrypted with sender's pubkey
gasFee: 1000, // in SHIELD
nonce: 0,
senderPublicKey: '0x...',
signature: '0x...',
});
console.log('Transaction submitted:', txId);
// Wait for finalization
const status = await client.waitForFinalization(txId);
console.log('Finalized in batch:', status);API Reference
SolShieldClient
Constructors
// Connect to testnet (localhost:8080)
const client = SolShieldClient.testnet();
// Connect to mainnet
const client = SolShieldClient.mainnet();
// Connect to custom endpoint
const client = new SolShieldClient('https://your-sequencer.io');Methods
// Submit a confidential transaction
// Returns: transaction UUID
sendConfidential(tx: SendOptions): Promise<string>
// Get transaction status
getTransaction(txId: string): Promise<L2Transaction | null>
// Wait for a tx to be included in a finalized batch
// Returns: batch number
waitForFinalization(txId: string, timeoutMs?: number): Promise<number>
// Get sequencer stats (TPS, batches, burns, etc.)
getStats(): Promise<SequencerStats>
// Get batch details by number
getBatch(batchNumber: number): Promise<L2Batch | null>
// Estimate gas fee for a transaction
estimateGas(): Promise<number>
// Check if sequencer is reachable
isOnline(): Promise<boolean>PedersenCommitment
Cryptographic commitment that hides a value while allowing homomorphic operations.
// Commit to a value (amount in SHIELD units)
const c = PedersenCommitment.commit(1000);
// Verify an opening
const valid = c.verify(); // true
// Serialize for transport
const hex = c.toHex();
// Deserialize
const c2 = PedersenCommitment.fromHex(hex);
// Homomorphic addition — sum of commitments = commitment of sum
// (server-side, not exposed in client SDK)Types
interface L2Transaction {
id: string; // UUID
commitment: string; // hex-encoded Pedersen commitment (32 bytes)
encryptedRecipient: string; // XSalsa20 encrypted recipient pubkey
gasFee: number; // SHIELD units
nonce: number;
senderPublicKey: string;
signature: string;
timestamp: number; // Unix ms
status: TxStatus;
}
type TxStatus =
| 'Pending'
| { InBatch: number }
| { Finalized: string } // Finalized(l1TxHash)
| { Failed: string }; // Failed(reason)
interface L2Batch {
number: number;
txCount: number;
stateRoot: string; // 32-byte hex
prevStateRoot: string;
totalFees: number;
feesBurned: number;
createdAt: number; // Unix ms
l1TxHash: string | null;
}
interface SequencerStats {
totalTransactions: number;
totalBatches: number;
totalBurned: number; // SHIELD units
mempoolSize: number;
uptimeSeconds: number;
}
interface SendOptions {
commitment: string; // hex PedersenCommitment
encryptedRecipient: string;
gasFee: number;
nonce: number;
senderPublicKey: string;
signature: string;
}Error Handling
import {
SolShieldError,
InvalidTransactionError,
InsufficientGasError,
TransactionTimeoutError,
NetworkError,
} from '@solshield/sdk';
try {
await client.sendConfidential(tx);
} catch (err) {
if (err instanceof InsufficientGasError) {
console.error('Not enough gas. Required:', err.required);
} else if (err instanceof TransactionTimeoutError) {
console.error('Tx not finalized within timeout:', err.txId);
} else if (err instanceof NetworkError) {
console.error('Sequencer unreachable:', err.message);
}
}Examples
Full Send Flow
import { SolShieldClient, PedersenCommitment } from '@solshield/sdk';
import { createHash, randomBytes } from 'crypto';
const client = SolShieldClient.testnet();
async function sendPrivate(amount: number, recipientPubkey: string) {
// 1. Create commitment hiding the amount
const commitment = PedersenCommitment.commit(amount);
// 2. Encrypt recipient (simplified — use proper asymmetric encryption in prod)
const encRecipient = '0x' + createHash('sha256')
.update(recipientPubkey)
.digest('hex');
// 3. Get current nonce (track locally or query)
const stats = await client.getStats();
// 4. Build transaction
const gas = await client.estimateGas();
const txId = await client.sendConfidential({
commitment: commitment.toHex(),
encryptedRecipient: encRecipient,
gasFee: gas,
nonce: stats.totalTransactions,
senderPublicKey: '0x' + randomBytes(32).toString('hex'),
signature: '0x' + randomBytes(64).toString('hex'),
});
console.log('Sent:', txId);
// 5. Wait for inclusion
const batch = await client.waitForFinalization(txId, 30_000);
console.log(`Included in batch #${batch}`);
}Monitor Sequencer
const client = SolShieldClient.testnet();
// Poll stats every 5s
setInterval(async () => {
const stats = await client.getStats();
console.log({
txs: stats.totalTransactions,
batches: stats.totalBatches,
burned: (stats.totalBurned / 1_000_000).toFixed(2) + 'M SHIELD',
mempool: stats.mempoolSize,
});
}, 5000);Tokenomics
| Parameter | Value | |----------------|------------------------------| | Token | $SHIELD | | Supply | 100,000,000 SHIELD | | Gas | SHIELD only (no SOL on L2) | | Burn rate | 10% of every transaction fee | | Max burn cap | 30,000,000 SHIELD | | Launch price | $0.10 |
Roadmap
- Phase 1 ✅ — Core sequencer, SDK, Solana contracts
- Phase 2 ✅ — Devnet, 52/52 E2E tests, security audit
- Phase 3 🟡 — Testnet public, Explorer, npm publish
- Phase 4 — Mainnet, DEX listing, TGE, 9M SHIELD airdrop
Security
- Amounts hidden by Pedersen commitments (Ristretto255 curve)
- Recipients encrypted (XSalsa20)
- State integrity via Merkle trees (SHA-256)
- On-chain anchor on Solana L1 every batch
Found a vulnerability? See our Bug Bounty Program.
Links
License
MIT © SolShield Labs
