@hashlock/sdk
TypeScript SDK for HashLock — institutional OTC trading with HTLC atomic settlement on Ethereum and Bitcoin.
Install
npm install @hashlock/sdk
pnpm add @hashlock/sdk
Quick Start
import { HashLock } from '@hashlock/sdk';
const hl = new HashLock({
endpoint: 'http://142.93.106.129/graphql',
accessToken: 'your-jwt-token',
});
const rfq = await hl.createRFQ({
baseToken: 'ETH',
quoteToken: 'USDT',
side: 'SELL',
amount: '1.0',
});
console.log(`RFQ created: ${rfq.id}`);
Authentication
Get a JWT token by logging into the HashLock platform, then pass it to the SDK:
const hl = new HashLock({
endpoint: 'http://142.93.106.129/graphql',
accessToken: 'eyJhbGciOiJIUzI1NiIs...',
});
hl.setAccessToken('new-token');
RFQ Trading
Create an RFQ (Request for Quote)
const rfq = await hl.createRFQ({
baseToken: 'BTC',
quoteToken: 'USDT',
side: 'BUY',
amount: '0.5',
expiresIn: 300,
});
Respond with a Quote
const quote = await hl.submitQuote({
rfqId: rfq.id,
price: '68500.00',
amount: '0.5',
});
Accept a Quote (creates a Trade)
const accepted = await hl.acceptQuote(quote.id);
List & Query
const { rfqs, total } = await hl.listRFQs({ status: 'ACTIVE', page: 1 });
const rfq = await hl.getRFQ('rfq-uuid');
const quotes = await hl.getQuotes('rfq-uuid');
HTLC Settlement — ETH / ERC-20
After a trade is accepted, both parties lock assets in HTLC contracts.
Record an HTLC Lock (after on-chain tx)
const result = await hl.fundHTLC({
tradeId: 'trade-uuid',
txHash: '0xabc123...',
role: 'INITIATOR',
timelock: Math.floor(Date.now() / 1000) + 3600,
hashlock: '0xdef456...',
chainType: 'evm',
});
Claim an HTLC (reveal preimage)
const claimed = await hl.claimHTLC({
tradeId: 'trade-uuid',
txHash: '0xclaim...',
preimage: '0xsecret...',
chainType: 'evm',
});
Refund (after timelock expiry)
const refunded = await hl.refundHTLC({
tradeId: 'trade-uuid',
txHash: '0xrefund...',
});
Check HTLC Status
const status = await hl.getHTLCStatus('trade-uuid');
console.log(status?.initiatorHTLC?.status);
console.log(status?.counterpartyHTLC?.status);
HTLC Settlement — Bitcoin
Bitcoin HTLCs use P2WSH scripts (no smart contract deployment needed).
Prepare a Bitcoin HTLC
const btcHtlc = await hl.prepareBitcoinHTLC({
tradeId: 'trade-uuid',
role: 'INITIATOR',
senderPubKey: '02abc...',
receiverPubKey: '03def...',
timelock: Math.floor(Date.now() / 1000) + 7200,
amountSats: '100000',
});
console.log(`Send BTC to: ${btcHtlc.htlcAddress}`);
Claim a Bitcoin HTLC
const psbt = await hl.buildBitcoinClaimPSBT({
tradeId: 'trade-uuid',
htlcId: btcHtlc.htlcId,
preimage: '0xsecret...',
destinationPubKey: '02abc...',
feeRate: 10,
});
const signedTx = await wallet.signPsbt(psbt.psbtBase64);
const broadcast = await hl.broadcastBitcoinTx({
tradeId: 'trade-uuid',
txHex: signedTx,
});
console.log(`BTC claimed: ${broadcast.txid}`);
Cross-Chain Atomic Swap (ETH ↔ BTC)
await hl.fundHTLC({
tradeId, txHash: evmTxHash, role: 'INITIATOR',
hashlock, timelock: now + 7200, chainType: 'evm',
});
const btc = await hl.prepareBitcoinHTLC({
tradeId, role: 'COUNTERPARTY',
senderPubKey: bobPub, receiverPubKey: alicePub,
timelock: now + 3600, amountSats: '100000',
});
await hl.fundHTLC({
tradeId, txHash: btcFundingTxid, role: 'COUNTERPARTY',
chainType: 'bitcoin', redeemScript: btc.redeemScript,
});
Error Handling
import { HashLockError, GraphQLError, AuthError, NetworkError } from '@hashlock/sdk';
try {
await hl.getTrade('bad-id');
} catch (err) {
if (err instanceof AuthError) {
} else if (err instanceof GraphQLError) {
console.error('API error:', err.errors);
} else if (err instanceof NetworkError) {
console.error('Network issue:', err.message);
}
}
Configuration
const hl = new HashLock({
endpoint: 'http://142.93.106.129/graphql',
accessToken: 'jwt-token',
timeout: 30000,
retries: 3,
});
endpoint | string | — | GraphQL API URL (required) |
accessToken | string | — | JWT bearer token |
timeout | number | 30000 | Request timeout (ms) |
retries | number | 3 | Retry attempts for transient failures |
fetch | typeof fetch | globalThis.fetch | Custom fetch implementation |
Mainnet Contracts (Ethereum)
License
MIT