Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
harshjv committed Sep 29, 2018
2 parents 213619d + 2e9458a commit 14da4b4
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 84 deletions.
10 changes: 5 additions & 5 deletions README.md
@@ -1,6 +1,6 @@
# Chain Abstraction Layer <img align="right" src="./liquality-logo.png" height="80px" />

[![ChainAbstractionLayer](https://travis-ci.org/consensys/chainabstractionlayer.svg?branch=master)](https://travis-ci.org/consensys/chainabstractionlayer)
[![ChainAbstractionLayer](https://travis-ci.org/liquality/chainabstractionlayer.svg?branch=master)](https://travis-ci.org/liquality/chainabstractionlayer)
[![Standard Code Style](https://img.shields.io/badge/codestyle-standard-brightgreen.svg)](https://github.com/standard/standard)
[![MIT License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](./LICENSE.md)
[![ChainAbstractionLayer](https://img.shields.io/npm/dt/chainabstractionlayer.svg)](https://npmjs.com/package/chainabstractionlayer)
Expand Down Expand Up @@ -50,15 +50,15 @@ bitcoin
<td>
<a href="./examples/browser/ethereum/ledger.html">Source</a>
&amp;
<a href="https://consensys.github.io/chainabstractionlayer/examples/browser/ethereum/ledger.html">Demo</a>
<a href="https://liquality.github.io/chainabstractionlayer/examples/browser/ethereum/ledger.html">Demo</a>
</td>
</tr>
<tr>
<td>MetaMask</td>
<td>
<a href="./examples/browser/ethereum/metamask.html">Source</a>
&amp;
<a href="https://consensys.github.io/chainabstractionlayer/examples/browser/ethereum/metamask.html">Demo</a>
<a href="https://liquality.github.io/chainabstractionlayer/examples/browser/ethereum/metamask.html">Demo</a>
</td>
</tr>
<tr>
Expand All @@ -67,7 +67,7 @@ bitcoin
<td>
<a href="./examples/browser/bitcoin/ledger.html">Source</a>
&amp;
<a href="https://consensys.github.io/chainabstractionlayer/examples/browser/bitcoin/ledger.html">Demo</a>
<a href="https://liquality.github.io/chainabstractionlayer/examples/browser/bitcoin/ledger.html">Demo</a>
</td>
</tr>
</tbody>
Expand All @@ -76,7 +76,7 @@ bitcoin

## Documentation

The documentation is being generated by [esdoc](https://www.npmjs.com/package/esdoc). Github Page hosted documentation is available at [consensys.github.io/chainabstractionlayer](https://consensys.github.io/chainabstractionlayer/)
The documentation is being generated by [esdoc](https://www.npmjs.com/package/esdoc). Github Page hosted documentation is available at [liquality.github.io/chainabstractionlayer](https://liquality.github.io/chainabstractionlayer/)

If you want to build documentation locally;

Expand Down
83 changes: 46 additions & 37 deletions examples/swap/swap-e2e.html
Expand Up @@ -25,40 +25,41 @@ <h3>Generate secret:</h3>
<p><button id="btcGenerateSecret">Generate Secret</button></p>
<p>secret: <textarea id="btcGenerateSecretResult"></textarea></p>
<p>secretHash: <textarea id="btcGenerateSecretResultHash"></textarea></p>
<h3>Generate swap:</h3>
<h3>Initiate swap:</h3>
<p>value: <input type="text" id="btcFundValue" value="100" /></p>
<p>recipientAddress: <input type="text" id="btcRecipientAddress" value="myPhar2QNiePwTAL775nNipcpatpLP2GPG" /></p>
<p>refundAddress: <input type="text" id="btcRefundAddress" value="mr3iwwmxLXRxyxgxD1EWgfCAe2mL2tuNGF" /></p>
<p>secretHash: <input type="text" id="btcSecretHash" value="edc64c6523778961fe9ba03ab7d624b27ca1dd5b01e7734cc6c891d50db04269"
/></p>
<p>expiration: <input type="text" id="btcExpiration" value="12" /></p>
<p><button id="btcGenerateSwap">Generate Swap</button></p>
<p>script: <textarea id="btcGenerateSwapResult"></textarea></p>
<h3>Fund script:</h3>
<p>Script: <input type="text" id="btcFundScript" /></p>
<p>Value: <input type="text" id="btcFundValue" value="0" /></p>
<p><button id="btcSendTransaction">Send</button></p>
<p>transaction hash: <textarea id="btcSendTransactionResult"></textarea></p>
<p>secretHash: <input type="text" id="btcSecretHash" /></p>
<p>expiration: <input type="text" id="btcExpiration" value="1568194353" /></p>
<p><button id="btcInitiateSwap">Initiate Swap</button></p>
<p>transaction hash: <textarea id="btcInitiateSwapResult"></textarea></p>
<h3>Claim swap:</h3>
<p><strong>Wait until initiation transaction has been confirmed!</strong></p>
<p>secret: <input type="text" id="btcClaimSecret" /></p>
<p>initiationTxHash: <input type="text" id="btcInitiationTxHash" /></p>
<p><button id="btcClaimSwap">Claim Swap</button></p>
<p>transaction hash: <textarea id="btcClaimSwapResult"></textarea></p>
</td>
<td>
<h3>Generate secret:</h3>
<p>Swap params: <input type="text" id="ethMessage" value="<currency1><value1><currency2><value2>" /></p>
<p><button id="ethGenerateSecret">Generate Secret</button></p>
<p>secret: <textarea id="ethGenerateSecretResult"></textarea></p>
<p>secretHash: <textarea id="ethGenerateSecretResultHash"></textarea></p>
<h3>Generate swap:</h3>
<p>recipientAddress: <input type="text" id="ethRecipientAddress" value="d2b471c995cae3e580930175431f2341a03f55e2"
/></p>
<p>refundAddress: <input type="text" id="ethRefundAddress" value="33f284119394dd7d2f6afd1d33869611de6d00b4" /></p>
<p>secretHash: <input type="text" id="ethSecretHash" value="edc64c6523778961fe9ba03ab7d624b27ca1dd5b01e7734cc6c891d50db04269"
/></p>
<p>expiration: <input type="text" id="ethExpiration" value="12" /></p>
<p><button id="ethGenerateSwap">Generate Swap</button></p>
<p>script: <textarea id="ethGenerateSwapResult"></textarea></p>
<h3>Fund script:</h3>
<p>Script: <input type="text" id="ethFundScript" /></p>
<p>Value: <input type="text" id="ethFundValue" value="0" /></p>
<p><button id="ethSendTransaction">Send</button></p>
<p>transaction hash: <textarea id="ethSendTransactionResult"></textarea></p>
<h3>Initiate swap:</h3>
<p>value: <input type="text" id="ethFundValue" value="100" /></p>
<p>recipientAddress: <input type="text" id="ethRecipientAddress" value="0x454f8D6e2b0F6Ca13638cE6E00904D5E75CBA291" /></p>
<p>refundAddress: <input type="text" id="ethRefundAddress" value="0x4C01f55Edb32743FFC30876e203F60fBCe4ADd14" /></p>
<p>secretHash: <input type="text" id="ethSecretHash" /></p>
<p>expiration: <input type="text" id="ethExpiration" value="1568194353" /></p>
<p><button id="ethInitiateSwap">Initiate Swap</button></p>
<p>transaction hash: <textarea id="ethInitiateSwapResult"></textarea></p>
<h3>Claim swap:</h3>
<p><strong>Wait until initiation transaction has been confirmed!</strong></p>
<p>secret: <input type="text" id="ethClaimSecret" /></p>
<p>initiationTxHash: <input type="text" id="ethInitiationTxHash" /></p>
<p><button id="ethClaimSwap">Claim Swap</button></p>
<p>transaction hash: <textarea id="ethClaimSwapResult"></textarea></p>
</td>
</tr>
</table>
Expand All @@ -70,7 +71,7 @@ <h3>Fund script:</h3>
const bitcoin = new Client()
bitcoin.addProvider(new providers.bitcoin.BitcoinRPCProvider('https://localhost:18332', 'bitcoin', 'local321'))
bitcoin.addProvider(new providers.bitcoin.BitcoinLedgerProvider({ network: networks.bitcoin_testnet }))
bitcoin.addProvider(new providers.bitcoin.BitcoinSwapProvider())
bitcoin.addProvider(new providers.bitcoin.BitcoinSwapProvider({ network: networks.bitcoin_testnet }))

const ethereum = new Client()
ethereum.addProvider(new providers.ethereum.EthereumRPCProvider('https://localhost:8545'))
Expand All @@ -80,34 +81,42 @@ <h3>Fund script:</h3>
function generateSecret (client, prefix) {
client.generateSecret($(`#${prefix}Message`).val()).then(result => {
$(`#${prefix}GenerateSecretResult`).text(result)
$(`#${prefix}GenerateSecretResultHash`).text(crypto.hash160(result))
$(`#${prefix}GenerateSecretResultHash`).text(crypto.sha256(result))
})
}

function generateSwap (client, prefix) {
client.generateSwap(
function initiateSwap (client, prefix) {
client.initiateSwap(
parseInt($(`#${prefix}FundValue`).val()),
$(`#${prefix}RecipientAddress`).val(),
$(`#${prefix}RefundAddress`).val(),
$(`#${prefix}SecretHash`).val(),
parseInt($(`#${prefix}Expiration`).val())
).then(result => {
$(`#${prefix}GenerateSwapResult`).text(result)
$(`#${prefix}InitiateSwapResult`).text(result)
})
}

function fundSwap (client, prefix) {
client.sendTransaction(null, parseInt($(`#${prefix}FundValue`).val()), $(`#${prefix}FundScript`).val()).then(result => {
$(`#${prefix}SendTransactionResult`).text(result, null, 2)
function claimSwap (client, prefix) {
client.claimSwap(
$(`#${prefix}InitiationTxHash`).val(),
parseInt($(`#${prefix}FundValue`).val()),
$(`#${prefix}RecipientAddress`).val(),
$(`#${prefix}RefundAddress`).val(),
$(`#${prefix}ClaimSecret`).val(),
parseInt($(`#${prefix}Expiration`).val())
).then(result => {
$(`#${prefix}ClaimSwapResult`).text(result)
})
}

$('#btcGenerateSecret').click(generateSecret.bind(null, bitcoin, 'btc'))
$('#btcGenerateSwap').click(generateSwap.bind(null, bitcoin, 'btc'))
$('#btcSendTransaction').click(fundSwap.bind(null, bitcoin, 'btc'))
$('#btcInitiateSwap').click(initiateSwap.bind(null, bitcoin, 'btc'))
$('#btcClaimSwap').click(claimSwap.bind(null, ethereum, 'btc'))

$('#ethGenerateSecret').click(generateSecret.bind(null, ethereum, 'eth'))
$('#ethGenerateSwap').click(generateSwap.bind(null, ethereum, 'eth'))
$('#ethSendTransaction').click(fundSwap.bind(null, ethereum, 'eth'))
$('#ethInitiateSwap').click(initiateSwap.bind(null, ethereum, 'eth'))
$('#ethClaimSwap').click(claimSwap.bind(null, ethereum, 'eth'))
</script>
</body>

Expand Down
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -15,12 +15,12 @@
"license": "MIT",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/consensys/chainabstractionlayer.git"
"url": "git+ssh://git@github.com/liquality/chainabstractionlayer.git"
},
"bugs": {
"url": "https://github.com/consensys/chainabstractionlayer/issues"
"url": "https://github.com/liquality/chainabstractionlayer/issues"
},
"homepage": "https://github.com/consensys/chainabstractionlayer#readme",
"homepage": "https://github.com/liquality/chainabstractionlayer#readme",
"author": "Liquality <info@liquality.io>",
"module": "src/index.js",
"browser": {
Expand Down
45 changes: 25 additions & 20 deletions src/Client.js
Expand Up @@ -4,7 +4,7 @@ import * as Ajv from 'ajv'
import * as providers from './providers'
import DNSParser from './DsnParser'
import { Block, Transaction } from './schema'
import { hash160 } from './crypto'
import { sha256 } from './crypto'
import {
DuplicateProviderError,
InvalidProviderError,
Expand Down Expand Up @@ -467,20 +467,21 @@ export default class Client {
*/
async generateSecret (message) {
const signedMessage = await this.signMessage(message)
const secret = hash160(signedMessage)
const secret = sha256(signedMessage)
return secret
}

/**
* Generate swap transaction data
* Initiate a swap
* @param {!number} value - The amount of native value to lock for the swap.
* @param {!string} recipientAddress - Recepient address for the swap in hex.
* @param {!string} refundAddress - Refund address for the swap in hex.
* @param {!string} secretHash - Secret hash for the swap in hex.
* @param {!number} expiration - Expiration time for the swap.
* @return {Promise<string, TypeError>} Resolves with swap contract bytecode.
* @return {Promise<string, TypeError>} Resolves with the transaction ID for the swap.
* Rejects with InvalidProviderResponseError if provider's response is invalid.
*/
async generateSwap (recipientAddress, refundAddress, secretHash, expiration) {
async initiateSwap (value, recipientAddress, refundAddress, secretHash, expiration) {
if (!isString(recipientAddress)) {
throw new TypeError('Recipient address should be a string')
}
Expand All @@ -501,7 +502,7 @@ export default class Client {
throw new TypeError('Invalid expiration time')
}

return this.getMethod('generateSwap')(recipientAddress, refundAddress, secretHash, expiration)
return this.getMethod('initiateSwap')(value, recipientAddress, refundAddress, secretHash, expiration)
}

/**
Expand All @@ -512,32 +513,36 @@ export default class Client {
* @return {Promise<string, TypeError>} Resolves with redeem swap contract bytecode.
* Rejects with InvalidProviderResponseError if provider's response is invalid.
*/
async redeemSwap (secret, pubKey = '', signature = '') {
if (!isString(secret)) {
throw new TypeError('Secret should be a string')
async claimSwap (initiationTxHash, value, recipientAddress, refundAddress, secret, expiration) {
if (!(/^[A-Fa-f0-9]+$/.test(initiationTxHash))) {
throw new TypeError('Initiation transaction hash should be a valid hex string')
}

if (!(/^[A-Fa-f0-9]+$/.test(secret))) {
throw new TypeError('Secret should be a valid hex string')
if (!isString(recipientAddress)) {
throw new TypeError('Recipient address should be a string')
}

if (!isString(pubKey)) {
throw new TypeError('PubKey should be a string')
if (!isString(recipientAddress)) {
throw new TypeError('Recipient address should be a string')
}

if (!(/^[A-Fa-f0-9]*$/.test(pubKey))) {
throw new TypeError('PubKey should be a valid hex string')
if (!isString(refundAddress)) {
throw new TypeError('Refund address should be a string')
}

if (!isString(signature)) {
throw new TypeError('Signature should be a string')
if (!isString(secret)) {
throw new TypeError('Secret hash should be a string')
}

if (!(/^[A-Fa-f0-9]*$/.test(signature))) {
throw new TypeError('Signature should be a valid hex string')
if (!(/^[A-Fa-f0-9]+$/.test(secret))) {
throw new TypeError('Secret hash should be a valid hex string')
}

if (!isNumber(expiration)) {
throw new TypeError('Invalid expiration time')
}

return this.getMethod('redeemSwap')(secret, pubKey, signature)
return this.getMethod('claimSwap')(initiationTxHash, value, recipientAddress, refundAddress, secret, expiration)
}

/**
Expand Down
7 changes: 1 addition & 6 deletions src/providers/bitcoin/BitcoinLedgerProvider.js
Expand Up @@ -3,7 +3,7 @@ import Bitcoin from '@ledgerhq/hw-app-btc'

import { BigNumber } from 'bignumber.js'
import { base58, padHexStart } from '../../crypto'
import { pubKeyToAddress, addressToPubKeyHash } from './BitcoinUtil'
import { addressToPubKeyHash } from './BitcoinUtil'
import Address from '../../Address'
import networks from '../../networks'

Expand Down Expand Up @@ -138,11 +138,6 @@ export default class BitcoinLedgerProvider extends LedgerProvider {
async createSignedTransaction (to, value, data, from) {
const app = await this.getApp()

if (data) {
const scriptPubKey = padHexStart(data)
to = pubKeyToAddress(scriptPubKey, this._network.name, 'scriptHash')
}

const unusedAddress = this.getUnusedAddress(from)
const unspentOutputsToUse = this.getUtxosForAmount(value)

Expand Down
18 changes: 14 additions & 4 deletions src/providers/bitcoin/BitcoinSwapProvider.js
@@ -1,7 +1,6 @@
import Provider from '../../Provider'
import { pubKeyToAddress, addressToPubKeyHash } from './BitcoinUtil'
import { addressToPubKeyHash, pubKeyToAddress } from './BitcoinUtil'
import { padHexStart } from '../../crypto'

import networks from '../../networks'

export default class BitcoinSwapProvider extends Provider {
Expand Down Expand Up @@ -43,6 +42,17 @@ export default class BitcoinSwapProvider extends Provider {
].join('')
}

async initiateSwap (value, recipientAddress, refundAddress, secretHash, expiration) {
const script = this.generateSwap(recipientAddress, refundAddress, secretHash, expiration)
const scriptPubKey = padHexStart(script)
const p2shAddress = pubKeyToAddress(scriptPubKey, this._network.name, 'scriptHash')
return this.getMethod('sendTransaction')(p2shAddress, value, script)
}

async claimSwap (initiationTxHash, value, recipientAddress, refundAddress, secret, expiration) {
throw new Error('Not implemented yet')
}

_spendSwap (signature, pubKey, isRedeem, secret) {
const redeemEncoded = isRedeem ? '51' : '00' // OP_1 : OP_0
const encodedSecret = isRedeem
Expand All @@ -67,11 +77,11 @@ export default class BitcoinSwapProvider extends Provider {
return bytecode.join('')
}

redeemSwap (secret, pubKey, signature) {
getRedeemSwapData (secret, pubKey, signature) {
return this._spendSwap(signature, pubKey, true, secret)
}

refundSwap (pubKey, signature) {
getRefundSwapData (pubKey, signature) {
return this._spendSwap(signature, pubKey, false)
}

Expand Down
5 changes: 5 additions & 0 deletions src/providers/ethereum/EthereumRPCProvider.js
Expand Up @@ -32,6 +32,11 @@ export default class EthereumRPCProvider extends JsonRpcProvider {
return this.jsonrpc('eth_getTransactionByHash', txHash)
}

async getTransactionReceipt (txHash) {
txHash = ensureHexEthFormat(txHash)
return this.rpc('eth_getTransactionReceipt', txHash)
}

async getBalance (addresses) {
const addrs = addresses.map(ensureHexEthFormat)
const promiseBalances = await Promise.all(addrs.map(address => this.rpc('eth_getBalance', address, 'latest')))
Expand Down

0 comments on commit 14da4b4

Please sign in to comment.