Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/1inch/cross-chain-sdk/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The HashLock class manages cryptographic commitments for atomic swaps. It creates hash locks from secrets that ensure trustless execution.

Class Definition

class HashLock {
  static hashSecret(secret: string): string
  static getMerkleLeaves(secrets: string[]): MerkleLeaf[]
  static getMerkleLeavesFromSecretHashes(secretHashes: string[]): MerkleLeaf[]
  static getProof(leaves: string[], idx: number): MerkleLeaf[]
  static forSingleFill(secret: string): HashLock
  static forMultipleFills(leaves: MerkleLeaf[]): HashLock
  static fromString(value: string): HashLock
  static fromBuffer(value: Buffer): HashLock
  
  getPartsCount(): bigint
  toString(): string
  toJSON(): string
  toBuffer(): Buffer
  eq(other: HashLock): boolean
}

Static Methods

hashSecret

Hashes a secret using keccak256.
static hashSecret(secret: string): string
secret
string
required
32-byte hex-encoded secret (must start with ‘0x’)
Returns: keccak256 hash of the secret Example:
import { HashLock } from '@1inch/cross-chain-sdk'
import { randomBytes } from 'crypto'

const secret = '0x' + randomBytes(32).toString('hex')
const secretHash = HashLock.hashSecret(secret)

console.log(secretHash) // 0x...

forSingleFill

Creates a hash lock for orders with a single fill.
static forSingleFill(secret: string): HashLock
secret
string
required
32-byte hex-encoded secret
Example:
const secret = '0x' + randomBytes(32).toString('hex')
const hashLock = HashLock.forSingleFill(secret)

// Use in order creation
const { hash, order, quoteId } = await sdk.createOrder(quote, {
  walletAddress,
  hashLock,
  preset: PresetEnum.fast,
  secretHashes: [HashLock.hashSecret(secret)]
})

forMultipleFills

Creates a hash lock for orders with multiple fills using a merkle tree.
static forMultipleFills(leaves: MerkleLeaf[]): HashLock
leaves
MerkleLeaf[]
required
Array of merkle leaves (must be > 2 items)
Example:
import { HashLock } from '@1inch/cross-chain-sdk'
import { randomBytes } from 'crypto'

// Generate multiple secrets
const secrets = Array.from({ length: 3 })
  .map(() => '0x' + randomBytes(32).toString('hex'))

// Create merkle leaves
const leaves = HashLock.getMerkleLeaves(secrets)

// Create hash lock
const hashLock = HashLock.forMultipleFills(leaves)

// Use in order creation
const secretHashes = secrets.map(s => HashLock.hashSecret(s))
const { hash, order, quoteId } = await sdk.createOrder(quote, {
  walletAddress,
  hashLock,
  preset: PresetEnum.medium,
  secretHashes
})

getMerkleLeaves

