15
15
* PERFORMANCE OF THIS SOFTWARE.
16
16
*/
17
17
18
- import { generateKeyPair , encodeContractAddress } from '../utils/crypto'
18
+ import { generateKeyPair , encodeContractAddress , encodeBase64Check } from '../utils/crypto'
19
19
import {
20
20
options ,
21
21
changeStatus ,
@@ -25,7 +25,23 @@ import {
25
25
channelId ,
26
26
disconnect
27
27
} from './internal'
28
- import { unpackTx } from '../tx/builder'
28
+ import { unpackTx , buildTx } from '../tx/builder'
29
+
30
+ function encodeRlpTx ( rlpBinary ) {
31
+ return `tx_${ encodeBase64Check ( rlpBinary ) } `
32
+ }
33
+
34
+ async function appendSignature ( tx , signFn ) {
35
+ const { signatures, encodedTx } = unpackTx ( tx ) . tx
36
+ const result = await signFn ( encodeRlpTx ( encodedTx . rlpEncoded ) )
37
+ if ( result ) {
38
+ const { tx : signedTx , txType } = unpackTx ( result )
39
+ return encodeRlpTx ( buildTx ( {
40
+ signatures : signatures . concat ( signedTx . signatures ) ,
41
+ encodedTx : signedTx . encodedTx . rlpEncoded
42
+ } , txType ) . rlpEncoded )
43
+ }
44
+ }
29
45
30
46
function handleUnexpectedMessage ( channel , message , state ) {
31
47
if ( state . reject ) {
@@ -63,15 +79,35 @@ export async function awaitingChannelCreateTx (channel, message, state) {
63
79
responder : 'responder_sign'
64
80
} [ options . get ( channel ) . role ]
65
81
if ( message . method === `channels.sign.${ tag } ` ) {
66
- const signedTx = await options . get ( channel ) . sign ( tag , message . params . data . tx )
67
- send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { tx : signedTx } } )
82
+ if ( message . params . data . tx ) {
83
+ const signedTx = await options . get ( channel ) . sign ( tag , message . params . data . tx )
84
+ send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { tx : signedTx } } )
85
+ return { handler : awaitingOnChainTx }
86
+ }
87
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx => options . get ( channel ) . sign ( tag , tx ) )
88
+ send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { signed_tx : signedTx } } )
68
89
return { handler : awaitingOnChainTx }
69
90
}
70
91
}
71
92
72
93
export function awaitingOnChainTx ( channel , message , state ) {
73
94
if ( message . method === 'channels.on_chain_tx' ) {
74
- emit ( channel , 'onChainTx' , message . params . data . tx )
95
+ if (
96
+ message . params . data . info === 'funding_signed' &&
97
+ options . get ( channel ) . role === 'initiator'
98
+ ) {
99
+ return { handler : awaitingOnChainTx }
100
+ }
101
+ if (
102
+ message . params . data . info === 'funding_created' &&
103
+ options . get ( channel ) . role === 'responder'
104
+ ) {
105
+ return { handler : awaitingOnChainTx }
106
+ }
107
+ emit ( channel , 'onChainTx' , message . params . data . signed_tx , {
108
+ info : message . params . data . info ,
109
+ type : message . params . data . type
110
+ } )
75
111
return { handler : awaitingBlockInclusion }
76
112
}
77
113
if (
@@ -126,13 +162,22 @@ export async function channelOpen (channel, message, state) {
126
162
return { handler : channelOpen }
127
163
case 'close_mutual' :
128
164
return { handler : channelOpen }
165
+ case 'closing' :
166
+ changeStatus ( channel , 'closing' )
167
+ return { handler : channelOpen }
168
+ case 'closed_confirmed' :
169
+ changeStatus ( channel , 'closed' )
170
+ return { handler : channelClosed }
129
171
case 'died' :
130
172
changeStatus ( channel , 'died' )
131
173
return { handler : channelClosed }
132
174
}
133
175
break
134
176
case 'channels.on_chain_tx' :
135
- emit ( channel , 'onChainTx' , message . params . data . tx )
177
+ emit ( channel , 'onChainTx' , message . params . data . signed_tx , {
178
+ info : message . params . data . info ,
179
+ type : message . params . data . type
180
+ } )
136
181
return { handler : channelOpen }
137
182
case 'channels.leave' :
138
183
// TODO: emit event
@@ -151,8 +196,15 @@ channelOpen.enter = (channel) => {
151
196
export async function awaitingOffChainTx ( channel , message , state ) {
152
197
if ( message . method === 'channels.sign.update' ) {
153
198
const { sign } = state
154
- const signedTx = await sign ( message . params . data . tx , { updates : message . params . data . updates } )
155
- send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
199
+ if ( message . params . data . tx ) {
200
+ const signedTx = await sign ( message . params . data . tx , { updates : message . params . data . updates } )
201
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
202
+ return { handler : awaitingOffChainUpdate , state }
203
+ }
204
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx =>
205
+ sign ( tx , { updates : message . params . data . updates } )
206
+ )
207
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { signed_tx : signedTx } } )
156
208
return { handler : awaitingOffChainUpdate , state }
157
209
}
158
210
if ( message . method === 'channels.error' ) {
@@ -194,14 +246,22 @@ export async function awaitingTxSignRequest (channel, message, state) {
194
246
// eslint-disable-next-line no-useless-escape
195
247
const [ , tag ] = message . method . match ( / ^ c h a n n e l s \. s i g n \. ( [ ^ \. ] + ) $ / ) || [ ]
196
248
if ( tag ) {
197
- const signedTx = await options . get ( channel ) . sign (
198
- tag ,
199
- message . params . data . tx ,
200
- { updates : message . params . data . updates }
201
- )
202
- if ( signedTx ) {
203
- send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { tx : signedTx } } )
204
- return { handler : channelOpen }
249
+ if ( message . params . data . tx ) {
250
+ const signedTx = await options . get ( channel ) . sign ( tag , message . params . data . tx , {
251
+ updates : message . params . data . updates
252
+ } )
253
+ if ( signedTx ) {
254
+ send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { tx : signedTx } } )
255
+ return { handler : channelOpen }
256
+ }
257
+ } else {
258
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx =>
259
+ options . get ( channel ) . sign ( tag , tx , { updates : message . params . data . updates } )
260
+ )
261
+ if ( signedTx ) {
262
+ send ( channel , { jsonrpc : '2.0' , method : `channels.${ tag } ` , params : { signed_tx : signedTx } } )
263
+ return { handler : channelOpen }
264
+ }
205
265
}
206
266
// soft-reject via competing update
207
267
send ( channel , {
@@ -230,8 +290,13 @@ export function awaitingUpdateConflict (channel, message, state) {
230
290
231
291
export async function awaitingShutdownTx ( channel , message , state ) {
232
292
if ( message . method === 'channels.sign.shutdown_sign' ) {
233
- const signedTx = await Promise . resolve ( state . sign ( message . params . data . tx ) )
234
- send ( channel , { jsonrpc : '2.0' , method : 'channels.shutdown_sign' , params : { tx : signedTx } } )
293
+ if ( message . params . data . tx ) {
294
+ const signedTx = await state . sign ( message . params . data . tx )
295
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.shutdown_sign' , params : { tx : signedTx } } )
296
+ return { handler : awaitingShutdownOnChainTx , state }
297
+ }
298
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx => state . sign ( tx ) )
299
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.shutdown_sign' , params : { signed_tx : signedTx } } )
235
300
return { handler : awaitingShutdownOnChainTx , state }
236
301
}
237
302
return handleUnexpectedMessage ( channel , message , state )
@@ -260,11 +325,16 @@ export function awaitingLeave (channel, message, state) {
260
325
261
326
export async function awaitingWithdrawTx ( channel , message , state ) {
262
327
if ( message . method === 'channels.sign.withdraw_tx' ) {
263
- const signedTx = await Promise . resolve ( state . sign (
264
- message . params . data . tx ,
265
- { updates : message . params . data . updates }
266
- ) )
267
- send ( channel , { jsonrpc : '2.0' , method : 'channels.withdraw_tx' , params : { tx : signedTx } } )
328
+ const { sign } = state
329
+ if ( message . params . data . tx ) {
330
+ const signedTx = await sign ( message . params . data . tx , { updates : message . params . data . updates } )
331
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.withdraw_tx' , params : { tx : signedTx } } )
332
+ return { handler : awaitingWithdrawCompletion , state }
333
+ }
334
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx =>
335
+ sign ( tx , { updates : message . params . data . updates } )
336
+ )
337
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.withdraw_tx' , params : { signed_tx : signedTx } } )
268
338
return { handler : awaitingWithdrawCompletion , state }
269
339
}
270
340
return handleUnexpectedMessage ( channel , message , state )
@@ -273,7 +343,7 @@ export async function awaitingWithdrawTx (channel, message, state) {
273
343
export function awaitingWithdrawCompletion ( channel , message , state ) {
274
344
if ( message . method === 'channels.on_chain_tx' ) {
275
345
if ( state . onOnChainTx ) {
276
- state . onOnChainTx ( message . params . data . tx )
346
+ state . onOnChainTx ( message . params . data . signed_tx )
277
347
}
278
348
return { handler : awaitingWithdrawCompletion , state }
279
349
}
@@ -303,11 +373,16 @@ export function awaitingWithdrawCompletion (channel, message, state) {
303
373
304
374
export async function awaitingDepositTx ( channel , message , state ) {
305
375
if ( message . method === 'channels.sign.deposit_tx' ) {
306
- const signedTx = await Promise . resolve ( state . sign (
307
- message . params . data . tx ,
308
- { updates : message . params . data . updates }
309
- ) )
310
- send ( channel , { jsonrpc : '2.0' , method : 'channels.deposit_tx' , params : { tx : signedTx } } )
376
+ const { sign } = state
377
+ if ( message . params . data . tx ) {
378
+ const signedTx = await sign ( message . params . data . tx , { updates : message . params . data . updates } )
379
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.deposit_tx' , params : { tx : signedTx } } )
380
+ return { handler : awaitingDepositCompletion , state }
381
+ }
382
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx =>
383
+ sign ( tx , { updates : message . params . data . updates } )
384
+ )
385
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.deposit_tx' , params : { signed_tx : signedTx } } )
311
386
return { handler : awaitingDepositCompletion , state }
312
387
}
313
388
return handleUnexpectedMessage ( channel , message , state )
@@ -316,7 +391,7 @@ export async function awaitingDepositTx (channel, message, state) {
316
391
export function awaitingDepositCompletion ( channel , message , state ) {
317
392
if ( message . method === 'channels.on_chain_tx' ) {
318
393
if ( state . onOnChainTx ) {
319
- state . onOnChainTx ( message . params . data . tx )
394
+ state . onOnChainTx ( message . params . data . signed_tx )
320
395
}
321
396
return { handler : awaitingDepositCompletion , state }
322
397
}
@@ -346,8 +421,13 @@ export function awaitingDepositCompletion (channel, message, state) {
346
421
347
422
export async function awaitingNewContractTx ( channel , message , state ) {
348
423
if ( message . method === 'channels.sign.update' ) {
349
- const signedTx = await Promise . resolve ( state . sign ( message . params . data . tx ) )
350
- send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
424
+ if ( message . params . data . tx ) {
425
+ const signedTx = await state . sign ( message . params . data . tx )
426
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
427
+ return { handler : awaitingNewContractCompletion , state }
428
+ }
429
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx => state . sign ( tx ) )
430
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { signed_tx : signedTx } } )
351
431
return { handler : awaitingNewContractCompletion , state }
352
432
}
353
433
return handleUnexpectedMessage ( channel , message , state )
@@ -378,8 +458,13 @@ export function awaitingNewContractCompletion (channel, message, state) {
378
458
379
459
export async function awaitingCallContractUpdateTx ( channel , message , state ) {
380
460
if ( message . method === 'channels.sign.update' ) {
381
- const signedTx = await Promise . resolve ( state . sign ( message . params . data . tx ) )
382
- send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
461
+ if ( message . params . data . tx ) {
462
+ const signedTx = await state . sign ( message . params . data . tx )
463
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { tx : signedTx } } )
464
+ return { handler : awaitingCallContractCompletion , state }
465
+ }
466
+ const signedTx = await appendSignature ( message . params . data . signed_tx , tx => state . sign ( tx ) )
467
+ send ( channel , { jsonrpc : '2.0' , method : 'channels.update' , params : { signed_tx : signedTx } } )
383
468
return { handler : awaitingCallContractCompletion , state }
384
469
}
385
470
return handleUnexpectedMessage ( channel , message , state )
0 commit comments