Building on Stellar means solving the same problems over and over — wallet connection, event listening, payment forms, testing mocks. MergeLabs solves them once so you can focus on your product.
MergeLabs is a TypeScript-first monorepo providing production-ready packages for the Stellar and Soroban blockchain ecosystem. Built with strict typing, comprehensive testing, and real-world use cases in mind.
- Real transaction building — Not mock implementations. Real Horizon payments, trustlines, and Soroban contract calls
- Production-tested — Exponential backoff, error handling, retry logic built-in
- Developer experience — Type-safe APIs, JSDoc comments, headless components
- Wallet agnostic — Freighter integration with extensibility for more wallets
| Package | Version | Description | NPM |
|---|---|---|---|
@astronlabs/notify |
Real-time Soroban event streaming with XDR decoding | Docs | |
@astronlabs/mock |
Mock RPC, contracts, and wallets for testing | Docs | |
@astronlabs/hooks |
React hooks for Stellar integration | Docs | |
@astronlabs/forms |
Headless form components | Docs |
# Using pnpm (recommended)
pnpm add @astronlabs/hooks @astronlabs/forms
# Using npm
npm install @astronlabs/hooks @astronlabs/forms
# Using yarn
yarn add @astronlabs/hooks @astronlabs/formsimport { StellarProvider, useFreighter, useBalance } from '@astronlabs/hooks';
function App() {
return (
<StellarProvider
config={{
network: 'testnet',
rpcUrl: 'https://soroban-testnet.stellar.org',
}}
>
<Wallet />
</StellarProvider>
);
}
function Wallet() {
const { connect, publicKey, connected } = useFreighter();
const { balance, loading } = useBalance(publicKey ?? '');
if (!connected) {
return <button onClick={connect}>Connect Freighter</button>;
}
return (
<div>
<p>Address: {publicKey}</p>
<p>Balance: {loading ? 'Loading...' : balance}</p>
</div>
);
}Real-time event streaming from Soroban smart contracts with automatic XDR decoding.
- Polls Soroban RPC
getEventswith configurable intervals - Automatic XDR decoding to JavaScript objects
- Built-in retry logic with exponential backoff
- Type-safe event filtering
import { StellarNotify } from '@astronlabs/notify';
const notify = new StellarNotify({
rpcUrl: 'https://soroban-testnet.stellar.org',
network: 'testnet',
pollInterval: 5000,
});
// Listen for token transfers
const unsubscribe = notify.onTransfer('CONTRACT_ID', (event) => {
console.log('Transfer:', {
from: event.data.from,
to: event.data.to,
amount: event.data.amount,
});
});
// Cleanup
unsubscribe();
notify.destroy();Mock implementations for isolated testing without network dependencies.
- Mock RPC server with simulated latency
- Mock contracts with state management
- Mock Freighter wallet for testing
- Pre-built fixtures for common scenarios
import { MockRpc, MockContract, tokenFixture } from '@astronlabs/mock';
const rpc = new MockRpc({ latency: 100 });
const token = new MockContract(rpc, tokenFixture);
// Simulate events
token.emit('transfer', {
from: 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
to: 'GBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
amount: 10000000n,
});React hooks for Stellar blockchain interactions.
useFreighter— Wallet connection and transaction signinguseBalance— Account balance fetching with cachinguseSendPayment— Real payment transactions (Horizon)useContractCall— Soroban contract invocation (simulate → sign → submit)useTransaction— Transaction status polling with backoff
import { useSendPayment } from '@astronlabs/hooks';
function PaymentForm() {
const { send, loading, error, result } = useSendPayment();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const result = await send({
destination: 'G...',
amount: '10',
memo: 'Payment for services',
});
console.log('Transaction:', result.txHash);
};
return (
<form onSubmit={handleSubmit}>
<button disabled={loading}>
{loading ? 'Sending...' : 'Send 10 XLM'}
</button>
{error && <p>Error: {error.message}</p>}
{result && <p>Success! TX: {result.txHash}</p>}
</form>
);
}Headless form components with Stellar transaction integration.
- Render props pattern for full UI control
- Built-in validation
- Automatic wallet connection checks
- Error handling with user-friendly messages
import { SendPaymentForm } from '@astronlabs/forms';
<SendPaymentForm
onSuccess={(result) => console.log('Sent:', result.txHash)}
onError={(err) => console.error('Failed:', err.message)}
>
{({ handleSubmit, loading, values, onChange, errors }) => (
<form onSubmit={handleSubmit}>
<input
name="destination"
value={values.destination}
onChange={onChange}
placeholder="G..."
/>
{errors.destination && <span>{errors.destination}</span>}
<input
name="amount"
value={values.amount}
onChange={onChange}
placeholder="Amount in XLM"
/>
{errors.amount && <span>{errors.amount}</span>}
<button type="submit" disabled={loading}>
{loading ? 'Sending...' : 'Send Payment'}
</button>
</form>
)}
</SendPaymentForm>- Node.js 18+
- pnpm 8+
# Clone the repository
git clone https://github.com/AstronLabs/MergeLabs.git
cd MergeLabs
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Run type checking
pnpm typecheck| Command | Description |
|---|---|
pnpm build |
Build all packages |
pnpm test |
Run unit tests |
pnpm test:integration |
Run tests against live testnet |
pnpm coverage |
Generate coverage reports |
pnpm lint |
Run linting |
pnpm typecheck |
Run TypeScript checks |
pnpm changeset |
Create a changeset for release |
MergeLabs/
├── packages/
│ ├── notify/ # Event streaming
│ ├── mock/ # Testing utilities
│ ├── hooks/ # React hooks
│ └── forms/ # Form components
├── .github/
│ └── workflows/ # CI/CD pipelines
├── pnpm-workspace.yaml # pnpm workspace config
└── README.md # This file
# Run all tests
pnpm test
# Run tests for specific package
pnpm --filter @astronlabs/notify test
# Watch mode
pnpm --filter @astronlabs/hooks test:watchTests that run against live Stellar testnet infrastructure:
pnpm test:integrationThese verify real RPC calls, Horizon queries, and event polling work correctly.
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Run the test suite (
pnpm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Core hooks with real transaction support
- Event streaming with XDR decoding
- Multi-wallet adapter system (xBull, Albedo, LOBSTR)
- Soroswap DEX integration hooks
- Blend lending protocol support
- CLI tool for project scaffolding
- Contract type generator from WASM specs
MIT © AstronLabs
- Stellar Development Foundation for the Soroban platform
- Freighter for wallet integration
- The Stellar open-source community
Built with ❤️ for the Stellar ecosystem