Creates merkle leaves from an array of secrets.
static getMerkleLeaves(secrets: string[]): MerkleLeaf[]
secrets
string[]
required
Array of 32-byte hex-encoded secrets
Returns: Array of merkle leaves suitable for forMultipleFills Example:
const secrets = [
  '0x' + randomBytes(32).toString('hex'),
  '0x' + randomBytes(32).toString('hex'),
  '0x' + randomBytes(32).toString('hex'
]

const leaves = HashLock.getMerkleLeaves(secrets)
const hashLock = HashLock.forMultipleFills(leaves)

getMerkleLeavesFromSecretHashes

Creates merkle leaves from pre-hashed secrets.
static getMerkleLeavesFromSecretHashes(secretHashes: string[]): MerkleLeaf[]
secretHashes
string[]
required
Array of keccak256 hashes of secrets

getProof

Generates a merkle proof for a specific leaf.
static getProof(leaves: string[], idx: number): MerkleLeaf[]
leaves
string[]
required
Array of merkle leaves
idx
number
required
Index of the leaf to prove
Returns: Merkle proof as array of sibling hashes

fromString / fromBuffer

Creates a HashLock from an existing hash value.
static fromString(value: string): HashLock
static fromBuffer(value: Buffer): HashLock

Instance Methods

getPartsCount

Returns the number of fills for multi-fill orders.
getPartsCount(): bigint
Only use this method for multi-fill hash locks. For single-fill hash locks, this returns garbage data.
Example:
const secrets = Array.from({ length: 5 })
  .map(() => '0x' + randomBytes(32).toString('hex'))

const hashLock = HashLock.forMultipleFills(
  HashLock.getMerkleLeaves(secrets)
)

console.log(hashLock.getPartsCount()) // 4n (count - 1)

toString / toJSON

Converts the hash lock to a hex string.
toString(): string
toJSON(): string
Example:
const hashLock = HashLock.forSingleFill(secret)
console.log(hashLock.toString()) // 0x...

const json = JSON.stringify({ hashLock })
// Uses toJSON() automatically

toBuffer

Converts the hash lock to a Buffer.
toBuffer(): Buffer

eq

Compares two hash locks for equality.
eq(other: HashLock): boolean

Complete Examples

Single Fill Order

import { SDK, HashLock, PresetEnum, NetworkEnum } from '@1inch/cross-chain-sdk'
import { randomBytes } from 'crypto'

const sdk = new SDK(/* config */)

// Get quote with single fill preset
const quote = await sdk.getQuote({
  srcChainId: NetworkEnum.ETHEREUM,
  dstChainId: NetworkEnum.POLYGON,
  srcTokenAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  dstTokenAddress: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f',
  amount: '1000000',
  walletAddress: '0x...',
  enableEstimate: true
})

// Single secret
const secret = '0x' + randomBytes(32).toString('hex')
const hashLock = HashLock.forSingleFill(secret)
const secretHashes = [HashLock.hashSecret(secret)]

// Create and submit order
const { hash, order, quoteId } = await sdk.createOrder(quote, {
  walletAddress: '0x...',
  hashLock,
  preset: PresetEnum.fast,
  secretHashes
})

await sdk.submitOrder(quote.srcChainId, order, quoteId, secretHashes)

Multiple Fill Order

import { SDK, HashLock, PresetEnum } from '@1inch/cross-chain-sdk'
import { randomBytes } from 'crypto'

const sdk = new SDK(/* config */)

// Get quote
const quote = await sdk.getQuote(/* params */)

// Get preset to determine secret count
const preset = quote.getPreset(PresetEnum.medium)
const secretCount = preset.secretsCount

// Generate secrets
const secrets = Array.from({ length: secretCount })
  .map(() => '0x' + randomBytes(32).toString('hex'))

// Create hash lock with merkle tree
const hashLock = HashLock.forMultipleFills(
  HashLock.getMerkleLeaves(secrets)
)

const secretHashes = secrets.map(s => HashLock.hashSecret(s))

// Create and submit order
const { hash, order, quoteId } = await sdk.createOrder(quote, {
  walletAddress: '0x...',
  hashLock,
  preset: PresetEnum.medium,
  secretHashes
})

await sdk.submitOrder(quote.srcChainId, order, quoteId, secretHashes)

// Submit secrets as fills become ready
while (true) {
  const { fills } = await sdk.getReadyToAcceptSecretFills(hash)
  
  for (const { idx } of fills) {
    await sdk.submitSecret(hash, secrets[idx])
  }
  
  const { status } = await sdk.getOrderStatus(hash)
  if (status === OrderStatus.Executed) break
  
  await new Promise(resolve => setTimeout(resolve, 1000))
}

Security Notes

Never reuse secrets across orders. Each order must have unique, randomly generated secrets.
Secrets must be exactly 32 bytes. Use crypto.randomBytes(32) or equivalent secure random generation.
For multi-fill orders, the hash lock encodes both the merkle root and the number of fills in a single bytes32 value.