Skip to content
This repository was archived by the owner on Mar 23, 2021. It is now read-only.

Commit 3e9334b

Browse files
bors[bot]da-kamiFranck Royer
authored
Merge #234
234: add comments to the separate apps example r=D4nte a=da-kami cleaned up PR, there should not be additional changes @D4nte Co-authored-by: Daniel Karzel <daniel.karzel@coblox.tech> Co-authored-by: Franck Royer <franck@coblox.tech>
2 parents 66f5ea4 + dc8f5d4 commit 3e9334b

File tree

6 files changed

+194
-62
lines changed

6 files changed

+194
-62
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## Fixed
1010
- Upgrade `separate_apps` example to comit-sdk 0.7.0 to fix maker auto-accept.
11+
- Add code comments in `separate_apps` to describe the behaviour and help app developers understand how to use COMIT SDK.
1112

1213
## [0.5.0] - 2019-11-28
1314

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ If you have any question please [reach out to the team in our Gitter chat](https
1616

1717
1. `yarn create comit-app new <your-app-name>`,
1818
2. `yarn create comit-app start-env` to start blockchain and COMIT nodes,
19-
3. Run the [btc-eth](https://github.com/comit-network/create-comit-app/tree/master/new_project/examples/btc_eth) example (in separate terminal):
20-
1. Navigate to the btc-eth example app directory `cd <path-to-your-app>/examples/btc_eth`,
19+
3. Run the [separate-apps](https://github.com/comit-network/create-comit-app/tree/master/new_project/examples/separate_apps) example (in separate terminals for the taker and maker):
20+
1. Navigate to the separate-apps example app directory `cd <path-to-your-app>/examples/separate-apps`,
2121
2. `yarn install` to install dependencies,
22-
3. `yarn start` to run the application.
22+
3. `yarn run maker` to run the maker app.
23+
4. `yarn run taker` to run the taker app.
24+
5. Follow the steps be hitting `Return` to complete the swap.
2325

2426
You can find additional examples in the [examples](https://github.com/comit-network/create-comit-app/tree/master/new_project/examples) directory that is created as part of step 1.
2527

new_project/examples/separate_apps/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
An example project that shows how to swap Bitcoin for Ether with COMIT.
44

5+
In this example the taker and maker are split up in separate executable files.
6+
Upon executing the maker and taker apps the execution will bounce between the maker and taker, making the example closer to a production app.
7+
8+
The example includes the simple negotiation protocol provided by the COMIT SDK.
9+
10+
It sets off at the point where the maker has already published an order for the taker.
11+
It then consists of 5 steps:
12+
1. The taker takes the order and starts the swap execution.
13+
2. The taker funds the Ethereum HTLC.
14+
3. The maker funds the Bitcoin HTLC.
15+
4. The taker redeems the Bitcoin HTLC.
16+
5. The maker redeems the Ethereum HTLC.
17+
518
## How to run this example
619

720
1. Make sure you have an environment setup through `create-comit-app`,

new_project/examples/separate_apps/src/lib.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { BitcoinWallet, Cnd, ComitClient, EthereumWallet } from "comit-sdk";
22
import fs from "fs";
33

44
export async function startClient(index: number): Promise<Actor> {
5+
checkEnvFile(process.env.DOTENV_CONFIG_PATH!);
6+
57
const bitcoinWallet = await BitcoinWallet.newInstance(
68
"regtest",
79
process.env.BITCOIN_P2P_URI!,

new_project/examples/separate_apps/src/maker.ts

Lines changed: 97 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,25 @@ import { formatEther } from "ethers/utils";
88
import moment from "moment";
99
import readLineSync from "readline-sync";
1010
import { toBitcoin } from "satoshi-bitcoin-ts";
11-
import { checkEnvFile, startClient } from "./lib";
12-
13-
function createOrder(): Order {
14-
return {
15-
id: "123",
16-
tradingPair: "ETH-BTC",
17-
validUntil: moment().unix() + 300,
18-
ask: {
19-
nominalAmount: "9",
20-
asset: "ether",
21-
ledger: "ethereum",
22-
},
23-
bid: {
24-
nominalAmount: "1",
25-
asset: "bitcoin",
26-
ledger: "bitcoin",
27-
},
28-
};
29-
}
30-
11+
import { startClient } from "./lib";
12+
13+
/**
14+
* This executable function represents the maker side during a trade.
15+
* A trade consists of two phases: negotiation and execution.
16+
*
17+
* During the negotiation phase the maker publishes an order that the taker can take.
18+
* Once the negotiation is over (i.e. the taker has accepted the order) the execution of the swap commences.
19+
*
20+
* -- Execution details: --
21+
* Most of the logic of the swap execution is done by COMIT SDK. The example tells the ComitClient that
22+
* it wants to execute fund and redeem for a specific swap. The ComitClient checks for the availability of the
23+
* fund and redeem action in the comit node daemon.
24+
*/
3125
(async function main() {
32-
checkEnvFile(process.env.DOTENV_CONFIG_PATH!);
33-
26+
// Initialize the maker Actor
3427
const maker = await startClient(0);
3528

29+
// print balances before swapping
3630
console.log(
3731
"[Maker] Bitcoin balance: %f. Ether balance: %f",
3832
parseFloat(await maker.bitcoinWallet.getBalance()).toFixed(2),
@@ -41,46 +35,70 @@ function createOrder(): Order {
4135
).toFixed(2)
4236
);
4337

44-
const peerId = await maker.comitClient.getPeerId();
45-
const addressHint = await maker.comitClient
46-
.getPeerListenAddresses()
47-
.then(addresses => addresses[0]);
48-
49-
console.log("[Maker] peer id:", peerId);
50-
console.log("[Maker] address hint:", addressHint);
51-
52-
// start negotiation protocol handler so that a taker can take the order and receives the latest rate
53-
38+
// Initialize the maker negotiator that defines the negotiation phase of the trade.
39+
// The maker negotiator manages the maker's orders, makes them available to potential takers
40+
// and defines when an order was taken by a taker.
41+
// Once an order was taken by a taker the negotiator hands over the order and execution parameters to the
42+
// execution phase.
5443
const makerNegotiator = new MakerNegotiator(
5544
maker.comitClient,
5645
{
46+
// Connection information for the comit network daemon.
47+
// The maker has to provide this to the taker for the execution phase,
48+
// so that the taker's comit network daemon can message the maker's comit network daemon.
5749
peer: {
58-
peer_id: peerId,
59-
address_hint: addressHint,
50+
peer_id: maker.peerId,
51+
address_hint: maker.addressHint,
6052
},
53+
// The expiry time for the taker.
6154
alpha_expiry: moment().unix() + 7200,
55+
// The expiry time for the maker
6256
beta_expiry: moment().unix() + 3600,
57+
// The network the swap will be executed on.
6358
ledgers: {
6459
bitcoin: { network: "regtest" },
65-
// TODO: It should be possible to use the chain_id
6660
ethereum: { network: "regtest" },
6761
},
6862
},
6963
{ maxTimeoutSecs: 1000, tryIntervalSecs: 0.1 }
7064
);
7165

66+
// Start the HTTP service used to publish orders.
7267
const makerHttpApi = new MakerHttpApi(makerNegotiator);
73-
68+
// The maker's HTTP service will be served at port 2318.
7469
makerHttpApi.listen(2318);
75-
const order = createOrder();
70+
// Create an order to be published.
71+
const order: Order = {
72+
id: "123",
73+
tradingPair: "ETH-BTC",
74+
validUntil: moment().unix() + 300,
75+
ask: {
76+
nominalAmount: "9",
77+
asset: "ether",
78+
ledger: "ethereum",
79+
},
80+
bid: {
81+
nominalAmount: "1",
82+
asset: "bitcoin",
83+
ledger: "bitcoin",
84+
},
85+
};
86+
87+
// Publish the order so the taker can take it.
7688
makerNegotiator.addOrder(order);
7789

90+
// Let the world know that there is an order available.
91+
// In a real-world application this information could be shared publicly, e.g. on social medias.
7892
const invitationDetails = `http://localhost:2318/orders/ETH-BTC`;
7993
console.log(`Waiting for someone taking my order at: ${invitationDetails}`);
8094

95+
// Wait for a taker to accept the order and send a swap request through the comit network daemon (cnd).
8196
let swapHandle;
97+
// This loop runs until a swap request was sent from the taker to the maker
98+
// and a swap is waiting to be processed on the maker's side.
8299
while (!swapHandle) {
83100
await new Promise(r => setTimeout(r, 1000));
101+
// Check for incoming swaps in the comit node daemon (cnd) of the maker.
84102
swapHandle = await maker.comitClient.getOngoingSwaps().then(swaps => {
85103
if (swaps) {
86104
return swaps[0];
@@ -90,6 +108,7 @@ function createOrder(): Order {
90108
});
91109
}
92110

111+
// Retrieve the details (properties) of the swap
93112
const swap = await swapHandle.fetchDetails();
94113
const swapParams = swap.properties!.parameters;
95114

@@ -100,26 +119,64 @@ function createOrder(): Order {
100119
swapParams.beta_asset.name
101120
);
102121

103-
readLineSync.question("2. Continue?");
122+
// Wait for commandline input for demo purposes
123+
readLineSync.question("3. Continue funding the Bitcoin HTLC?");
104124

105125
const tryParams: TryParams = { maxTimeoutSecs: 100, tryIntervalSecs: 1 };
106126

107127
console.log(
108128
"Bitcoin HTLC funded! TXID: ",
129+
130+
// -- FUND --
131+
// Wait for the successful execution of the funding transaction of the maker.
132+
//
133+
// -- Execution Details: --
134+
// The maker's fund transaction will only be executed after the maker's comit network daemon (cnd)
135+
// has detected the funding transaction of the taker. (The taker funds first.)
136+
//
137+
// This promise will thus resolve once:
138+
// - The taker has sent the fund transaction,
139+
// - The maker's comit network daemon has retrieved the taker's fund transaction from an incoming block,
140+
// - The maker has sent the fund transaction.
141+
//
142+
// The transaction ID will be returned by the wallet after sending the transaction.
109143
await swapHandle.fund(tryParams)
110144
);
111145

112-
readLineSync.question("4. Continue?");
146+
// Wait for commandline input for demo purposes
147+
readLineSync.question("5. Continue redeeming the Ethereum HTLC?");
113148

114-
console.log("Ether redeemed! TXID: ", await swapHandle.redeem(tryParams));
149+
console.log(
150+
"Ether redeemed! TXID: ",
151+
152+
// -- REDEEM --
153+
// Wait for the successful execution of the redeem transaction of the maker.
154+
//
155+
// -- Execution Details: --
156+
// The maker's redeem transaction will only be executed after the maker's comit network daemon (cnd)
157+
// has detected the redeem transaction of the taker. (The taker redeems first.)
158+
//
159+
// This promise will thus resolve once:
160+
// - The taker has sent the fund transaction,
161+
// - The maker's comit network daemon has retrieved the taker's fund transaction from an incoming block,
162+
// - The maker has sent the fund transaction,
163+
// - The taker's comit network daemon has retrieved the maker's fund transaction from an incoming block,
164+
// - The taker has sent the redeem transaction.
165+
//
166+
// The transaction ID will be returned by the wallet after sending the transaction.
167+
await swapHandle.redeem(tryParams)
168+
);
115169

116170
console.log("Swapped!");
171+
172+
// print balances after swapping
117173
console.log(
118174
"[Maker] Bitcoin balance: %f. Ether balance: %f",
119175
parseFloat(await maker.bitcoinWallet.getBalance()).toFixed(2),
120176
parseFloat(
121177
formatEther(await maker.ethereumWallet.getBalance())
122178
).toFixed(2)
123179
);
180+
124181
process.exit();
125182
})();

0 commit comments

Comments
 (0)