@@ -8,31 +8,25 @@ import { formatEther } from "ethers/utils";
8
8
import moment from "moment" ;
9
9
import readLineSync from "readline-sync" ;
10
10
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
+ */
31
25
( async function main ( ) {
32
- checkEnvFile ( process . env . DOTENV_CONFIG_PATH ! ) ;
33
-
26
+ // Initialize the maker Actor
34
27
const maker = await startClient ( 0 ) ;
35
28
29
+ // print balances before swapping
36
30
console . log (
37
31
"[Maker] Bitcoin balance: %f. Ether balance: %f" ,
38
32
parseFloat ( await maker . bitcoinWallet . getBalance ( ) ) . toFixed ( 2 ) ,
@@ -41,46 +35,70 @@ function createOrder(): Order {
41
35
) . toFixed ( 2 )
42
36
) ;
43
37
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.
54
43
const makerNegotiator = new MakerNegotiator (
55
44
maker . comitClient ,
56
45
{
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.
57
49
peer : {
58
- peer_id : peerId ,
59
- address_hint : addressHint ,
50
+ peer_id : maker . peerId ,
51
+ address_hint : maker . addressHint ,
60
52
} ,
53
+ // The expiry time for the taker.
61
54
alpha_expiry : moment ( ) . unix ( ) + 7200 ,
55
+ // The expiry time for the maker
62
56
beta_expiry : moment ( ) . unix ( ) + 3600 ,
57
+ // The network the swap will be executed on.
63
58
ledgers : {
64
59
bitcoin : { network : "regtest" } ,
65
- // TODO: It should be possible to use the chain_id
66
60
ethereum : { network : "regtest" } ,
67
61
} ,
68
62
} ,
69
63
{ maxTimeoutSecs : 1000 , tryIntervalSecs : 0.1 }
70
64
) ;
71
65
66
+ // Start the HTTP service used to publish orders.
72
67
const makerHttpApi = new MakerHttpApi ( makerNegotiator ) ;
73
-
68
+ // The maker's HTTP service will be served at port 2318.
74
69
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.
76
88
makerNegotiator . addOrder ( order ) ;
77
89
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.
78
92
const invitationDetails = `http://localhost:2318/orders/ETH-BTC` ;
79
93
console . log ( `Waiting for someone taking my order at: ${ invitationDetails } ` ) ;
80
94
95
+ // Wait for a taker to accept the order and send a swap request through the comit network daemon (cnd).
81
96
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.
82
99
while ( ! swapHandle ) {
83
100
await new Promise ( r => setTimeout ( r , 1000 ) ) ;
101
+ // Check for incoming swaps in the comit node daemon (cnd) of the maker.
84
102
swapHandle = await maker . comitClient . getOngoingSwaps ( ) . then ( swaps => {
85
103
if ( swaps ) {
86
104
return swaps [ 0 ] ;
@@ -90,6 +108,7 @@ function createOrder(): Order {
90
108
} ) ;
91
109
}
92
110
111
+ // Retrieve the details (properties) of the swap
93
112
const swap = await swapHandle . fetchDetails ( ) ;
94
113
const swapParams = swap . properties ! . parameters ;
95
114
@@ -100,26 +119,64 @@ function createOrder(): Order {
100
119
swapParams . beta_asset . name
101
120
) ;
102
121
103
- readLineSync . question ( "2. Continue?" ) ;
122
+ // Wait for commandline input for demo purposes
123
+ readLineSync . question ( "3. Continue funding the Bitcoin HTLC?" ) ;
104
124
105
125
const tryParams : TryParams = { maxTimeoutSecs : 100 , tryIntervalSecs : 1 } ;
106
126
107
127
console . log (
108
128
"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.
109
143
await swapHandle . fund ( tryParams )
110
144
) ;
111
145
112
- readLineSync . question ( "4. Continue?" ) ;
146
+ // Wait for commandline input for demo purposes
147
+ readLineSync . question ( "5. Continue redeeming the Ethereum HTLC?" ) ;
113
148
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
+ ) ;
115
169
116
170
console . log ( "Swapped!" ) ;
171
+
172
+ // print balances after swapping
117
173
console . log (
118
174
"[Maker] Bitcoin balance: %f. Ether balance: %f" ,
119
175
parseFloat ( await maker . bitcoinWallet . getBalance ( ) ) . toFixed ( 2 ) ,
120
176
parseFloat (
121
177
formatEther ( await maker . ethereumWallet . getBalance ( ) )
122
178
) . toFixed ( 2 )
123
179
) ;
180
+
124
181
process . exit ( ) ;
125
182
} ) ( ) ;
0 commit comments