Production-grade blockchain infrastructure SDK for PetAd. Provides secure, reusable utilities and abstractions for escrow, custody guarantees, and transaction management on the Stellar network.
⚠️ SECURITY CRITICAL: This SDK handles blockchain transactions and private keys. It requires rigorous testing and external security audits before production use.
- Overview
- Purpose
- Features
- Tech Stack
- Prerequisites
- Installation
- Configuration
- Quick Start
- Usage Examples
- Project Structure
- API Reference
- Testing
- Security Guidelines
- Scripts
- Deployment Tools
- Contributing
- Audit & Security
- License
PetAd Chain is the blockchain infrastructure layer powering the PetAd platform. It serves as a standalone TypeScript SDK that abstracts the complexity of Stellar blockchain operations into clean, type-safe APIs.
This repository is designed to be:
- 📦 Modular - Use as a library in your backend or as a standalone service
- 🔒 Security-First - Built with security best practices and external audit readiness
- 🧪 Well-Tested - Comprehensive test suite covering all escrow scenarios
- 🎯 Production-Ready - Battle-tested abstractions for real-world blockchain operations
┌─────────────────────────────────────────────────────┐
│ PetAd Backend (NestJS) │
│ Application Logic Layer │
└───────────────────┬─────────────────────────────────┘
│
│ imports @petad/stellar-sdk
▼
┌─────────────────────────────────────────────────────┐
│ PetAd Chain SDK (This Repository) │
│ ┌──────────────────────────────────────────┐ │
│ │ Escrow Utilities │ │
│ └──────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────┐ │
│ │ Transaction Builders │ │
│ └──────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────┐ │
│ │ Account Management │ │
│ └──────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────┐ │
│ │ Horizon Client Wrapper │ │
│ └──────────────────────────────────────────┘ │
└───────────────────┬─────────────────────────────────┘
│
│ Stellar SDK
▼
┌─────────────────────────────────────────────────────┐
│ Stellar Network (Testnet/Mainnet) │
│ Blockchain Layer │
└─────────────────────────────────────────────────────┘
This SDK abstracts blockchain complexity and exposes clean, type-safe APIs for:
| Feature | Description |
|---|---|
| Escrow Account Creation | Generate 2-of-3 multisig escrow accounts with time locks |
| Multisig Orchestration | Build and sign multi-signature transactions |
| Custody Locking | Lock funds in escrow for time-bound custody agreements |
| Automatic Release | Time-based or condition-based escrow settlement |
| Trust Hash Anchoring | Permanently record trust snapshots on-chain with memo |
| Event Verification | Cryptographically verify on-chain event anchoring |
| Network Abstraction | Seamless switching between testnet and mainnet |
| Custody Locking | Lock funds in escrow for time-bound custody agreements |
| Automatic Release | Time-based or condition-based escrow settlement |
| Event Verification | Cryptographically verify on-chain event anchoring |
| Network Abstraction | Seamless switching between testnet and mainnet |
- ✅ Type-Safe - Full TypeScript support with strict typing
- ✅ Idempotent - Safe to retry all operations
- ✅ Testnet Support - Complete testing infrastructure
- ✅ Error Handling - Comprehensive error types and recovery
- ✅ Transaction Monitoring - Track transaction status and confirmations
- ✅ Key Management - Secure key handling with HSM support
- ✅ Gas Optimization - Minimal transaction fees
- ✅ Event Anchoring - Hash-based event verification on-chain
| Technology | Version | Purpose |
|---|---|---|
| TypeScript | 5.0+ | Type-safe development |
| Stellar SDK | Latest | Blockchain interaction |
| Node.js | 20+ | Runtime environment |
| Jest | Latest | Testing framework |
| ESLint | Latest | Code quality |
| Prettier | Latest | Code formatting |
- Node.js
>= 20.0.0 - npm
>= 10.0.0or pnpm>= 8.0.0 - Stellar Account (testnet or mainnet)
- TypeScript knowledge recommended
Verify installations:
node --version
npm --versionInstall in your project:
npm install @petad/stellar-sdkOr with pnpm:
pnpm add @petad/stellar-sdkOr with yarn:
yarn add @petad/stellar-sdkClone and build locally:
# 1. Clone the repository
git clone https://github.com/petad/petad-chain.git
cd petad-chain
# 2. Install dependencies
npm install
# 3. Build the SDK
npm run build
# 4. Link locally (for development)
npm linkIn your project:
npm link @petad/stellar-sdkCreate a .env file in your project root:
# Network Configuration
STELLAR_NETWORK=testnet # Options: testnet | public
STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org
# Platform Keys (for escrow operations)
MASTER_SECRET_KEY=S... # Platform escrow signing key
MASTER_PUBLIC_KEY=G... # Platform public address
# Optional: Advanced Configuration
STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
TRANSACTION_TIMEOUT=180 # seconds
MAX_FEE=10000 # stroops (0.001 XLM)-
Generate keypair:
npm run generate-keypair
-
Fund account:
- Visit: https://friendbot.stellar.org
- Paste your public key (G...)
- Get 10,000 test XLM
-
Verify account:
npm run verify-account -- YOUR_PUBLIC_KEY
import { StellarSDK } from '@petad/stellar-sdk';
// Initialize SDK
const sdk = new StellarSDK({
network: 'testnet',
horizonUrl: 'https://horizon-testnet.stellar.org',
masterSecretKey: process.env.MASTER_SECRET_KEY
});
// Create an escrow account
const escrow = await sdk.escrow.createAccount({
adopterPublicKey: 'G...',
ownerPublicKey: 'G...',
depositAmount: '100', // XLM
duration: 30 // days
});
console.log('Escrow created:', escrow.accountId);
console.log('Transaction hash:', escrow.transactionHash);Create a 2-of-3 multisig escrow account for adoption deposits:
import { createEscrowAccount } from '@petad/stellar-sdk';
async function setupAdoptionEscrow() {
const escrow = await createEscrowAccount({
// Signer 1: Adopter
adopterPublicKey: 'GADOPTER...',
// Signer 2: Pet Owner/Shelter
ownerPublicKey: 'GOWNER...',
// Signer 3: Platform (automatically added)
// platformPublicKey is read from env
// Escrow configuration
depositAmount: '500', // 500 XLM deposit
adoptionFee: '50', // 50 XLM platform fee
// Time lock (optional)
unlockDate: new Date('2026-03-15'),
// Metadata
petId: 'pet-12345',
adoptionId: 'adoption-67890'
});
return {
escrowAccountId: escrow.accountId,
transactionHash: escrow.hash,
signers: escrow.signers,
thresholds: escrow.thresholds
};
}Response:
{
escrowAccountId: 'GESCROW...',
transactionHash: '0x123abc...',
signers: [
{ publicKey: 'GADOPTER...', weight: 1 },
{ publicKey: 'GOWNER...', weight: 1 },
{ publicKey: 'GPLATFORM...', weight: 1 }
],
thresholds: {
low: 0,
medium: 2, // 2-of-3 required
high: 2
}
}Build and sign a multisig transaction to release escrow funds:
import { buildMultisigTransaction, signTransaction } from '@petad/stellar-sdk';
async function releaseEscrowFunds() {
// 1. Build transaction
const transaction = await buildMultisigTransaction({
sourceAccount: 'GESCROW...', // Escrow account
operations: [
{
type: 'payment',
destination: 'GOWNER...',
amount: '450', // Release to owner
asset: 'native' // XLM
},
{
type: 'payment',
destination: 'GPLATFORM...',
amount: '50', // Platform fee
asset: 'native'
}
],
memo: 'Adoption #67890 - Completed',
fee: '1000' // 0.0001 XLM
});
// 2. Sign with adopter key
const adopterSigned = await signTransaction(
transaction,
'SADOPTERSECRET...'
);
// 3. Sign with platform key
const platformSigned = await signTransaction(
adopterSigned,
process.env.MASTER_SECRET_KEY
);
// 4. Submit to network (2-of-3 threshold met)
const result = await sdk.horizon.submitTransaction(platformSigned);
return {
successful: result.successful,
hash: result.hash,
ledger: result.ledger
};
}Lock funds for temporary custody with automatic time-based release:
import { lockCustodyFunds, scheduleCustodyRelease } from '@petad/stellar-sdk';
async function setupTemporaryCustody() {
// 1. Lock custody deposit
const lock = await lockCustodyFunds({
custodianPublicKey: 'GCUSTODIAN...',
ownerPublicKey: 'GOWNER...',
depositAmount: '200',
durationDays: 14,
// Conditions for early release
conditions: {
noViolations: true,
petReturned: true
}
});
// 2. Schedule automatic release
const releaseSchedule = await scheduleCustodyRelease({
escrowAccountId: lock.accountId,
releaseDate: lock.unlockDate,
// Release distribution
distribution: [
{ recipient: 'GOWNER...', percentage: 95 },
{ recipient: 'GPLATFORM...', percentage: 5 }
]
});
return {
custodyId: lock.accountId,
lockedAmount: lock.amount,
unlockDate: lock.unlockDate,
scheduledReleaseId: releaseSchedule.id
};
}Permanently record trust snapshots on the Stellar blockchain:
import PetAdChain from '@petad/stellar-sdk';
import crypto from 'crypto';
async function anchorTrustSnapshot() {
const chain = new PetAdChain({ useTestnet: false });
// Create hash of trust data (max 28 bytes)
const trustData = {
userId: 'user-123',
score: 95,
timestamp: Date.now()
};
const hash = crypto
.createHash('sha256')
.update(JSON.stringify(trustData))
.digest('hex')
.substring(0, 28); // Truncate to 28 bytes
// Anchor on blockchain (0.00001 XLM self-payment)
const result = await chain.anchorTrustHash(hash, process.env.SECRET_KEY!);
return {
trustHash: hash,
transactionHash: result.hash,
verified: result.verified,
timestamp: result.timestamp
};
}
// CLI usage
// npm run anchor-trust-hash -- --hash "trust-snapshot-123"Key Features:
- Minimal cost: 0.00001 XLM + network fee
- Immutable record with blockchain timestamp
- Hash visible in transaction memo
- Maximum hash size: 28 bytes
See TRUST_HASH_README.md for detailed documentation.
Verify that an event was properly anchored on the Stellar blockchain:
import { verifyEventHash, anchorEventHash } from '@petad/stellar-sdk';
// Anchor an event
async function anchorAdoptionEvent(adoptionData: any) {
const eventHash = crypto
.createHash('sha256')
.update(JSON.stringify(adoptionData))
.digest('hex');
const anchoring = await anchorEventHash({
hash: eventHash,
eventType: 'ADOPTION_COMPLETED',
metadata: {
adoptionId: adoptionData.id,
timestamp: new Date().toISOString()
}
});
return {
eventHash,
transactionHash: anchoring.txHash,
ledger: anchoring.ledger
};
}
// Verify the event later
async function verifyAdoption(eventHash: string, txHash: string) {
const verification = await verifyEventHash({
expectedHash: eventHash,
transactionHash: txHash
});
return {
verified: verification.isValid,
timestamp: verification.timestamp,
ledger: verification.ledger,
confirmations: verification.confirmations
};
}src/
├── escrow/ # Escrow lifecycle management
│ ├── create.ts # Account creation
│ ├── lock.ts # Fund locking
│ ├── release.ts # Settlement logic
│ ├── dispute.ts # Dispute handling
│ └── types.ts # Type definitions
│
├── accounts/ # Account utilities
│ ├── create.ts # Account generation
│ ├── fund.ts # Funding operations
│ ├── multisig.ts # Multisig configuration
│ └── keypair.ts # Key management
│
├── transactions/ # Transaction builders
│ ├── builder.ts # Transaction construction
│ ├── signer.ts # Signing utilities
│ ├── submit.ts # Network submission
│ └── monitor.ts # Status tracking
│
├── clients/ # Network clients
│ ├── horizon.ts # Horizon API wrapper
│ ├── friendbot.ts # Testnet funding
│ └── network.ts # Network utilities
│
├── utils/ # Shared utilities
│ ├── crypto.ts # Hashing, signing
│ ├── errors.ts # Error types
│ ├── validation.ts # Input validation
│ └── constants.ts # Network constants
│
├── index.ts # Main SDK export
└── types/ # Global type definitions
├── escrow.ts
├── transaction.ts
└── network.ts
Main SDK entry point.
class StellarSDK {
constructor(config: SDKConfig);
escrow: EscrowManager;
accounts: AccountManager;
transactions: TransactionManager;
horizon: HorizonClient;
}Handles escrow operations.
class EscrowManager {
createAccount(params: CreateEscrowParams): Promise<EscrowAccount>;
lockFunds(params: LockFundsParams): Promise<LockResult>;
releaseFunds(params: ReleaseParams): Promise<ReleaseResult>;
handleDispute(params: DisputeParams): Promise<DisputeResult>;
}Builds and manages transactions.
class TransactionManager {
build(params: BuildParams): Promise<Transaction>;
sign(tx: Transaction, secretKey: string): Promise<Transaction>;
submit(tx: Transaction): Promise<SubmitResult>;
monitor(hash: string): Promise<TransactionStatus>;
}interface CreateEscrowParams {
adopterPublicKey: string;
ownerPublicKey: string;
depositAmount: string;
adoptionFee?: string;
unlockDate?: Date;
metadata?: Record<string, any>;
}
interface EscrowAccount {
accountId: string;
transactionHash: string;
signers: Signer[];
thresholds: Thresholds;
unlockDate?: Date;
}
interface Signer {
publicKey: string;
weight: number;
}
interface Thresholds {
low: number;
medium: number;
high: number;
}✅ Transaction Review
- Always verify transaction details before signing
- Implement multi-party approval for high-value transactions
- Log all transactions for audit trails
✅ Network Validation
- Verify network before submitting transactions
- Use testnet for all development and testing
- Double-check Horizon URLs
✅ Input Validation
- Validate all user inputs
- Sanitize public keys and amounts
- Reject malformed transaction data
✅ Error Handling
- Never expose secret keys in error messages
- Log errors securely (no sensitive data)
- Implement proper retry logic
✅ Audit Trail
- Log all escrow operations
- Maintain immutable audit logs
- Monitor for suspicious activity
- External security audit completed
- Penetration testing performed
- Key rotation procedures documented
- Incident response plan in place
- Insurance/liability coverage secured
- Legal review of smart contract logic
- Disaster recovery plan tested
| Script | Description |
|---|---|
npm run build |
Compile TypeScript to JavaScript |
npm run dev |
Development mode with watch |
npm run lint |
Run ESLint |
npm run format |
Format with Prettier |
npm run type-check |
TypeScript type checking |
npm run generate-keypair |
Generate new Stellar keypair |
npm run verify-account |
Verify account on network |
The scripts/ directory contains deployment utilities:
node scripts/create-escrow.js --adopter GADOPTER... --owner GOWNER... --amount 500node scripts/monitor-tx.js --hash 0x123abc...node scripts/broadcast.js --file transaction.json --network testnetnode scripts/verify-event.js --hash sha256hash --tx 0x456def...We welcome blockchain-focused contributions!
- 🔐 Escrow Optimizations - Gas efficiency, feature enhancements
- 🛡️ Security Hardening - Vulnerability fixes, best practices
- 📚 Documentation - Examples, guides, API docs
- 🔧 Tooling - CLI utilities, monitoring dashboards
- Fork the repository
- Create feature branch (
git checkout -b feature/escrow-improvement) - Write tests for new functionality
- Ensure all tests pass (
npm test) - Lint your code (
npm run lint) - Commit changes (
git commit -m 'feat: improve escrow gas efficiency') - Push to fork (
git push origin feature/escrow-improvement) - Open Pull Request
Pull requests affecting these areas require 2+ maintainer reviews:
- Escrow logic (
src/escrow/) - Transaction signing (
src/transactions/signer.ts) - Key management (
src/accounts/keypair.ts) - Network submission (
src/transactions/submit.ts)
See CONTRIBUTING.md for detailed guidelines.
This SDK is security-critical infrastructure that handles:
- Private key operations
- Financial transactions
- Escrow fund management
- Stellar network downtime affects all operations
- Transaction fees subject to network congestion
- Testnet resets may clear historical data
- Time locks require network time synchronization
This project is licensed under the MIT License - see the LICENSE file for details.
- Built for transparent, trustworthy pet adoption
- Powered by Stellar blockchain technology
- Inspired by the need of reliable pet adoptioin in africa and in peer-to-peer custody agreements
- Backend: petad-backend - NestJS API server
- Frontend: petad-frontend - React web app
Made with ⛓️ by the PetAd Team
Building blockchain trust infrastructure, one escrow at a time.