{"id":15540630,"url":"https://github.com/chatch/hashed-timelock-contract-ethereum","last_synced_at":"2025-04-06T03:05:20.576Z","repository":{"id":52379954,"uuid":"103606835","full_name":"chatch/hashed-timelock-contract-ethereum","owner":"chatch","description":"Hashed Timelock Contracts for ETH, ERC20 and ERC721 on Ethereum","archived":false,"fork":false,"pushed_at":"2021-07-26T05:43:08.000Z","size":983,"stargazers_count":225,"open_issues_count":3,"forks_count":111,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-23T15:05:13.220Z","etag":null,"topics":["atomic-swap","blockchain","cryptocurrencies","erc20","erc721","ethereum","hashlock","htlc","smart-contracts","solidity","timelock"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chatch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-15T02:54:50.000Z","updated_at":"2025-01-11T10:52:04.000Z","dependencies_parsed_at":"2022-09-08T17:11:32.301Z","dependency_job_id":null,"html_url":"https://github.com/chatch/hashed-timelock-contract-ethereum","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chatch%2Fhashed-timelock-contract-ethereum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chatch%2Fhashed-timelock-contract-ethereum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chatch%2Fhashed-timelock-contract-ethereum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chatch%2Fhashed-timelock-contract-ethereum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chatch","download_url":"https://codeload.github.com/chatch/hashed-timelock-contract-ethereum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246975911,"owners_count":20862989,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic-swap","blockchain","cryptocurrencies","erc20","erc721","ethereum","hashlock","htlc","smart-contracts","solidity","timelock"],"created_at":"2024-10-02T12:14:11.013Z","updated_at":"2025-04-06T03:05:20.558Z","avatar_url":"https://github.com/chatch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hashed-timelock-contract-ethereum\n\n[![NPM Package](https://img.shields.io/npm/v/ethereum-htlc.svg?style=flat-square)](https://www.npmjs.org/package/ethereum-htlc)\n[![Build Status](https://travis-ci.com/chatch/hashed-timelock-contract-ethereum.svg?branch=master)](https://travis-ci.com/chatch/hashed-timelock-contract-ethereum)\n\n[Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) (HTLCs) for Ethereum:\n\n- [HashedTimelock.sol](contracts/HashedTimelock.sol) - HTLC for native ETH token\n- [HashedTimelockERC20.sol](contracts/HashedTimelockERC20.sol) - HTLC for ERC20 tokens\n- [HashedTimelockERC721.sol](contracts/HashedTimelockERC721.sol) - HTLC for ERC721 tokens\n\nUse these contracts for creating HTLCs on the Ethereum side of a cross chain atomic swap (for example the [xcat](https://github.com/chatch/xcat) project).\n\n## Run Tests\n* Install dependencies\n* Start [Ganache](https://www.trufflesuite.com/ganache) with network ID `4447`\n* Run the [Truffle](https://www.trufflesuite.com/truffle) tests\n\n```\n$ npm install\n$ npm run ganache-start\n$ npm run test\nUsing network 'test'.\n\nCompiling ./test/helper/ASEANToken.sol...\nCompiling ./test/helper/EUToken.sol...\n\n\n  Contract: HashedTimelock\n    ✓ newContract() should create new contract and store correct details (92ms)\n    ✓ newContract() should fail when no ETH sent (84ms)\n    ✓ newContract() should fail with timelocks in the past (78ms)\n    ✓ newContract() should reject a duplicate contract request (159ms)\n    ✓ withdraw() should send receiver funds when given the correct secret preimage (214ms)\n    ✓ withdraw() should fail if preimage does not hash to hashX (111ms)\n    ✓ withdraw() should fail if caller is not the receiver (162ms)\n    ✓ withdraw() should fail after timelock expiry (1243ms)\n    ✓ refund() should pass after timelock expiry (1273ms)\n    ✓ refund() should fail before the timelock expiry (132ms)\n    ✓ getContract() returns empty record when contract doesn't exist (48ms)\n\n  Contract: HashedTimelockERC20\n    ✓ newContract() should create new contract and store correct details (214ms)\n    ✓ newContract() should fail when no token transfer approved (107ms)\n    ✓ newContract() should fail when token amount is 0 (166ms)\n    ✓ newContract() should fail when tokens approved for some random account (214ms)\n    ✓ newContract() should fail when the timelock is in the past (136ms)\n    ✓ newContract() should reject a duplicate contract request (282ms)\n    ✓ withdraw() should send receiver funds when given the correct secret preimage (363ms)\n    ✓ withdraw() should fail if preimage does not hash to hashX (227ms)\n    ✓ withdraw() should fail if caller is not the receiver  (307ms)\n    ✓ withdraw() should fail after timelock expiry (2257ms)\n    ✓ refund() should pass after timelock expiry (2407ms)\n    ✓ refund() should fail before the timelock expiry (283ms)\n    ✓ getContract() returns empty record when contract doesn't exist (55ms)\n\n  Contract: HashedTimelock swap between two ERC20 tokens\n    ✓ Step 1: Alice sets up a swap with Bob in the AliceERC20 contract (233ms)\n    ✓ Step 2: Bob sets up a swap with Alice in the BobERC20 contract (239ms)\n    ✓ Step 3: Alice as the initiator withdraws from the BobERC20 with the secret (97ms)\n    ✓ Step 4: Bob as the counterparty withdraws from the AliceERC20 with the secret learned from Alice's withdrawal (144ms)\n    Test the refund scenario:\n      ✓ the swap is set up with 5sec timeout on both sides (3613ms)\n\n  Contract: HashedTimelock swap between ERC721 token and ERC20 token (Delivery vs. Payment)\n    ✓ Step 1: Alice sets up a swap with Bob to transfer the Commodity token #1 (256ms)\n    ✓ Step 2: Bob sets up a swap with Alice in the payment contract (231ms)\n    ✓ Step 3: Alice as the initiator withdraws from the BobERC721 with the secret (95ms)\n    ✓ Step 4: Bob as the counterparty withdraws from the AliceERC721 with the secret learned from Alice's withdrawal (132ms)\n    Test the refund scenario:\n      ✓ the swap is set up with 5sec timeout on both sides (3737ms)\n\n  Contract: HashedTimelock swap between two ERC721 tokens\n    ✓ Step 1: Alice sets up a swap with Bob in the AliceERC721 contract (225ms)\n    ✓ Step 2: Bob sets up a swap with Alice in the BobERC721 contract (265ms)\n    ✓ Step 3: Alice as the initiator withdraws from the BobERC721 with the secret (131ms)\n    ✓ Step 4: Bob as the counterparty withdraws from the AliceERC721 with the secret learned from Alice's withdrawal (119ms)\n    Test the refund scenario:\n      ✓ the swap is set up with 5sec timeout on both sides (3635ms)\n\n\n  39 passing (27s)\n```\n\n## Protocol - Native ETH\n\n### Main flow\n\n![](docs/sequence-diagram-htlc-eth-success.png?raw=true)\n\n### Timelock expires\n\n![](docs/sequence-diagram-htlc-eth-refund.png?raw=true)\n\n## Protocol - ERC20\n\n### Main flow\n\n![](docs/sequence-diagram-htlc-erc20-success.png?raw=true)\n\n### Timelock expires\n\n![](docs/sequence-diagram-htlc-erc20-refund.png?raw=true)\n\n## Interface\n\n### HashedTimelock\n\n1.  `newContract(receiverAddress, hashlock, timelock)` create new HTLC with given receiver, hashlock and expiry; returns contractId bytes32\n2.  `withdraw(contractId, preimage)` claim funds revealing the preimage\n3.  `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.\n\nSee [test/htlc.js](test/htlc.js) for examples of interacting with the contract from javascript.\n\n### HashedTimelockERC20\n\n1.  `newContract(receiverAddress, hashlock, timelock, tokenContract, amount)` create new HTLC with given receiver, hashlock, expiry, ERC20 token contract address and amount of tokens\n2.  `withdraw(contractId, preimage)` claim funds revealing the preimage\n3.  `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.\n\nSee [test/htlcERC20.js](test/htlcERC20.js) for examples of interacting with the contract from javascript.\n\n### HashedTimelockERC721\n\n1.  `newContract(receiverAddress, hashlock, timelock, tokenContract, tokenId)` create new HTLC with given receiver, hashlock, expiry, ERC20 token contract address and the token to transfer\n2.  `withdraw(contractId, preimage)` claim funds revealing the preimage\n3.  `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchatch%2Fhashed-timelock-contract-ethereum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchatch%2Fhashed-timelock-contract-ethereum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchatch%2Fhashed-timelock-contract-ethereum/lists"}